From cf3659fc6f88cbbc19a2f99e2a02ed2c058fd036 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Mon, 11 Nov 2019 19:57:48 -0800 Subject: [PATCH] Fix CFRunLoop types to avoid UB A number of callback functions associated with the CFRunLoop types are allowed to be NULL to evoke default behavior. Prior to this commit the definition of those structs prevented passing in null which meant resorting to transmute or other tricks to effectively set null, but with recent compiler versions the compiler emits `ud2` instructions and triggers a fault at runtime. The correct resolution for this is to define these fields as `Option`al callbacks and that is what this commit does. I've used this approach successfully here in another project: Refs: https://github.com/wez/wezterm/commit/398f333c32fb1ff4ccd9cc001a66ae22522eb60c I've bumped up the version for the crate as part of this commit because it effectively changes the API around these structs. --- core-foundation-sys/Cargo.toml | 2 +- core-foundation-sys/src/runloop.rs | 38 +++++++++++++++--------------- core-foundation/Cargo.toml | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/core-foundation-sys/Cargo.toml b/core-foundation-sys/Cargo.toml index 16e1ff2..9fb311d 100644 --- a/core-foundation-sys/Cargo.toml +++ b/core-foundation-sys/Cargo.toml @@ -3,7 +3,7 @@ name = "core-foundation-sys" description = "Bindings to Core Foundation for macOS" homepage = "https://github.com/servo/core-foundation-rs" repository = "https://github.com/servo/core-foundation-rs" -version = "0.6.3" +version = "0.7.0" authors = ["The Servo Project Developers"] license = "MIT / Apache-2.0" build = "build.rs" diff --git a/core-foundation-sys/src/runloop.rs b/core-foundation-sys/src/runloop.rs index cfaf9db..53035a2 100644 --- a/core-foundation-sys/src/runloop.rs +++ b/core-foundation-sys/src/runloop.rs @@ -50,13 +50,13 @@ pub const kCFRunLoopAllActivities: CFOptionFlags = 0x0FFFFFFF; pub struct CFRunLoopSourceContext { pub version: CFIndex, pub info: *mut c_void, - pub retain: extern "C" fn (info: *const c_void) -> *const c_void, - pub release: extern "C" fn (info: *const c_void), - pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, - pub equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, - pub hash: extern "C" fn (info: *const c_void) -> CFHashCode, - pub schedule: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), - pub cancel: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), + pub retain: Option *const c_void>, + pub release: Option, + pub copyDescription: Option CFStringRef>, + pub equal: Option Boolean>, + pub hash: Option CFHashCode>, + pub schedule: Option, + pub cancel: Option, pub perform: extern "C" fn (info: *const c_void), } @@ -64,11 +64,11 @@ pub struct CFRunLoopSourceContext { pub struct CFRunLoopSourceContext1 { pub version: CFIndex, pub info: *mut c_void, - pub retain: extern "C" fn (info: *const c_void) -> *const c_void, - pub release: extern "C" fn (info: *const c_void), - pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, - pub equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, - pub hash: extern "C" fn (info: *const c_void) -> CFHashCode, + pub retain: Option *const c_void>, + pub release: Option, + pub copyDescription: Option CFStringRef>, + pub equal: Option Boolean>, + pub hash: Option CFHashCode>, // note that the following two fields are platform dependent in the C header, the ones here are for macOS pub getPort: extern "C" fn (info: *mut c_void) -> mach_port_t, pub perform: extern "C" fn (msg: *mut c_void, size: CFIndex, allocator: CFAllocatorRef, info: *mut c_void) -> *mut c_void, @@ -78,9 +78,9 @@ pub struct CFRunLoopSourceContext1 { pub struct CFRunLoopObserverContext { pub version: CFIndex, pub info: *mut c_void, - pub retain: extern "C" fn (info: *const c_void) -> *const c_void, - pub release: extern "C" fn (info: *const c_void), - pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, + pub retain: Option *const c_void>, + pub release: Option, + pub copyDescription: Option CFStringRef>, } pub type CFRunLoopObserverCallBack = extern "C" fn (observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void); @@ -89,15 +89,15 @@ pub type CFRunLoopObserverCallBack = extern "C" fn (observer: CFRunLoopObserverR pub struct CFRunLoopTimerContext { pub version: CFIndex, pub info: *mut c_void, - pub retain: extern "C" fn (info: *const c_void) -> *const c_void, - pub release: extern "C" fn (info: *const c_void), - pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, + pub retain: Option *const c_void>, + pub release: Option, + pub copyDescription: Option CFStringRef>, } pub type CFRunLoopTimerCallBack = extern "C" fn (timer: CFRunLoopTimerRef, info: *mut c_void); #[repr(C)] -pub struct __CFRunLoopTimer; +pub struct __CFRunLoopTimer(c_void); pub type CFRunLoopTimerRef = *mut __CFRunLoopTimer; diff --git a/core-foundation/Cargo.toml b/core-foundation/Cargo.toml index b36beb6..38d4abf 100644 --- a/core-foundation/Cargo.toml +++ b/core-foundation/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["macos", "framework", "objc"] [dependencies.core-foundation-sys] path = "../core-foundation-sys" -version = "0.6.1" +version = "0.7.0" [dependencies] libc = "0.2"