Skip to content

Commit

Permalink
Replace transmuted references with explicit pointer type casts
Browse files Browse the repository at this point in the history
This commit replaces all usages of `std::mem::transmute` on references in the codebase with explicit pointer type casts.
This is done to prevent undefined behavior caused by transmuting integer types to references, and subsequently dereferencing them.
  • Loading branch information
nickbeth committed Nov 10, 2024
1 parent a6c96e8 commit f7e348b
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 62 deletions.
15 changes: 9 additions & 6 deletions native-windows-gui/src/controls/date_picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl DatePicker {

let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);

let info = unsafe{ get_dtp_info(handle) };
let info = get_dtp_info(handle);

match info.stateCheck {
STATE_SYSTEM_CHECKED => true,
Expand All @@ -185,13 +185,15 @@ impl DatePicker {
pub fn value(&self) -> Option<DatePickerValue> {
use winapi::um::commctrl::{GDT_VALID, DTM_GETSYSTEMTIME};
use winapi::um::minwinbase::SYSTEMTIME;
use winapi::shared::minwindef::LPARAM;
use std::mem;

let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);

let mut syst: SYSTEMTIME = unsafe{ mem::zeroed() };
let syst_ptr = &mut syst as *mut _;

let r = unsafe{ wh::send_message(handle, DTM_GETSYSTEMTIME, 0, mem::transmute(&mut syst)) };
let r = wh::send_message(handle, DTM_GETSYSTEMTIME, 0, syst_ptr as LPARAM);
match r {
GDT_VALID => Some(DatePickerValue {
year: syst.wYear,
Expand Down Expand Up @@ -488,14 +490,15 @@ impl<'a> DatePickerBuilder<'a> {
use winapi::um::commctrl::DATETIMEPICKERINFO;
use winapi::shared::windef::HWND;

unsafe fn get_dtp_info(handle: HWND) -> DATETIMEPICKERINFO {
fn get_dtp_info(handle: HWND) -> DATETIMEPICKERINFO {
use winapi::um::commctrl::DTM_GETDATETIMEPICKERINFO;
use winapi::shared::minwindef::DWORD;
use winapi::shared::minwindef::{DWORD, LPARAM};
use std::mem;

let mut dtp_info: DATETIMEPICKERINFO = mem::zeroed();
let mut dtp_info: DATETIMEPICKERINFO = unsafe { mem::zeroed() };
dtp_info.cbSize = mem::size_of::<DATETIMEPICKERINFO>() as DWORD;
wh::send_message(handle, DTM_GETDATETIMEPICKERINFO, 0, mem::transmute(&mut dtp_info));
let dtp_info_ptr = &mut dtp_info as *mut _;
wh::send_message(handle, DTM_GETDATETIMEPICKERINFO, 0, dtp_info_ptr as LPARAM);

dtp_info
}
7 changes: 3 additions & 4 deletions native-windows-gui/src/controls/extern_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,13 @@ impl ExternCanvas {
/// - icon: The new icon. If None, the icon is removed
pub fn set_icon(&self, icon: Option<&Icon>) {
use winapi::um::winuser::WM_SETICON;
use std::{mem, ptr};
use winapi::shared::minwindef::LPARAM;
use std::ptr;

let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);

let image_handle = icon.map(|i| i.handle).unwrap_or(ptr::null_mut());
unsafe {
wh::send_message(handle, WM_SETICON, 0, mem::transmute(image_handle));
}
wh::send_message(handle, WM_SETICON, 0, image_handle as LPARAM);
}

/// Return true if the control currently has the keyboard focus
Expand Down
34 changes: 11 additions & 23 deletions native-windows-gui/src/controls/list_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,7 @@ impl<D: Display+Default> ListBox<D> {
let display = format!("{}", item);
let display_os = to_utf16(&display);

unsafe {
wh::send_message(handle, LB_ADDSTRING, 0, mem::transmute(display_os.as_ptr()));
}
wh::send_message(handle, LB_ADDSTRING, 0, display_os.as_ptr() as LPARAM);

self.collection.borrow_mut().push(item);
}
Expand All @@ -131,9 +129,7 @@ impl<D: Display+Default> ListBox<D> {
col.insert(index, item);
}

unsafe {
wh::send_message(handle, LB_INSERTSTRING, index, mem::transmute(display_os.as_ptr()));
}
wh::send_message(handle, LB_INSERTSTRING, index, display_os.as_ptr() as LPARAM);
}


Expand Down Expand Up @@ -215,10 +211,8 @@ impl<D: Display+Default> ListBox<D> {
let index = index as usize;
let length = (wh::send_message(handle, LB_GETTEXTLEN, index, 0) as usize) + 1; // +1 for the terminating null character
let mut buffer: Vec<WCHAR> = Vec::with_capacity(length);
unsafe {
buffer.set_len(length);
wh::send_message(handle, LB_GETTEXT, index, mem::transmute(buffer.as_ptr()));
}
unsafe { buffer.set_len(length); }
wh::send_message(handle, LB_GETTEXT, index, buffer.as_ptr() as LPARAM);

Some(from_utf16(&buffer))
}
Expand Down Expand Up @@ -292,13 +286,11 @@ impl<D: Display+Default> ListBox<D> {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
let os_string = to_utf16(value);

unsafe {
let index = wh::send_message(handle, LB_SELECTSTRING, 0, mem::transmute(os_string.as_ptr()));
if index == LB_ERR {
None
} else {
Some(index as usize)
}
let index = wh::send_message(handle, LB_SELECTSTRING, 0, os_string.as_ptr() as LPARAM);
if index == LB_ERR {
None
} else {
Some(index as usize)
}
}

Expand Down Expand Up @@ -327,9 +319,7 @@ impl<D: Display+Default> ListBox<D> {
let display = format!("{}", item);
let display_os = to_utf16(&display);

unsafe {
wh::send_message(handle, LB_ADDSTRING, 0, mem::transmute(display_os.as_ptr()));
}
wh::send_message(handle, LB_ADDSTRING, 0, display_os.as_ptr() as LPARAM);
}
}

Expand All @@ -345,9 +335,7 @@ impl<D: Display+Default> ListBox<D> {
let display = format!("{}", item);
let display_os = to_utf16(&display);

unsafe {
wh::send_message(handle, LB_ADDSTRING, 0, mem::transmute(display_os.as_ptr()));
}
wh::send_message(handle, LB_ADDSTRING, 0, display_os.as_ptr() as LPARAM);
}

let mut col_ref = self.collection.borrow_mut();
Expand Down
10 changes: 5 additions & 5 deletions native-windows-gui/src/controls/tabs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl TabsContainer {
let handler0 = bind_raw_event_handler_inner(&parent_handle, handle as usize, move |_hwnd, msg, _w, l| { unsafe {
match msg {
WM_NOTIFY => {
let nmhdr: &NMHDR = mem::transmute(l);
let nmhdr = &*(l as *const NMHDR);
if nmhdr.code == TCN_SELCHANGE {
let index = SendMessageW(handle, TCM_GETCURSEL, 0, 0) as i32;
let data: (HWND, i32) = (handle, index);
Expand Down Expand Up @@ -318,7 +318,7 @@ impl TabsContainer {
data.tab_offset_y = tab_height;

let data_ptr = &data as *const ResizeDirectChildrenParams;
EnumChildWindows(hwnd, Some(resize_direct_children), mem::transmute(data_ptr));
EnumChildWindows(hwnd, Some(resize_direct_children), data_ptr as LPARAM);
},
_ => {}
}
Expand Down Expand Up @@ -612,7 +612,7 @@ impl Tab {
let count_ptr = &mut count as *mut usize;

unsafe {
EnumChildWindows(tab_view_handle, Some(count_children), mem::transmute(count_ptr));
EnumChildWindows(tab_view_handle, Some(count_children), count_ptr as LPARAM);
}

count
Expand Down Expand Up @@ -757,7 +757,7 @@ unsafe extern "system" fn count_children(handle: HWND, params: LPARAM) -> BOOL {

if &wh::get_window_class_name(handle) == "NWG_TAB" {
let tab_index = (wh::get_window_long(handle, GWL_USERDATA)) as WPARAM;
let count: &mut usize = ::std::mem::transmute(params);
let count = params as *mut usize;
*count = usize::max(tab_index+1, *count);
}

Expand All @@ -768,7 +768,7 @@ unsafe extern "system" fn count_children(handle: HWND, params: LPARAM) -> BOOL {
unsafe extern "system" fn toggle_children_tabs(handle: HWND, params: LPARAM) -> BOOL {
use winapi::um::winuser::GWL_USERDATA;

let &(parent, index): &(HWND, i32) = mem::transmute(params);
let (parent, index) = *(params as *const (HWND, i32));
if wh::get_window_parent(handle) == parent {
let tab_index = wh::get_window_long(handle, GWL_USERDATA) as i32;
let visible = tab_index == index + 1;
Expand Down
7 changes: 3 additions & 4 deletions native-windows-gui/src/controls/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,13 @@ impl Window {
/// - icon: The new icon. If None, the icon is removed
pub fn set_icon(&self, icon: Option<&Icon>) {
use winapi::um::winuser::WM_SETICON;
use std::{mem, ptr};
use winapi::shared::minwindef::LPARAM;
use std::ptr;

let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);

let image_handle = icon.map(|i| i.handle).unwrap_or(ptr::null_mut());
unsafe {
wh::send_message(handle, WM_SETICON, 0, mem::transmute(image_handle));
}
wh::send_message(handle, WM_SETICON, 0, image_handle as LPARAM);
}

/// Return true if the control currently has the keyboard focus
Expand Down
4 changes: 2 additions & 2 deletions native-windows-gui/src/resources/file_dialog.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use winapi::um::shobjidl::IFileDialog;
use winapi::um::shobjidl::{IFileDialog, IFileOpenDialog};
use crate::win32::resources_helper as rh;

use crate::win32::base_helper::to_utf16;
Expand Down Expand Up @@ -115,7 +115,7 @@ impl FileDialog {
}

unsafe {
rh::filedialog_get_items(mem::transmute(&mut *self.handle))
rh::filedialog_get_items(&mut *(self.handle as *mut IFileOpenDialog))
}
}

Expand Down
5 changes: 3 additions & 2 deletions native-windows-gui/src/win32/menu.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*!
Native Windows GUI menu base.
*/
use winapi::shared::basetsd::UINT_PTR;
use winapi::shared::windef::{HMENU, HWND};
use winapi::shared::minwindef::UINT;
use super::base_helper::{CUSTOM_ID_BEGIN, to_utf16};
Expand Down Expand Up @@ -70,7 +71,7 @@ pub unsafe fn build_hmenu_control(text: Option<String>, item: bool, separator: b
return Err(NwgError::menu_create("Menu without parent"));
}
use_menu_command(menu);
AppendMenuW(menubar, flags, mem::transmute(menu), text.as_ptr());
AppendMenuW(menubar, flags, menu as UINT_PTR, text.as_ptr());
}

// Draw the menu bar to make sure the changes are visible
Expand All @@ -89,7 +90,7 @@ pub unsafe fn build_hmenu_control(text: Option<String>, item: bool, separator: b
return Err(NwgError::menu_create("Menu without parent"));
}
use_menu_command(menu);
AppendMenuW(parent, flags, mem::transmute(menu), text.as_ptr());
AppendMenuW(parent, flags, menu as UINT_PTR, text.as_ptr());
}
}

Expand Down
10 changes: 6 additions & 4 deletions native-windows-gui/src/win32/resources_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,15 @@ pub unsafe fn create_file_dialog<'a, 'b>(
use winapi::um::shobjidl::{FOS_PICKFOLDERS, FOS_ALLOWMULTISELECT, FOS_FORCEFILESYSTEM};
use winapi::um::combaseapi::CoCreateInstance;
use winapi::shared::{wtypesbase::CLSCTX_INPROC_SERVER, winerror::S_OK};
use winapi::shared::minwindef::LPVOID;

let (clsid, uuid) = match action {
FileDialogAction::Save => (CLSID_FileSaveDialog, IFileDialog::uuidof()),
_ => (CLSID_FileOpenDialog, IFileOpenDialog::uuidof())
};

let mut handle: *mut IFileDialog = ptr::null_mut();
let r = CoCreateInstance(&clsid, ptr::null_mut(), CLSCTX_INPROC_SERVER, &uuid, mem::transmute(&mut handle) );
let r = CoCreateInstance(&clsid, ptr::null_mut(), CLSCTX_INPROC_SERVER, &uuid, &mut handle as *mut _ as *mut LPVOID);
if r != S_OK {
return Err(NwgError::file_dialog("Filedialog creation failed"));
}
Expand Down Expand Up @@ -418,7 +419,7 @@ pub unsafe fn file_dialog_set_default_folder<'a>(dialog: &mut IFileDialog, folde
let mut shellitem: *mut IShellItem = ptr::null_mut();
let path = to_utf16(&folder_name);

if SHCreateItemFromParsingName(path.as_ptr(), ptr::null_mut(), &IShellItem::uuidof(), mem::transmute(&mut shellitem) ) != S_OK {
if SHCreateItemFromParsingName(path.as_ptr(), ptr::null_mut(), &IShellItem::uuidof(), &mut shellitem as *mut _ as *mut *mut c_void) != S_OK {
return Err(NwgError::file_dialog("Failed to set default folder"));
}

Expand Down Expand Up @@ -504,7 +505,7 @@ pub unsafe fn filedialog_get_items(dialog: &mut IFileOpenDialog) -> Result<Vec<O
let mut _item: *mut IShellItem = ptr::null_mut();
let mut _items: *mut IShellItemArray = ptr::null_mut();

if dialog.GetResults( mem::transmute(&mut _items) ) != S_OK {
if dialog.GetResults(&mut _items as *mut _) != S_OK {
return Err(NwgError::file_dialog("Failed to get dialog items"));
}

Expand All @@ -530,6 +531,7 @@ pub unsafe fn filedialog_get_items(dialog: &mut IFileOpenDialog) -> Result<Vec<O
unsafe fn get_ishellitem_path(item: &mut IShellItem) -> Result<OsString, NwgError> {
use winapi::um::shobjidl_core::SIGDN_FILESYSPATH;
use winapi::shared::{ntdef::PWSTR, winerror::S_OK};
use winapi::shared::minwindef::LPVOID;
use winapi::um::combaseapi::CoTaskMemFree;
use super::base_helper::os_string_from_wide_ptr;

Expand All @@ -540,7 +542,7 @@ unsafe fn get_ishellitem_path(item: &mut IShellItem) -> Result<OsString, NwgErro

let text = os_string_from_wide_ptr(item_path, None);

CoTaskMemFree(mem::transmute(item_path));
CoTaskMemFree(item_path as LPVOID);

Ok(text)
}
Expand Down
29 changes: 22 additions & 7 deletions native-windows-gui/src/win32/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,17 +597,17 @@ unsafe extern "system" fn process_events(hwnd: HWND, msg: UINT, w: WPARAM, l: LP
},
WM_NOTIFY => {
let code = {
let notif_ptr: *mut NMHDR = mem::transmute(l);
let notif_ptr = l as *mut NMHDR;
(&*notif_ptr).code
};

match code {
TTN_GETDISPINFOW => handle_tooltip_callback(mem::transmute::<_, *mut NMTTDISPINFOW>(l), callback),
_ => handle_default_notify_callback(mem::transmute::<_, *const NMHDR>(l), callback)
TTN_GETDISPINFOW => handle_tooltip_callback(l as *mut NMTTDISPINFOW, callback),
_ => handle_default_notify_callback(l as *const NMHDR, callback)
}
},
WM_MENUCOMMAND => {
let parent_handle: HMENU = mem::transmute(l);
let parent_handle = l as HMENU;
let item_id = GetMenuItemID(parent_handle, w as i32);
let handle = ControlHandle::MenuItem(parent_handle, item_id);
callback(Event::OnMenuItemSelected, NO_DATA, handle);
Expand Down Expand Up @@ -1074,7 +1074,12 @@ unsafe fn GetWindowSubclass(hwnd: HWND, proc: SUBCLASSPROC, uid: UINT_PTR, data:
SUBCLASS_COLLECTION = Some(Mutex::new(HashMap::new()));
}

let id = (hwnd as usize, mem::transmute(proc), uid);
let proc_id = match proc {
Some(p) => p as usize,
None => 0
};

let id = (hwnd as usize, proc_id, uid);
match SUBCLASS_COLLECTION.as_ref() {
Some(collection_mutex) => {
let collection = collection_mutex.lock().unwrap();
Expand All @@ -1096,7 +1101,12 @@ unsafe fn SetWindowSubclass(hwnd: HWND, proc: SUBCLASSPROC, uid: UINT_PTR, data:
SUBCLASS_COLLECTION = Some(Mutex::new(HashMap::new()));
}

let id = (hwnd as usize, mem::transmute(proc), uid);
let proc_id = match proc {
Some(p) => p as usize,
None => 0
};

let id = (hwnd as usize, proc_id, uid);
match SUBCLASS_COLLECTION.as_ref() {
Some(collection_mutex) => {
let mut collection = collection_mutex.lock().unwrap();
Expand All @@ -1119,7 +1129,12 @@ unsafe fn RemoveWindowSubclass(hwnd: HWND, proc: SUBCLASSPROC, uid: UINT_PTR) ->
SUBCLASS_COLLECTION = Some(Mutex::new(HashMap::new()));
}

let id = (hwnd as usize, mem::transmute(proc), uid);
let proc_id = match proc {
Some(p) => p as usize,
None => 0
};

let id = (hwnd as usize, proc_id, uid);
match SUBCLASS_COLLECTION.as_ref() {
Some(collection_mutex) => {
let mut collection = collection_mutex.lock().unwrap();
Expand Down
7 changes: 2 additions & 5 deletions native-windows-gui/src/win32/window_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,7 @@ pub fn get_window_parent(hwnd: HWND) -> HWND {

pub fn get_window_font(handle: HWND) -> HFONT {
use winapi::um::winuser::{ WM_GETFONT };
unsafe {
let h = send_message(handle, WM_GETFONT, 0, 0);
mem::transmute(h)
}
send_message(handle, WM_GETFONT, 0, 0) as HFONT
}

pub fn maximize_window(handle: HWND) {
Expand Down Expand Up @@ -203,7 +200,7 @@ pub unsafe fn set_window_font(handle: HWND, font_handle: Option<HFONT>, redraw:

let font_handle = font_handle.unwrap_or(ptr::null_mut());

SendMessageW(handle, WM_SETFONT, mem::transmute(font_handle), redraw as LPARAM);
SendMessageW(handle, WM_SETFONT, font_handle as WPARAM, redraw as LPARAM);
}


Expand Down

0 comments on commit f7e348b

Please sign in to comment.