Hello community,

here is the log from the commit of package cjs for openSUSE:Factory checked in 
at 2017-08-22 11:10:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cjs (Old)
 and      /work/SRC/openSUSE:Factory/.cjs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cjs"

Tue Aug 22 11:10:46 2017 rev:8 rq:518008 version:3.4.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/cjs/cjs.changes  2017-08-10 14:11:33.173102107 
+0200
+++ /work/SRC/openSUSE:Factory/.cjs.new/cjs.changes     2017-08-22 
11:10:49.330291437 +0200
@@ -1,0 +2,12 @@
+Sun Aug 20 16:09:40 UTC 2017 - [email protected]
+
+- Update to version 3.4.4:
+  * object.cpp: Follow-up to 503fa20 - handler ID's must be managed
+    from start to finish - they should be initialised to 0, and
+    re-set to 0 whenever they're finished being used.
+  * arg: Don't crash when asked to convert a null strv to an array.
+  * object: Don't invalidate closure if already invalid.
+  * closure: Remove a pointer to runtime.
+  * closure: Prevent use-after-free in closures.
+
+-------------------------------------------------------------------

Old:
----
  cjs-3.4.3.tar.gz

New:
----
  cjs-3.4.4.tar.gz

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

Other differences:
------------------
++++++ cjs.spec ++++++
--- /var/tmp/diff_new_pack.4V3DGx/_old  2017-08-22 11:10:50.234164166 +0200
+++ /var/tmp/diff_new_pack.4V3DGx/_new  2017-08-22 11:10:50.234164166 +0200
@@ -20,7 +20,7 @@
 %define sover   0
 %define typelib typelib-1_0-CjsPrivate-1_0
 Name:           cjs
-Version:        3.4.3
+Version:        3.4.4
 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.3.tar.gz -> cjs-3.4.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.3/configure.ac new/cjs-3.4.4/configure.ac
--- old/cjs-3.4.3/configure.ac  2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/configure.ac  2017-08-09 12:43:55.000000000 +0200
@@ -3,7 +3,7 @@
 
 m4_define(pkg_major_version, 3)
 m4_define(pkg_minor_version, 4)
-m4_define(pkg_micro_version, 3)
+m4_define(pkg_micro_version, 4)
 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.3/debian/changelog 
new/cjs-3.4.4/debian/changelog
--- old/cjs-3.4.3/debian/changelog      2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/debian/changelog      2017-08-09 12:43:55.000000000 +0200
@@ -1,3 +1,17 @@
+cjs (3.4.4) sonya; urgency=medium
+
+  [ leigh123linux ]
+  * object: Keep proper track of pending closure invalidations
+  * revert b66d7c2965f20c2cf51628840682c404a01bf408
+
+  [ Michael Webster ]
+  * Add a debug package.
+
+  [ Jason Hicks ]
+  * object: Zero out new ConnectData
+
+ -- Clement Lefebvre <[email protected]>  Wed, 09 Aug 2017 12:43:19 +0200
+
 cjs (3.4.3) sonya; urgency=medium
 
   [ Michael Webster ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.3/debian/control new/cjs-3.4.4/debian/control
--- old/cjs-3.4.3/debian/control        2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/debian/control        2017-08-09 12:43:55.000000000 +0200
@@ -67,3 +67,17 @@
  .
  This package contains the development files applications need to
  build against.
+
+Package: libcjs-dbg
+Section: debug
+Architecture: any
+Priority: extra
+Depends: libcjs0f (= ${binary:Version}),
+         ${misc:Depends}
+Description: Mozilla-based javascript bindings for the Cinnamon platform
+ Makes it possible for applications to use all of Cinnamon's platform
+ libraries using the JavaScript language. It's mainly based on the
+ Mozilla JavaScript engine and the GObject introspection framework.
+ .
+ This development package contains unstripped binaries compiled with
+ debugging symbols needed by gdb.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.3/debian/control.in 
new/cjs-3.4.4/debian/control.in
--- old/cjs-3.4.3/debian/control.in     2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/debian/control.in     2017-08-09 12:43:55.000000000 +0200
@@ -63,3 +63,17 @@
  .
  This package contains the development files applications need to
  build against.
+
+Package: libcjs-dbg
+Section: debug
+Architecture: any
+Priority: extra
+Depends: libcjs0f (= ${binary:Version}),
+         ${misc:Depends}
+Description: Mozilla-based javascript bindings for the Cinnamon platform
+ Makes it possible for applications to use all of Cinnamon's platform
+ libraries using the JavaScript language. It's mainly based on the
+ Mozilla JavaScript engine and the GObject introspection framework.
+ .
+ This development package contains unstripped binaries compiled with
+ debugging symbols needed by gdb.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.3/debian/rules new/cjs-3.4.4/debian/rules
--- old/cjs-3.4.3/debian/rules  2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/debian/rules  2017-08-09 12:43:55.000000000 +0200
@@ -27,6 +27,9 @@
 override_dh_auto_test:
        dh_auto_test || true
 
+override_dh_strip:
+       dh_strip --dbg-package=libcjs-dbg
+
 override_dh_makeshlibs:
        dh_makeshlibs -Xusr/lib/cjs-1.0/ -V'libcjs0f (>= 
$(DEB_UPSTREAM_VERSION)), libcjs0-$(LIBMOZJS)' -- -c4
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cjs-3.4.3/gi/object.cpp new/cjs-3.4.4/gi/object.cpp
--- old/cjs-3.4.3/gi/object.cpp 2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/gi/object.cpp 2017-08-09 12:43:55.000000000 +0200
@@ -24,6 +24,7 @@
 #include <config.h>
 
 #include <deque>
+#include <map>
 #include <memory>
 #include <set>
 #include <stack>
@@ -65,6 +66,7 @@
 
     /* a list of all signal connections, used when tracing */
     std::set<ConnectData *> signals;
+    std::map<ConnectData *, unsigned> pending_invalidations;
 
     /* the GObjectClass wrapped by this JS Object (only used for
        prototypes) */
@@ -79,7 +81,6 @@
 struct _ConnectData {
     ObjectInstance *obj;
     GClosure *closure;
-    unsigned idle_invalidate_id;
 };
 
 static std::stack<JS::PersistentRootedObject> object_init_list;
@@ -1416,8 +1417,8 @@
 signal_connection_invalidate_idle(void *user_data)
 {
     auto cd = static_cast<ConnectData *>(user_data);
+    cd->obj->pending_invalidations.erase(cd);
     cd->obj->signals.erase(cd);
-    cd->idle_invalidate_id = 0;
     g_slice_free(ConnectData, cd);
     return G_SOURCE_REMOVE;
 }
@@ -1427,7 +1428,41 @@
                               GClosure *closure)
 {
     auto cd = static_cast<ConnectData *>(data);
-    cd->idle_invalidate_id = g_idle_add(signal_connection_invalidate_idle, cd);
+    std::map<ConnectData *, unsigned>& pending = 
cd->obj->pending_invalidations;
+    g_assert(pending.count(cd) == 0);
+    pending[cd] = g_idle_add(signal_connection_invalidate_idle, cd);
+}
+
+/* This is basically the same as invalidate_all_signals(), but does not defer
+ * the invalidation to an idle handler. */
+static void
+invalidate_all_signals_now(ObjectInstance *priv)
+{
+    for (auto& iter : priv->pending_invalidations) {
+        ConnectData *cd = iter.first;
+        g_source_remove(iter.second);
+        g_slice_free(ConnectData, cd);
+        /* Erase element if not already erased */
+        priv->signals.erase(cd);
+    }
+    priv->pending_invalidations.clear();
+
+    /* 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()) {
+        ConnectData *cd = *priv->signals.begin();
+
+        /* We 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);
+        /* Erase element if not already erased */
+        priv->signals.erase(cd);
+    }
 }
 
 static void
@@ -1449,39 +1484,22 @@
                                     priv->info ? 
g_base_info_get_namespace((GIBaseInfo*) priv->info) : "_gjs_private",
                                     priv->info ? 
g_base_info_get_name((GIBaseInfo*) priv->info) : g_type_name(priv->gtype)));
 
+    /* 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 applies only to instances, not prototypes, but it's possible that
+     * an instance's GObject is already freed at this point. */
+    invalidate_all_signals_now(priv);
+
+    /* Object is instance, not prototype, AND GObject is not already freed */
     if (priv->gobj) {
         bool had_toggle_up;
         bool had_toggle_down;
 
-        /* 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);
-                cd->idle_invalidate_id = 0;
-            } else {
-                /* 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",
                     priv->info ? g_base_info_get_namespace((GIBaseInfo*) 
priv->info) : "",
@@ -1666,10 +1684,9 @@
     if (closure == NULL)
         goto out;
 
-    connect_data = g_slice_new(ConnectData);
+    connect_data = g_slice_new0(ConnectData);
     priv->signals.insert(connect_data);
     connect_data->obj = priv;
-    connect_data->idle_invalidate_id = 0;
     /* 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.3/installed-tests/js/testEverythingEncapsulated.js 
new/cjs-3.4.4/installed-tests/js/testEverythingEncapsulated.js
--- old/cjs-3.4.3/installed-tests/js/testEverythingEncapsulated.js      
2017-07-06 11:11:13.000000000 +0200
+++ new/cjs-3.4.4/installed-tests/js/testEverythingEncapsulated.js      
2017-08-09 12:43:55.000000000 +0200
@@ -1,4 +1,6 @@
+const GLib = imports.gi.GLib;
 const Regress = imports.gi.Regress;
+const System = imports.system;
 
 describe('Introspected structs', function () {
     let struct;
@@ -261,3 +263,18 @@
         expect(Regress.TestObj.new_callback.length).toEqual(1);
     });
 });
+
+describe('Garbage collection of introspected objects', function () {
+    // This tests a regression that would very rarely crash, but
+    // when run under valgrind this code would show use-after-free.
+    it('collects objects properly with signals connected', function (done) {
+        function orphanObject() {
+            let obj = new Regress.TestObj();
+            obj.connect('notify', () => {});
+        }
+
+        orphanObject();
+        System.gc();
+        GLib.idle_add(GLib.PRIORITY_LOW, () => done());
+    });
+});


Reply via email to