[gjs: 1/2] wrapperutils: Always set prototype private data



commit ebfd886b50bb224628ce2020a8bc2caec3022103
Author: Philip Chimento <philip chimento gmail com>
Date:   Fri Aug 2 00:05:46 2019 -0700

    wrapperutils: Always set prototype private data
    
    Set the private data of a prototype object with JS_SetPrivate() as soon
    as it is created. Otherwise, a garbage collection might happen while the
    private pointer is null, which will crash.
    
    Closes: GNOME/gjs#259.

 gi/wrapperutils.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
---
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index 95666216..4b577ff7 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -931,8 +931,15 @@ class GIWrapperPrototype : public Base {
         JS::RootedObject parent_proto(cx);
         if (!priv->get_parent_proto(cx, &parent_proto) ||
             !priv->define_jsclass(cx, in_object, parent_proto, constructor,
-                                  prototype) ||
-            !gjs_wrapper_define_gtype_prop(cx, constructor, gtype))
+                                  prototype))
+            return nullptr;
+
+        // Init the private variable of @private before we do anything else. If
+        // a garbage collection or error happens subsequently, then this object
+        // might be traced and we would end up dereferencing a null pointer.
+        JS_SetPrivate(prototype, priv);
+
+        if (!gjs_wrapper_define_gtype_prop(cx, constructor, gtype))
             return nullptr;
 
         // Every class has a toString() with C++ implementation, so define that
@@ -950,7 +957,6 @@ class GIWrapperPrototype : public Base {
                 return nullptr;
         }
 
-        JS_SetPrivate(prototype, priv);
         return priv;
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]