Hello community,

here is the log from the commit of package cjs for openSUSE:Factory checked in 
at 2017-06-29 15:18:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cjs (Old)
 and      /work/SRC/openSUSE:Factory/.cjs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cjs"

Thu Jun 29 15:18:01 2017 rev:6 rq:506912 version:3.4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/cjs/cjs.changes  2017-05-27 13:13:10.319555640 
+0200
+++ /work/SRC/openSUSE:Factory/.cjs.new/cjs.changes     2017-06-29 
15:18:19.265863430 +0200
@@ -1,0 +2,10 @@
+Wed Jun 28 19:20:44 UTC 2017 - [email protected]
+
+- Update to version 3.4.2:
+  * tweener: Add undefined property check.
+  * tweener.js: Silence some additional warnings due to
+    missing/unused properties.
+  * object: Prevent use-after-free in signal connections.
+  * util-root: Require GjsMaybeOwned callback to reset.
+
+-------------------------------------------------------------------

Old:
----
  cjs-3.4.1.tar.gz

New:
----
  cjs-3.4.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cjs.spec ++++++
--- /var/tmp/diff_new_pack.dF1nwc/_old  2017-06-29 15:18:21.137598845 +0200
+++ /var/tmp/diff_new_pack.dF1nwc/_new  2017-06-29 15:18:21.141598279 +0200
@@ -20,7 +20,7 @@
 %define sover   0
 %define typelib typelib-1_0-CjsPrivate-1_0
 Name:           cjs
-Version:        3.4.1
+Version:        3.4.2
 Release:        0
 Summary:        JavaScript module used by Cinnamon
 License:        MIT and (MPL-1.1 or GPL-2.0+ or LGPL-2.1+)

++++++ cjs-3.4.1.tar.gz -> cjs-3.4.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.1/cjs/jsapi-util-root.h 
new/cjs-3.4.2/cjs/jsapi-util-root.h
--- old/cjs-3.4.1/cjs/jsapi-util-root.h 2017-05-23 16:29:10.000000000 +0200
+++ new/cjs-3.4.2/cjs/jsapi-util-root.h 2017-06-26 12:19:31.000000000 +0200
@@ -170,11 +170,12 @@
          * to remove it. */
         m_has_weakref = false;
 
-        /* The object is still live across this callback. */
+        /* The object is still live entering this callback. The callback
+         * must reset() this wrapper. */
         if (m_notify)
             m_notify(handle(), m_data);
-
-        reset();
+        else
+            reset();
     }
 
 public:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.1/configure.ac new/cjs-3.4.2/configure.ac
--- old/cjs-3.4.1/configure.ac  2017-05-23 16:29:10.000000000 +0200
+++ new/cjs-3.4.2/configure.ac  2017-06-26 12:19:31.000000000 +0200
@@ -3,7 +3,7 @@
 
 m4_define(pkg_major_version, 3)
 m4_define(pkg_minor_version, 4)
