changeset 2952:7d12fd73ef54

Mac/iOS: Implement failsafe for dw_window_s/get_data() so we don't crash. Some objects don't support setting data on them, so if called on one of those objects, silently fail in Release mode and give a warning in DEBUG.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 04 Jan 2023 10:28:20 +0000
parents 34d16576c156
children 7dcd13597a4f
files ios/dw.m mac/dw.m
diffstat 2 files changed, 59 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/ios/dw.m	Wed Jan 04 09:45:49 2023 +0000
+++ b/ios/dw.m	Wed Jan 04 10:28:20 2023 +0000
@@ -10671,25 +10671,35 @@
         NSArray *subviews = [sv subviews];
         object = [subviews firstObject];
     }
-    WindowData *blah = (WindowData *)[object userdata];
-
-    if(!blah)
-    {
-        if(!dataname)
-            return;
-
-        blah = calloc(1, sizeof(WindowData));
-        [object setUserdata:blah];
-    }
-
-    if(data)
-        _dw_new_userdata(&(blah->root), dataname, data);
+    /* Failsafe so we don't crash */
+    if(![object respondsToSelector:NSSelectorFromString(@"userdata")])
+    {
+#ifdef DEBUG
+        NSLog(@"WARNING: Object class %@ does not support dw_window_set_data()\n", [object className]);
+#endif
+    }
     else
     {
-        if(dataname)
-            _dw_remove_userdata(&(blah->root), dataname, FALSE);
+        WindowData *blah = (WindowData *)[object userdata];
+
+        if(!blah)
+        {
+            if(!dataname)
+                return;
+
+            blah = calloc(1, sizeof(WindowData));
+            [object setUserdata:blah];
+        }
+
+        if(data)
+            _dw_new_userdata(&(blah->root), dataname, data);
         else
-            _dw_remove_userdata(&(blah->root), NULL, TRUE);
+        {
+            if(dataname)
+                _dw_remove_userdata(&(blah->root), dataname, FALSE);
+            else
+                _dw_remove_userdata(&(blah->root), NULL, TRUE);
+        }
     }
     DW_FUNCTION_RETURN_NOTHING;
 }
@@ -10728,13 +10738,23 @@
         NSArray *subviews = [sv subviews];
         object = [subviews firstObject];
     }
-    WindowData *blah = (WindowData *)[object userdata];
-
-    if(blah && blah->root && dataname)
-    {
-        UserData *ud = _dw_find_userdata(&(blah->root), dataname);
-        if(ud)
-            retval = ud->data;
+    /* Failsafe so we don't crash */
+    if(![object respondsToSelector:NSSelectorFromString(@"userdata")])
+    {
+#ifdef DEBUG
+        NSLog(@"WARNING: Object class %@ does not support dw_window_get_data()\n", [object className]);
+#endif
+    }
+    else
+    {
+        WindowData *blah = (WindowData *)[object userdata];
+
+        if(blah && blah->root && dataname)
+        {
+            UserData *ud = _dw_find_userdata(&(blah->root), dataname);
+            if(ud)
+                retval = ud->data;
+        }
     }
     DW_FUNCTION_RETURN_THIS(retval);
 }
--- a/mac/dw.m	Wed Jan 04 09:45:49 2023 +0000
+++ b/mac/dw.m	Wed Jan 04 10:28:20 2023 +0000
@@ -11638,6 +11638,14 @@
         NSBox *box = window;
         object = [box contentView];
     }
+    /* Failsafe so we don't crash */
+    if(![object respondsToSelector:NSSelectorFromString(@"userdata")])
+    {
+#ifdef DEBUG
+        NSLog(@"WARNING: Object class %@ does not support dw_window_set_data()\n", [object className]);
+#endif
+        return;
+    }
     WindowData *blah = (WindowData *)[object userdata];
 
     if(!blah)
@@ -11685,6 +11693,14 @@
         NSBox *box = window;
         object = [box contentView];
     }
+    /* Failsafe so we don't crash */
+    if(![object respondsToSelector:NSSelectorFromString(@"userdata")])
+    {
+#ifdef DEBUG
+        NSLog(@"WARNING: Object class %@ does not support dw_window_get_data()\n", [object className]);
+#endif
+        return NULL;
+    }
     WindowData *blah = (WindowData *)[object userdata];
 
     if(blah && blah->root && dataname)