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 almost 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 04c68b6
Show file tree
Hide file tree
Showing 10 changed files with 67 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
11 changes: 6 additions & 5 deletions native-windows-gui/src/controls/tabs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use winapi::um::winuser::{EnumChildWindows, WS_VISIBLE, WS_DISABLED, WS_EX_CONTR
use crate::win32::{base_helper::{to_utf16, check_hwnd}, window_helper as wh};
use crate::{NwgError, Font, RawEventHandler, unbind_raw_event_handler};
use super::{ControlBase, ControlHandle};
use std::intrinsics::saturating_add;
use std::{mem, cell::RefCell};

#[cfg(feature="image-list")]
Expand Down Expand Up @@ -265,7 +266,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 +319,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 +613,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 +758,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 +769,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 04c68b6

Please sign in to comment.