-m4_define(pkg_micro_version, 1)
+m4_define(pkg_micro_version, 2)
 m4_define(pkg_version, pkg_major_version.pkg_minor_version.pkg_micro_version)
 m4_define(pkg_int_version, (pkg_major_version * 100 + pkg_minor_version) * 100 
+ pkg_micro_version)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.1/debian/changelog 
new/cjs-3.4.2/debian/changelog
--- old/cjs-3.4.1/debian/changelog      2017-05-23 16:29:10.000000000 +0200
+++ new/cjs-3.4.2/debian/changelog      2017-06-26 12:19:31.000000000 +0200
@@ -1,3 +1,17 @@
+cjs (3.4.2) sonya; urgency=medium
+
+  [ leigh123linux ]
+  * tweener: Add undefined property check (#45)
+
+  [ Michael Webster ]
+  * tweener.js: silence some additional warnings due to missing/unused 
properties.
+
+  [ leigh123linux ]
+  * object: Prevent use-after-free in signal connections
+  * util-root: Require GjsMaybeOwned callback to reset
+
+ -- Clement Lefebvre <[email protected]>  Mon, 26 Jun 2017 12:18:57 +0200
+
 cjs (3.4.1) sonya; urgency=medium
 
   [ Clement Lefebvre ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.1/gi/object.cpp new/cjs-3.4.2/gi/object.cpp
--- old/cjs-3.4.1/gi/object.cpp 2017-05-23 16:29:10.000000000 +0200
+++ new/cjs-3.4.2/gi/object.cpp 2017-06-26 12:19:31.000000000 +0200
@@ -55,6 +55,8 @@
 #include <util/hash-x32.h>
 #include <girepository.h>
 
+typedef struct _ConnectData ConnectData;
+
 struct ObjectInstance {
     GIObjectInfo *info;
     GObject *gobj; /* NULL if we are the prototype and not an instance */
@@ -62,7 +64,7 @@
     GType gtype;
 
     /* a list of all signal connections, used when tracing */
-    GList *signals;
+    std::set<ConnectData *> signals;
 
     /* the GObjectClass wrapped by this JS Object (only used for
        prototypes) */
@@ -74,11 +76,11 @@
     unsigned js_object_finalized : 1;
 };
 
-typedef struct {
+struct _ConnectData {
     ObjectInstance *obj;
-    GList *link;
     GClosure *closure;
-} ConnectData;
+    unsigned idle_invalidate_id;
+};
 
 static std::stack<JS::PersistentRootedObject> object_init_list;
 static GHashTable *class_init_properties;
@@ -93,7 +95,7 @@
 GJS_DEFINE_PRIV_FROM_JS(ObjectInstance, gjs_object_instance_class)
 
 static void            disassociate_js_gobject (GObject *gobj);
-static void            invalidate_all_signals (ObjectInstance *priv);
+
 typedef enum {
     SOME_ERROR_OCCURRED = false,
     NO_SUCH_G_PROPERTY,
@@ -1220,6 +1222,21 @@
 }
 
 static void
+invalidate_all_signals(ObjectInstance *priv)
+{
+    /* Can't loop directly through the items, since invalidating an item's
+     * closure might have the effect of removing the item from the set in the
+     * invalidate notifier */
+    while (!priv->signals.empty()) {
+        /* This will also free cd, through the closure invalidation mechanism 
*/
+        ConnectData *cd = *priv->signals.begin();
+        g_closure_invalidate(cd->closure);
+        /* Erase element if not already erased */
+        priv->signals.erase(cd);
+    }
+}
+
+static void
 disassociate_js_gobject(GObject *gobj)
 {
     ObjectInstance *priv = get_object_qdata(gobj);
@@ -1374,43 +1391,44 @@
 }
 
 static void
-invalidate_all_signals(ObjectInstance *priv)
-{
-    GList *iter, *next;
-
-    for (iter = priv->signals; iter; ) {
-        ConnectData *cd = (ConnectData*) iter->data;
-        next = iter->next;
-
-        /* This will also free cd and iter, through
-           the closure invalidation mechanism */
-        g_closure_invalidate(cd->closure);
-
-        iter = next;
-    }
-}
-
-static void
 object_instance_trace(JSTracer *tracer,
                       JSObject *obj)
 {
     ObjectInstance *priv;
-    GList *iter;
 
     priv = (ObjectInstance *) JS_GetPrivate(obj);
     if (priv == NULL)
         return;
 
-    for (iter = priv->signals; iter; iter = iter->next) {
-        ConnectData *cd = (ConnectData *) iter->data;
-
+    for (ConnectData *cd : priv->signals)
         gjs_closure_trace(cd->closure, tracer);
-    }
 
     for (auto vfunc : priv->vfuncs)
         vfunc->js_function.trace(tracer, "ObjectInstance::vfunc");
 }
 
+/* Removing the signal connection data from the list means that the object 
stops
+ * tracing the JS function objects belonging to the closures. Incremental GC
+ * does not allow that in the middle of a garbage collection. Therefore, we 
must
+ * do it in an idle handler.
+ */
+static gboolean
+signal_connection_invalidate_idle(void *user_data)
+{
+    auto cd = static_cast<ConnectData *>(user_data);
+    cd->obj->signals.erase(cd);
+    g_slice_free(ConnectData, cd);
+    return G_SOURCE_REMOVE;
+}
+
+static void
+signal_connection_invalidated(void     *data,
+                              GClosure *closure)
+{
+    auto cd = static_cast<ConnectData *>(data);
+    cd->idle_invalidate_id = g_idle_add(signal_connection_invalidate_idle, cd);
+}
+
 static void
 object_instance_finalize(JSFreeOp  *fop,
                          JSObject  *obj)
@@ -1434,7 +1452,31 @@
         bool had_toggle_up;
         bool had_toggle_down;
 
-        invalidate_all_signals (priv);
+        /* We must invalidate all signal connections now, instead of in an idle
+         * handler, because the object will not exist anymore when we get
+         * around to the idle function. We originally needed to defer these
+         * invalidations to an idle function since the object needs to continue
+         * tracing its signal connections while GC is going on. However, once
+         * the object is finalized, it will not be tracing them any longer
+         * anyway, so it's safe to do them now.
+         *
+         * This is basically the same as invalidate_all_signals(), but does not
+         * defer the invalidation to an idle handler.
+         */
+        for (ConnectData *cd : priv->signals) {
+            /* First remove any pending invalidation, we are doing it now. */
+            if (cd->idle_invalidate_id > 0)
+                g_source_remove(cd->idle_invalidate_id);
+
+            /* We also have to remove the invalidate notifier, which would
+             * otherwise schedule a new pending invalidation. */
+            g_closure_remove_invalidate_notifier(cd->closure, cd,
+                                                 
signal_connection_invalidated);
+
+            g_closure_invalidate(cd->closure);
+            g_slice_free(ConnectData, cd);
+        }
+        priv->signals.clear();
 
         if (G_UNLIKELY (priv->gobj->ref_count <= 0)) {
             g_error("Finalizing proxy for an already freed object of type: 
%s.%s\n",
@@ -1568,29 +1610,6 @@
     return proto;
 }
 
-/* Removing the signal connection data from the list means that the object 
stops
- * tracing the JS function objects belonging to the closures. Incremental GC
- * does not allow that in the middle of a garbage collection. Therefore, we 
must
- * do it in an idle handler.
- */
-static gboolean
-signal_connection_invalidate_idle(void *user_data)
-{
-    ConnectData *connect_data = (ConnectData *) user_data;
-
-    connect_data->obj->signals = g_list_delete_link(connect_data->obj->signals,
-                                                    connect_data->link);
-    g_slice_free(ConnectData, connect_data);
-    return G_SOURCE_REMOVE;
-}
-
-static void
-signal_connection_invalidated(void     *data,
-                              GClosure *closure)
-{
-    g_idle_add(signal_connection_invalidate_idle, data);
-}
-
 static bool
 real_connect_func(JSContext *context,
                   unsigned   argc,
@@ -1644,9 +1663,8 @@
         goto out;
 
     connect_data = g_slice_new(ConnectData);
-    priv->signals = g_list_prepend(priv->signals, connect_data);
+    priv->signals.insert(connect_data);
     connect_data->obj = priv;
-    connect_data->link = priv->signals;
     /* This is a weak reference, and will be cleared when the closure is 
invalidated */
     connect_data->closure = closure;
     g_closure_add_invalidate_notifier(closure, connect_data, 
signal_connection_invalidated);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.1/modules/tweener/tweener.js 
new/cjs-3.4.2/modules/tweener/tweener.js
--- old/cjs-3.4.1/modules/tweener/tweener.js    2017-05-23 16:29:10.000000000 
+0200
+++ new/cjs-3.4.2/modules/tweener/tweener.js    2017-06-26 12:19:31.000000000 
+0200
@@ -508,6 +508,7 @@
                     if (scopes[i][istr] == undefined)
                         log("The property " + istr + " doesn't seem to be a 
normal object property of " + scopes[i] + " or a registered special property");
                 }
+                properties[istr].isSpecialProperty = false;
             }
         }
     }
@@ -542,11 +543,11 @@
                 copyProperties[istr] = new 
PropertyInfo(properties[istr].valueStart,
                                                         
properties[istr].valueComplete,
                                                         
properties[istr].valueComplete,
-                                                        
properties[istr].arrayIndex,
+                                                        
properties[istr].arrayIndex || 0,
                                                         {},
                                                         
properties[istr].isSpecialProperty,
-                                                        
properties[istr].modifierFunction,
-                                                        
properties[istr].modifierParameters);
+                                                        
properties[istr].modifierFunction || null,
+                                                        
properties[istr].modifierParameters || null);
             }
         }
 
