diff --git a/examples/intellisense-tu.rs b/examples/intellisense-tu.rs index fcdd8f5..974972c 100644 --- a/examples/intellisense-tu.rs +++ b/examples/intellisense-tu.rs @@ -32,6 +32,7 @@ fn main() { let name = cursor.get_display_name().unwrap(); println!("Name {:?}", name); + assert_eq!(name, "copy.hlsl"); let cursor_kind = cursor.get_kind().unwrap(); println!("CursorKind {:?}", cursor_kind); @@ -42,6 +43,19 @@ fn main() { let child_cursors = cursor.get_all_children().unwrap(); + assert_eq!( + child_cursors[0].get_display_name(), + Ok("g_input".to_owned()) + ); + assert_eq!( + child_cursors[1].get_display_name(), + Ok("g_output".to_owned()) + ); + assert_eq!( + child_cursors[2].get_display_name(), + Ok("copyCs(uint3)".to_owned()) + ); + for child_cursor in child_cursors { let range = child_cursor.get_extent().unwrap(); println!("Child Range {:?}", range); diff --git a/src/utils.rs b/src/utils.rs index db504cd..eff0f9c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -13,16 +13,19 @@ pub(crate) fn from_wide(wide: LPWSTR) -> String { unsafe { widestring::WideCStr::from_ptr_str(wide) .to_string() - .expect("utf16 decode failed") + .expect("widestring decode failed") } } #[cfg(windows)] pub(crate) fn from_bstr(string: BSTR) -> String { unsafe { - let len = SysStringLen(string); - let slice: &[WCHAR] = ::std::slice::from_raw_parts(string, len as usize); - let result = String::from_utf16(slice).unwrap(); + let len = SysStringLen(string) as usize; + + let result = widestring::WideCStr::from_ptr_with_nul(string, len) + .to_string() + .expect("widestring decode failed"); + SysFreeString(string); result } @@ -30,10 +33,14 @@ pub(crate) fn from_bstr(string: BSTR) -> String { #[cfg(not(windows))] pub(crate) fn from_bstr(string: BSTR) -> String { - // TODO (Marijn): This does NOT cover embedded NULLs: - // https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysstringlen#remarks - // Fortunately BSTRs are only used in names currently, which _likely_ don't include NULL characters (like binary data) - let result = from_lpstr(string as LPSTR); + // TODO (Marijn): This does NOT cover embedded NULLs + + // BSTR contains its size in the four bytes preceding the pointer, in order to contain NULL bytes: + // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr + // DXC on non-Windows does not adhere to that and simply allocates a buffer without prepending the size: + // https://github.com/microsoft/DirectXShaderCompiler/blob/a8d9780046cb64a1cea842fa6fc28a250e3e2c09/include/dxc/Support/WinAdapter.h#L49-L50 + let result = from_wide(string as LPWSTR); + unsafe { SysFreeString(string) }; result }