diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e12e40..57237ac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - **Breaking:** On iOS, `UIView` is now the default root view. `WindowBuilderExt::with_root_view_class` can be used to set the root view objective-c class to `GLKView` (OpenGLES) or `MTKView` (Metal/MoltenVK). - On iOS, the `UIApplication` is not started until `Window::new` is called. - Fixed thread unsafety with cursor hiding on macOS. +- On iOS, fixed the size of the `JmpBuf` type used for `setjmp`/`longjmp` calls. Previously this was a buffer overflow on most architectures. # Version 0.16.2 (2018-07-07) diff --git a/src/platform/ios/ffi.rs b/src/platform/ios/ffi.rs index 3e69d128..6fd1a7ca 100644 --- a/src/platform/ios/ffi.rs +++ b/src/platform/ios/ffi.rs @@ -64,10 +64,20 @@ extern { extern { pub fn setjmp(env: *mut c_void) -> c_int; - pub fn longjmp(env: *mut c_void, val: c_int); + pub fn longjmp(env: *mut c_void, val: c_int) -> !; } -pub type JmpBuf = [c_int; 27]; +// values taken from "setjmp.h" header in xcode iPhoneOS/iPhoneSimulator SDK +#[cfg(any(target_arch = "x86_64"))] +pub const JBLEN: usize = (9 * 2) + 3 + 16; +#[cfg(any(target_arch = "x86"))] +pub const JBLEN: usize = 18; +#[cfg(target_arch = "arm")] +pub const JBLEN: usize = 10 + 16 + 2; +#[cfg(target_arch = "aarch64")] +pub const JBLEN: usize = (14 + 8 + 2) * 2; + +pub type JmpBuf = [c_int; JBLEN]; pub trait NSString: Sized { unsafe fn alloc(_: Self) -> id { diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index b18bf226..1c8e7c85 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -92,6 +92,7 @@ use self::ffi::{ CGPoint, CGRect, id, + JBLEN, JmpBuf, kCFRunLoopDefaultMode, kCFRunLoopRunHandledSource, @@ -209,7 +210,7 @@ impl EventsLoop { pub fn new() -> EventsLoop { unsafe { if !msg_send![class!(NSThread), isMainThread] { - panic!("`Window` can only be created on the main thread on iOS"); + panic!("`EventsLoop` can only be created on the main thread on iOS"); } } EventsLoop { events_queue: Default::default() } @@ -315,7 +316,7 @@ impl Window { ) -> Result { unsafe { debug_assert!(mem::size_of_val(&JMPBUF) == mem::size_of::>()); - assert!(mem::replace(&mut JMPBUF, Some(Box::new([0; 27]))).is_none(), "Only one `Window` is supported on iOS"); + assert!(mem::replace(&mut JMPBUF, Some(Box::new([0; JBLEN]))).is_none(), "Only one `Window` is supported on iOS"); } unsafe {