From 89d94b55208ba1a140fabd12636e694c206bb534 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Wed, 21 Aug 2024 19:29:33 -0500 Subject: [PATCH] Consistent allocation failure for `windows-registry` (#3215) --- crates/libs/registry/src/bindings.rs | 1 - crates/libs/registry/src/data.rs | 31 +++++----- crates/libs/registry/src/key.rs | 2 +- crates/libs/registry/src/value.rs | 66 ++++++++++------------ crates/libs/registry/src/value_iterator.rs | 4 +- crates/tests/registry/tests/value.rs | 28 ++++----- crates/tests/registry/tests/values.rs | 6 +- crates/tools/bindings/src/registry.txt | 1 - 8 files changed, 65 insertions(+), 74 deletions(-) diff --git a/crates/libs/registry/src/bindings.rs b/crates/libs/registry/src/bindings.rs index 0e52bd79b3..ea270ec24f 100644 --- a/crates/libs/registry/src/bindings.rs +++ b/crates/libs/registry/src/bindings.rs @@ -21,7 +21,6 @@ windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap : HANDLE, dwfla pub type BOOL = i32; pub const ERROR_INVALID_DATA: WIN32_ERROR = 13u32; pub const ERROR_NO_MORE_ITEMS: WIN32_ERROR = 259u32; -pub const ERROR_OUTOFMEMORY: WIN32_ERROR = 14u32; #[repr(C)] #[derive(Clone, Copy)] pub struct FILETIME { diff --git a/crates/libs/registry/src/data.rs b/crates/libs/registry/src/data.rs index 6dd4cae3c6..b64fb8ba96 100644 --- a/crates/libs/registry/src/data.rs +++ b/crates/libs/registry/src/data.rs @@ -8,15 +8,15 @@ pub struct Data { impl Data { // Creates a buffer with the specified length of zero bytes. - pub fn new(len: usize) -> Result { + pub fn new(len: usize) -> Self { unsafe { - let bytes = Self::alloc(len)?; + let bytes = Self::alloc(len); if len > 0 { core::ptr::write_bytes(bytes.ptr, 0, len); } - Ok(bytes) + bytes } } @@ -30,34 +30,34 @@ impl Data { } // Creates a buffer by copying the bytes from the slice. - pub fn from_slice(slice: &[u8]) -> Result { + pub fn from_slice(slice: &[u8]) -> Self { unsafe { - let bytes = Self::alloc(slice.len())?; + let bytes = Self::alloc(slice.len()); if !slice.is_empty() { core::ptr::copy_nonoverlapping(slice.as_ptr(), bytes.ptr, slice.len()); } - Ok(bytes) + bytes } } // Allocates an uninitialized buffer. - unsafe fn alloc(len: usize) -> Result { + unsafe fn alloc(len: usize) -> Self { if len == 0 { - Ok(Self { + Self { ptr: null_mut(), len: 0, - }) + } } else { // This pointer will have at least 8 byte alignment. let ptr = HeapAlloc(GetProcessHeap(), 0, len) as *mut u8; if ptr.is_null() { - Err(Error::from_hresult(HRESULT::from_win32(ERROR_OUTOFMEMORY))) - } else { - Ok(Self { ptr, len }) + panic!("allocation failed"); } + + Self { ptr, len } } } } @@ -96,7 +96,7 @@ impl core::ops::DerefMut for Data { impl Clone for Data { fn clone(&self) -> Self { - Self::from_slice(self).unwrap() + Self::from_slice(self) } } @@ -114,9 +114,8 @@ impl core::fmt::Debug for Data { } } -impl TryFrom<[u8; N]> for Data { - type Error = Error; - fn try_from(from: [u8; N]) -> Result { +impl From<[u8; N]> for Data { + fn from(from: [u8; N]) -> Self { Self::from_slice(&from) } } diff --git a/crates/libs/registry/src/key.rs b/crates/libs/registry/src/key.rs index a001f6fb99..6bd2fe946f 100644 --- a/crates/libs/registry/src/key.rs +++ b/crates/libs/registry/src/key.rs @@ -144,7 +144,7 @@ impl Key { pub fn get_value>(&self, name: T) -> Result { let name = pcwstr(name); let (ty, len) = unsafe { self.raw_get_info(name.as_raw())? }; - let mut data = Data::new(len)?; + let mut data = Data::new(len); unsafe { self.raw_get_bytes(name.as_raw(), &mut data)? }; Ok(Value { data, ty }) } diff --git a/crates/libs/registry/src/value.rs b/crates/libs/registry/src/value.rs index a11539ecc1..8430d0d859 100644 --- a/crates/libs/registry/src/value.rs +++ b/crates/libs/registry/src/value.rs @@ -38,13 +38,12 @@ impl AsRef<[u8]> for Value { } } -impl TryFrom for Value { - type Error = Error; - fn try_from(from: u32) -> Result { - Ok(Self { - data: from.to_le_bytes().try_into()?, +impl From for Value { + fn from(from: u32) -> Self { + Self { + data: from.to_le_bytes().into(), ty: Type::U32, - }) + } } } @@ -55,13 +54,12 @@ impl TryFrom for u32 { } } -impl TryFrom for Value { - type Error = Error; - fn try_from(from: u64) -> Result { - Ok(Self { - data: from.to_le_bytes().try_into()?, +impl From for Value { + fn from(from: u64) -> Self { + Self { + data: from.to_le_bytes().into(), ty: Type::U64, - }) + } } } @@ -82,13 +80,12 @@ impl TryFrom for String { } } -impl TryFrom<&str> for Value { - type Error = Error; - fn try_from(from: &str) -> Result { - Ok(Self { - data: Data::from_slice(pcwstr(from).as_bytes())?, +impl From<&str> for Value { + fn from(from: &str) -> Self { + Self { + data: Data::from_slice(pcwstr(from).as_bytes()), ty: Type::String, - }) + } } } @@ -117,33 +114,30 @@ impl TryFrom for HSTRING { } } -impl TryFrom<&HSTRING> for Value { - type Error = Error; - fn try_from(from: &HSTRING) -> Result { - Ok(Self { - data: Data::from_slice(as_bytes(from))?, +impl From<&HSTRING> for Value { + fn from(from: &HSTRING) -> Self { + Self { + data: Data::from_slice(as_bytes(from)), ty: Type::String, - }) + } } } -impl TryFrom<&[u8]> for Value { - type Error = Error; - fn try_from(from: &[u8]) -> Result { - Ok(Self { - data: Data::from_slice(from)?, +impl From<&[u8]> for Value { + fn from(from: &[u8]) -> Self { + Self { + data: Data::from_slice(from), ty: Type::Bytes, - }) + } } } -impl TryFrom<[u8; N]> for Value { - type Error = Error; - fn try_from(from: [u8; N]) -> Result { - Ok(Self { - data: Data::from_slice(&from)?, +impl From<[u8; N]> for Value { + fn from(from: [u8; N]) -> Self { + Self { + data: Data::from_slice(&from), ty: Type::Bytes, - }) + } } } diff --git a/crates/libs/registry/src/value_iterator.rs b/crates/libs/registry/src/value_iterator.rs index f66f9724c3..e11d319b5a 100644 --- a/crates/libs/registry/src/value_iterator.rs +++ b/crates/libs/registry/src/value_iterator.rs @@ -37,7 +37,7 @@ impl<'a> ValueIterator<'a> { key, range: 0..count as usize, name: vec![0; name_max_len as usize + 1], - data: Data::new(value_max_len as usize)?, + data: Data::new(value_max_len as usize), }) } } @@ -72,7 +72,7 @@ impl<'a> Iterator for ValueIterator<'a> { Some(( name, Value { - data: Data::from_slice(&self.data[0..data_len as usize]).unwrap(), + data: Data::from_slice(&self.data[0..data_len as usize]), ty: ty.into(), }, )) diff --git a/crates/tests/registry/tests/value.rs b/crates/tests/registry/tests/value.rs index deb0929621..ec23dd443d 100644 --- a/crates/tests/registry/tests/value.rs +++ b/crates/tests/registry/tests/value.rs @@ -7,27 +7,27 @@ fn value() -> Result<()> { _ = CURRENT_USER.remove_tree(test_key); let key = CURRENT_USER.create(test_key)?; - key.set_value("u32", &Value::try_from(123u32)?)?; + key.set_value("u32", &Value::from(123u32))?; assert_eq!(key.get_type("u32")?, Type::U32); - assert_eq!(key.get_value("u32")?, Value::try_from(123u32)?); + assert_eq!(key.get_value("u32")?, Value::from(123u32)); assert_eq!(key.get_u32("u32")?, 123u32); assert_eq!(key.get_u64("u32")?, 123u64); assert_eq!(u32::try_from(key.get_value("u32")?)?, 123u32); assert_eq!(unsafe { key.raw_get_info(w!("u32"))? }, (Type::U32, 4)); - key.set_value("u64", &Value::try_from(123u64)?)?; + key.set_value("u64", &Value::from(123u64))?; assert_eq!(key.get_type("u64")?, Type::U64); - assert_eq!(key.get_value("u64")?, Value::try_from(123u64)?); + assert_eq!(key.get_value("u64")?, Value::from(123u64)); assert_eq!(key.get_u32("u64")?, 123u32); assert_eq!(key.get_u64("u64")?, 123u64); assert_eq!(u64::try_from(key.get_value("u64")?)?, 123u64); assert_eq!(unsafe { key.raw_get_info(w!("u64"))? }, (Type::U64, 8)); - key.set_value("string", &Value::try_from("string")?)?; + key.set_value("string", &Value::from("string"))?; assert_eq!(key.get_type("string")?, Type::String); - assert_eq!(key.get_value("string")?, Value::try_from("string")?); + assert_eq!(key.get_value("string")?, Value::from("string")); assert_eq!(key.get_string("string")?, "string"); assert_eq!(String::try_from(key.get_value("string")?)?, "string"); @@ -36,7 +36,7 @@ fn value() -> Result<()> { (Type::String, 14) ); - let mut value = Value::try_from("expand")?; + let mut value = Value::from("expand"); value.set_ty(Type::ExpandString); assert_eq!(value.ty(), Type::ExpandString); key.set_value("expand", &value)?; @@ -49,13 +49,13 @@ fn value() -> Result<()> { (Type::ExpandString, 14) ); - key.set_value("bytes", &Value::try_from([1u8, 2u8, 3u8])?)?; + key.set_value("bytes", &Value::from([1u8, 2u8, 3u8]))?; assert_eq!(key.get_type("bytes")?, Type::Bytes); - assert_eq!(key.get_value("bytes")?, Value::try_from([1, 2, 3])?); + assert_eq!(key.get_value("bytes")?, Value::from([1, 2, 3])); assert_eq!(unsafe { key.raw_get_info(w!("bytes"))? }, (Type::Bytes, 3)); - let mut value = Value::try_from([1u8, 2u8, 3u8, 4u8].as_slice())?; + let mut value = Value::from([1u8, 2u8, 3u8, 4u8].as_slice()); value.set_ty(Type::Other(1234)); key.set_value("slice", &value)?; assert_eq!(key.get_type("slice")?, Type::Other(1234)); @@ -66,9 +66,9 @@ fn value() -> Result<()> { (Type::Other(1234), 4) ); - key.set_value("hstring", &Value::try_from(h!("HSTRING"))?)?; + key.set_value("hstring", &Value::from(h!("HSTRING")))?; assert_eq!(key.get_type("hstring")?, Type::String); - assert_eq!(key.get_value("hstring")?, Value::try_from(h!("HSTRING"))?); + assert_eq!(key.get_value("hstring")?, Value::from(h!("HSTRING"))); assert_eq!(key.get_string("hstring")?, "HSTRING"); assert_eq!(HSTRING::try_from(key.get_value("hstring")?)?, "HSTRING"); @@ -77,9 +77,9 @@ fn value() -> Result<()> { (Type::String, 16) ); - let abc = Value::try_from("abc")?; + let abc = Value::from("abc"); assert_eq!(abc.as_wide(), &[97, 98, 99, 0]); - let abc = Value::try_from(h!("abcd"))?; + let abc = Value::from(h!("abcd")); assert_eq!(abc.as_wide(), &[97, 98, 99, 100, 0]); Ok(()) diff --git a/crates/tests/registry/tests/values.rs b/crates/tests/registry/tests/values.rs index e846138abe..9ad13514c7 100644 --- a/crates/tests/registry/tests/values.rs +++ b/crates/tests/registry/tests/values.rs @@ -16,9 +16,9 @@ fn values() -> Result<()> { assert_eq!( names, [ - ("u32".to_string(), Value::try_from(123u32)?), - ("u64".to_string(), Value::try_from(456u64)?), - ("string".to_string(), Value::try_from("hello world")?), + ("u32".to_string(), Value::from(123u32)), + ("u64".to_string(), Value::from(456u64)), + ("string".to_string(), Value::from("hello world")), ] ); diff --git a/crates/tools/bindings/src/registry.txt b/crates/tools/bindings/src/registry.txt index 6bc398c2bd..917ea742a7 100644 --- a/crates/tools/bindings/src/registry.txt +++ b/crates/tools/bindings/src/registry.txt @@ -4,7 +4,6 @@ --filter Windows.Win32.Foundation.ERROR_INVALID_DATA Windows.Win32.Foundation.ERROR_NO_MORE_ITEMS - Windows.Win32.Foundation.ERROR_OUTOFMEMORY Windows.Win32.System.Memory.GetProcessHeap Windows.Win32.System.Memory.HeapAlloc Windows.Win32.System.Memory.HeapFree