From 74db542bf46d6238a68e5f54305250f37750d12a Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Sun, 15 Sep 2024 20:15:38 +0200 Subject: [PATCH] Fix UB in `Instance::supports_()` --- openxr/src/instance.rs | 43 +++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/openxr/src/instance.rs b/openxr/src/instance.rs index e5f3417..bee4344 100644 --- a/openxr/src/instance.rs +++ b/openxr/src/instance.rs @@ -149,35 +149,44 @@ impl Instance { } } + // Note: to avoid undefined behaviour, `ext_props` should be initialized filling in all fields + // manually. The OpenXR spec does not guarantee that `get_system_properties()` will return an + // error when pushing `ext_props` to `SystemProperties::next` if the corresponding extension is + // unsupported. Using `T::out()` and then `assume_init()` could lead to undefined behaviour + // because not all fields may be initialized. #[inline] - pub fn supports_render_model_loading(&self, system: SystemId) -> Result { + pub fn get_system_props_ext(&self, system: SystemId, ext_props: &mut T) -> Result<()> { unsafe { - let mut render_model = sys::SystemRenderModelPropertiesFB::out(ptr::null_mut()); - let mut p = sys::SystemProperties::out(&mut render_model as *mut _ as _); + let mut p = sys::SystemProperties::out(ext_props as *mut _ as _); cvt((self.fp().get_system_properties)( self.as_raw(), system, p.as_mut_ptr(), ))?; - Ok(render_model - .assume_init() - .supports_render_model_loading - .into()) } + Ok(()) + } + + #[inline] + pub fn supports_render_model_loading(&self, system: SystemId) -> Result { + let mut props = sys::SystemRenderModelPropertiesFB { + ty: sys::SystemRenderModelPropertiesFB::TYPE, + next: ptr::null_mut(), + supports_render_model_loading: sys::FALSE, + }; + self.get_system_props_ext(system, &mut props)?; + Ok(props.supports_render_model_loading.into()) } #[inline] pub fn supports_hand_tracking(&self, system: SystemId) -> Result { - unsafe { - let mut hand = sys::SystemHandTrackingPropertiesEXT::out(ptr::null_mut()); - let mut p = sys::SystemProperties::out(&mut hand as *mut _ as _); - cvt((self.fp().get_system_properties)( - self.as_raw(), - system, - p.as_mut_ptr(), - ))?; - Ok(hand.assume_init().supports_hand_tracking.into()) - } + let mut props = sys::SystemHandTrackingPropertiesEXT { + ty: sys::SystemHandTrackingPropertiesEXT::TYPE, + next: ptr::null_mut(), + supports_hand_tracking: sys::FALSE, + }; + self.get_system_props_ext(system, &mut props)?; + Ok(props.supports_hand_tracking.into()) } /// Construct a `Path` from a string