@@ -555,7 +556,7 @@
                                         _ticker.getTime() + (((delay * 1000) + 
(time * 1000)) / _timeScale),
                                         false,
                                         transition,
-                                        obj.transitionParams);
+                                        obj.transitionParams || null);
 
         tween.properties               =       isCaller ? null : 
copyProperties;
         tween.onStart                  =       obj.onStart;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.1/test/gjs-test-rooting.cpp 
new/cjs-3.4.2/test/gjs-test-rooting.cpp
--- old/cjs-3.4.1/test/gjs-test-rooting.cpp     2017-05-23 16:29:10.000000000 
+0200
+++ new/cjs-3.4.2/test/gjs-test-rooting.cpp     2017-06-26 12:19:31.000000000 
+0200
@@ -13,6 +13,8 @@
 
     bool finalized;
     bool notify_called;
+
+    GjsMaybeOwned<JSObject *> *obj;  /* only used in callback test cases */
 };
 
 static void
@@ -220,6 +222,7 @@
     g_assert_false(fx->notify_called);
     g_assert_false(fx->finalized);
     fx->notify_called = true;
+    fx->obj->reset();
 }
 
 static void
@@ -233,24 +236,24 @@
 test_maybe_owned_notify_callback_called_on_context_destroy(GjsRootingFixture 
*fx,
                                                            gconstpointer      
unused)
 {
-    auto obj = new GjsMaybeOwned<JSObject *>();
-    obj->root(PARENT(fx)->cx, test_obj_new(fx), context_destroyed, fx);
+    fx->obj = new GjsMaybeOwned<JSObject *>();
+    fx->obj->root(PARENT(fx)->cx, test_obj_new(fx), context_destroyed, fx);
 
     gjs_unit_test_destroy_context(PARENT(fx));
     g_assert_true(fx->notify_called);
-    delete obj;
+    delete fx->obj;
 }
 
 static void
 test_maybe_owned_object_destroyed_after_notify(GjsRootingFixture *fx,
                                                gconstpointer      unused)
 {
-    auto obj = new GjsMaybeOwned<JSObject *>();
-    obj->root(PARENT(fx)->cx, test_obj_new(fx), context_destroyed, fx);
+    fx->obj = new GjsMaybeOwned<JSObject *>();
+    fx->obj->root(PARENT(fx)->cx, test_obj_new(fx), context_destroyed, fx);
 
     gjs_unit_test_destroy_context(PARENT(fx));
     g_assert_true(fx->finalized);
-    delete obj;
+    delete fx->obj;
 }
 
 void


Reply via email to