Repository: tauri-apps/wry (language: rust)

Issue:
WebContext segfault on macOS
**Describe the bug**
If the webcontext is dropped while the webview is still alive, there will be a segfault since the pointer lifetime is not properly tied to the webview.

We ran into this in Dioxus.

https://github.com/DioxusLabs/dioxus/pull/935

The solution is to keep the pointer around, either internally via making webcontext owned instead of `&mut` or by leaking it.

**Platform and Versions (please complete the following information):**
OS: macOS
Rustc: 1.68.2

**Would you want to assign yourself to resolve this bug?**
- [ ] Yes
- [x] No





Discussion / hints:

Fix patch:
diff --git a/.changes/fix-webcontext.md b/.changes/fix-webcontext.md
new file mode 100644
index 000000000..2b3679b84
--- /dev/null
+++ b/.changes/fix-webcontext.md
@@ -0,0 +1,5 @@
+---
+"wry": patch
+---
+
+On macOS and iOS, remove webcontext implementation since we don't actually use it. This also fix segfault if users drop webcontext early.
diff --git a/src/webview/web_context.rs b/src/webview/web_context.rs
index 714e282c7..216b7b5a2 100644
--- a/src/webview/web_context.rs
+++ b/src/webview/web_context.rs
@@ -10,8 +10,6 @@
   target_os = "openbsd"
 ))]
 use crate::webview::webkitgtk::WebContextImpl;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-use crate::webview::wkwebview::WebContextImpl;
 
 use std::path::{Path, PathBuf};
 
@@ -93,11 +91,21 @@ impl WebContextData {
   }
 }
 
-#[cfg(any(target_os = "windows", target_os = "android"))]
+#[cfg(any(
+  target_os = "windows",
+  target_os = "android",
+  target_os = "macos",
+  target_os = "ios"
+))]
 #[derive(Debug)]
 pub(crate) struct WebContextImpl;
 
-#[cfg(any(target_os = "windows", target_os = "android"))]
+#[cfg(any(
+  target_os = "windows",
+  target_os = "android",
+  target_os = "macos",
+  target_os = "ios"
+))]
 impl WebContextImpl {
   fn new(_data: &WebContextData) -> Self {
     Self
diff --git a/src/webview/wkwebview/mod.rs b/src/webview/wkwebview/mod.rs
index 98889c43f..56ccb4fb5 100644
--- a/src/webview/wkwebview/mod.rs
+++ b/src/webview/wkwebview/mod.rs
@@ -5,10 +5,8 @@
 mod download;
 #[cfg(target_os = "macos")]
 mod file_drop;
-mod web_context;
 
 use url::Url;
-pub use web_context::WebContextImpl;
 
 #[cfg(target_os = "macos")]
 use cocoa::appkit::{NSView, NSViewHeightSizable, NSViewWidthSizable};
@@ -91,7 +89,7 @@ impl InnerWebView {
     window: Rc<Window>,
     attributes: WebViewAttributes,
     _pl_attrs: super::PlatformSpecificWebViewAttributes,
-    mut web_context: Option<&mut WebContext>,
+    _web_context: Option<&mut WebContext>,
   ) -> Result<Self> {
     // Function for ipc handler
     extern "C" fn did_receive(this: &Object, _: Sel, _: id, msg: id) {
@@ -267,11 +265,7 @@ impl InnerWebView {
         };
         let handler: id = msg_send![cls, new];
         let function = Box::into_raw(Box::new(function));
-        if let Some(context) = &mut web_context {
-          context.os.registered_protocols(function);
-        } else {
-          protocol_ptrs.push(function);
-        }
+        protocol_ptrs.push(function);
 
         (*handler).set_ivar("function", function as *mut _ as *mut c_void);
         let () = msg_send![config, setURLSchemeHandler:handler forURLScheme:NSString::new(&name)];
diff --git a/src/webview/wkwebview/web_context.rs b/src/webview/wkwebview/web_context.rs
deleted file mode 100644
index 7c2c5a2a7..000000000
--- a/src/webview/wkwebview/web_context.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use crate::Result;
-
-use crate::webview::web_context::WebContextData;
-use http::{Request, Response};
-use std::borrow::Cow;
-
-#[derive(Debug)]
-pub struct WebContextImpl {
-  protocols: Vec<*mut Box<dyn Fn(&Request<Vec<u8>>) -> Result<Response<Cow<'static, [u8]>>>>>,
-}
-
-impl WebContextImpl {
-  pub fn new(_data: &WebContextData) -> Self {
-    Self {
-      protocols: Vec::new(),
-    }
-  }
-
-  pub fn set_allows_automation(&mut self, _flag: bool) {}
-
-  pub fn registered_protocols(
-    &mut self,
-    handler: *mut Box<dyn Fn(&Request<Vec<u8>>) -> Result<Response<Cow<'static, [u8]>>>>,
-  ) {
-    self.protocols.push(handler);
-  }
-}
-
-impl Drop for WebContextImpl {
-  fn drop(&mut self) {
-    // We need to drop handler closures here
-    unsafe {
-      for ptr in self.protocols.iter() {
-        if !ptr.is_null() {
-          let _ = Box::from_raw(*ptr);
-        }
-      }
-    }
-  }
-}


Test patch: