Skip to content

Commit 4b2d520

Browse files
committed
ios: Check we're on the main thread before opening URL
`-[UIApplication openURL:options:completionHandler:]` is not safe to use from a thread that is not the main thread, since `UIApplication` is marked as `NS_SWIFT_UI_ACTOR` in the header, and the method is not marked with `NS_SWIFT_NONISOLATED` (unlike e.g. `canOpenURL:`).
1 parent 3620f60 commit 4b2d520

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/ios.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@ use crate::{Browser, BrowserOptions, Error, ErrorKind, Result, TargetType};
22
use block2::Block;
33
use objc2::rc::Retained;
44
use objc2::runtime::Bool;
5-
use objc2::{class, msg_send};
5+
use objc2::{class, msg_send, MainThreadMarker};
66
use objc2_foundation::{NSDictionary, NSObject, NSString, NSURL};
77

8-
fn app() -> Option<Retained<NSObject>> {
8+
fn app(mtm: MainThreadMarker) -> Option<Retained<NSObject>> {
9+
let _ = mtm;
10+
// SAFETY: The signature is correct, and we hold `MainThreadMarker`, so we
11+
// know we're on the main thread where it's safe to access the shared
12+
// UIApplication.
13+
//
14+
// NOTE: `sharedApplication` is declared as returning non-NULL, but it
15+
// will only do so inside `UIApplicationMain`; if called outside, the
16+
// shared application is NULL.
917
unsafe { msg_send![class!(UIApplication), sharedApplication] }
1018
}
1119

@@ -29,12 +37,19 @@ pub(super) fn open_browser_internal(
2937
// ensure we're opening only http/https urls, failing otherwise
3038
let url = target.get_http_url()?;
3139

40+
let mtm = MainThreadMarker::new().ok_or_else(|| {
41+
Error::new(
42+
ErrorKind::Other,
43+
"Cannot open URL from a thread that is not the main thread",
44+
)
45+
})?;
46+
3247
// always return true for a dry run
3348
if options.dry_run {
3449
return Ok(());
3550
}
3651

37-
let app = app().ok_or(Error::new(
52+
let app = app(mtm).ok_or(Error::new(
3853
ErrorKind::Other,
3954
"UIApplication is null, can't open url",
4055
))?;

0 commit comments

Comments
 (0)