Imported Upstream version 3.26.1 upstream/3.26.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 30 Oct 2018 01:29:38 +0000 (10:29 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 30 Oct 2018 01:29:38 +0000 (10:29 +0900)
19 files changed:
ChangeLog
Makefile.am
Makefile.in
NEWS
PKG-INFO
configure
configure.ac
gi/gimodule.c
gi/pygi-array.c
gi/pygi-closure.c
gi/pygi-enum-marshal.c
gi/pygobject-object.c
m4/ax_code_coverage.m4
m4/ax_compiler_flags_cflags.m4
m4/glib-2.0.m4
tests/gimarshallingtestsextra.c
tests/gimarshallingtestsextra.h
tests/test_gi.py
tests/test_signal.py

index c41ba69..23d0994 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,184 @@
+commit 17b4ba8707a8c6c24cd52e59a1f107dccfa9fd55
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Thu Oct 26 17:24:02 2017 +0200
+
+    pygobject-object: Fix Python GC collecting a ref cycle too early
+
+    PyGObject traverses its closures in tp_traverse, but the lifetime
+    of the closures
+    is tied to the lifetime of the GObject and not the wrapper. This
+    confuses
+    the Python GC when it sees a ref cycle and tries to break it up
+    with tp_clear.
+    Since tp_clear will not invalidate the closure and only invalidate
+    the Python
+    wrapper the closure callback gets called with the now cleared/invalid
+    object.
+
+    Instead let the GC only check the Python objects referenced by the
+    closure when tp_clear
+    would actually free them and as a result break the cycle. This is
+    only the case when
+    the wrapped object would be freed by tp_clear which is when its
+    reference count is at 1.
+
+    Original patch by Gustavo Carneiro:
+        https://bugzilla.gnome.org/show_bug.cgi?id=546802#c5
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=731501
+
+ gi/pygobject-object.c |  6 ++++--
+ tests/test_signal.py  | 29 ++++++++++++++++++++++++++++-
+ 2 files changed, 32 insertions(+), 3 deletions(-)
+
+commit b4bf1b9d936e021b1645c069c2e0a3062cfab62b
+Author: Daniel Colascione <dancol@dancol.org>
+Date:   Tue Oct 24 14:42:43 2017 +0200
+
+    Fix potential uninitialized memory access during GC
+
+    We use _PyGIDefaultArgPlaceholder as a sentinel value to represent
+    default
+    values during function argument list construction. Right now, it's
+    a Python
+    type object. We make it using PyObject_New, so most of its fields
+    end up
+    uninitialized. The object body being uninitialized wouldn't be a
+    problem if
+    the placeholder object were unreachable, but the object *can*
+    be reached
+    during GC by traversal through frame objects.
+
+    Depending on the exact contents of the uninitialized memory, the GC
+    can go on
+    to cause other kinds of memory corruption through the process.
+
+    IMHO, the easiest fix for this problem is to just make the
+    placeholder a
+    simpler data structure, like a list.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=786872
+
+ gi/gimodule.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1136f385d6080297bd57715b749c67f5e7208ba2
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Thu Oct 26 09:35:09 2017 +0200
+
+    test: revert parts of the previous test as it's broken on 32 bit
+    builds
+
+    The int based flag type can't represent the flag value on 32 bit,
+    some more work is needed there. Remove that check again for now.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=786948
+
+ tests/test_gi.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit a37687d3d8bdc42aea63e551401e6686c926c556
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Mon Oct 23 12:41:45 2017 +0200
+
+    flags: Add testcase for bug 786948
+
+    Add a flags type which has a value with the highes bit set
+    and fits in an int. While the C type is a signed int, the type
+    is registered as flags, which GI interprets as unsigned.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=786948
+
+ tests/gimarshallingtestsextra.c | 29 +++++++++++++++++++++++++++++
+ tests/gimarshallingtestsextra.h | 11 +++++++++++
+ tests/test_gi.py                |  5 +++++
+ 3 files changed, 45 insertions(+)
+
+commit 44a852191a67bc7ef76202412a0102de46eb26f0
+Author: Philippe Renon <philippe_renon@yahoo.fr>
+Date:   Thu Aug 31 16:39:08 2017 +0200
+
+    fix potential overflow when marshalling flags from py interface
+
+    the overflow happens on windows platforms when an unsigned
+    flags value overflows the capacity of a signed long
+    on windows long is a 32-bit signed integer.
+
+    fixes https://bugzilla.gnome.org/show_bug.cgi?id=786948
+
+ gi/pygi-enum-marshal.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit fa4330df4e26bb9f77a5cf081d3cc40c342709b9
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Sun Oct 22 17:59:17 2017 +0200
+
+    to_py_array: Properly handle enum array items
+
+    It used the fallback path and copied pointers.
+    Do the same thing we do for integer items instead.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=788890
+
+ gi/pygi-array.c                 |  3 +++
+ tests/gimarshallingtestsextra.c | 21 +++++++++++++++++++++
+ tests/gimarshallingtestsextra.h |  2 ++
+ tests/test_gi.py                |  6 ++++++
+ 4 files changed, 32 insertions(+)
+
+commit 5f0f3b330cfa1eb11db4f376d141445847cb9d16
+Author: James Clarke <jrtc27@jrtc27.com>
+Date:   Fri Oct 13 18:04:45 2017 +0100
+
+    closure: Fix unaligned and out-of-bounds access
+
+    When the direction is FROM_PYTHON, a whole GIArgument was being loaded
+    from the address given by the argument, but like any other case, this
+    could point to different types, and so could run off the end of the
+    pointed-to value, and, more importantly, be performing an unaligned
+    access, causing it to crash with SIGBUS on sparc64 when running
+    test_callback_scope_call_array_inout. Instead, reuse the existing code
+    for the TO_PYTHON case to do the copying into arg_value based on the
+    type.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=788894
+
+ gi/pygi-closure.c | 40 +++++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 19 deletions(-)
+
+commit d831decad9e8fdb449518997dee1a5eaa21e0313
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Fri Oct 13 19:24:01 2017 +0200
+
+    build: Fix not installing .egg-info file
+
+    While removing the egg target in 49cc3643819dad0d065d I wrongfully
+    removed that part as well. While the file extension has "egg" in
+    it it has nothing to do with eggs..
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=777719
+
+ Makefile.am | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 5b61ac3f2a66d93110642f43bec4f2a4e656681a
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Thu Oct 12 18:58:04 2017 +0200
+
+    configure.ac: version bump to 3.26.1
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 47af078546b1e9e4396bdea877c1cf0f21708818
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Tue Sep 12 08:31:22 2017 +0200
+
+    release 3.26.0
+
+ NEWS | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
 commit 9580b2f1e447cea2d50f8ab83a715b29e4e862e6
 Author: Christoph Reiter <creiter@src.gnome.org>
 Date:   Tue Sep 12 08:25:25 2017 +0200
index 4d1fdda..c3ba1a8 100644 (file)
@@ -87,6 +87,13 @@ endif
 # python
 pyexec_LTLIBRARIES =
 
+EGG_NAME = $(PACKAGE)-$(PACKAGE_VERSION)-py$(PYTHON_VERSION)
+install-data-local:
+       $(mkinstalldirs) $(DESTDIR)$(pyexecdir)
+       cp $(top_builddir)/PKG-INFO $(DESTDIR)$(pyexecdir)/$(EGG_NAME).egg-info
+uninstall-local:
+       rm -f $(DESTDIR)$(pyexecdir)/$(EGG_NAME).egg-info
+
 release-news:
        printf "%-8s%s\n" "$(VERSION)" "`LC_TIME=C date '+%d-%b-%Y'`" > NEWS.tmp
 
index 59f490a..08ce9e1 100644 (file)
@@ -509,6 +509,7 @@ nobase_pyexec_PYTHON = \
 
 # python
 pyexec_LTLIBRARIES = 
+EGG_NAME = $(PACKAGE)-$(PACKAGE_VERSION)-py$(PYTHON_VERSION)
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
@@ -1040,7 +1041,7 @@ info: info-recursive
 
 info-am:
 
-install-data-am: install-pkgconfigDATA
+install-data-am: install-data-local install-pkgconfigDATA
 
 install-dvi: install-dvi-recursive
 
@@ -1086,8 +1087,8 @@ ps: ps-recursive
 
 ps-am:
 
-uninstall-am: uninstall-nobase_pyexecPYTHON uninstall-pkgconfigDATA \
-       uninstall-pyexecLTLIBRARIES
+uninstall-am: uninstall-local uninstall-nobase_pyexecPYTHON \
+       uninstall-pkgconfigDATA uninstall-pyexecLTLIBRARIES
 
 .MAKE: $(am__recursive_targets) all check-am install-am install-strip
 
@@ -1100,17 +1101,17 @@ uninstall-am: uninstall-nobase_pyexecPYTHON uninstall-pkgconfigDATA \
        distclean-libtool distclean-local distclean-tags \
        distcleancheck distdir distuninstallcheck dvi dvi-am html \
        html-am info info-am install install-am install-data \
-       install-data-am install-dvi install-dvi-am install-exec \
-       install-exec-am install-html install-html-am install-info \
-       install-info-am install-man install-nobase_pyexecPYTHON \
-       install-pdf install-pdf-am install-pkgconfigDATA install-ps \
-       install-ps-am install-pyexecLTLIBRARIES install-strip \
-       installcheck installcheck-am installdirs installdirs-am \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags tags-am uninstall uninstall-am \
-       uninstall-nobase_pyexecPYTHON uninstall-pkgconfigDATA \
-       uninstall-pyexecLTLIBRARIES
+       install-data-am install-data-local install-dvi install-dvi-am \
+       install-exec install-exec-am install-html install-html-am \
+       install-info install-info-am install-man \
+       install-nobase_pyexecPYTHON install-pdf install-pdf-am \
+       install-pkgconfigDATA install-ps install-ps-am \
+       install-pyexecLTLIBRARIES install-strip installcheck \
+       installcheck-am installdirs installdirs-am maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+       uninstall-am uninstall-local uninstall-nobase_pyexecPYTHON \
+       uninstall-pkgconfigDATA uninstall-pyexecLTLIBRARIES
 
 .PRECIOUS: Makefile
 
@@ -1127,6 +1128,11 @@ build_pylinks:
 all-local: build_pylinks
 
 check-local: build_pylinks
+install-data-local:
+       $(mkinstalldirs) $(DESTDIR)$(pyexecdir)
+       cp $(top_builddir)/PKG-INFO $(DESTDIR)$(pyexecdir)/$(EGG_NAME).egg-info
+uninstall-local:
+       rm -f $(DESTDIR)$(pyexecdir)/$(EGG_NAME).egg-info
 
 release-news:
        printf "%-8s%s\n" "$(VERSION)" "`LC_TIME=C date '+%d-%b-%Y'`" > NEWS.tmp
diff --git a/NEWS b/NEWS
index 6abf74f..9070fd9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,14 @@
+3.26.1  27-Oct-2017
+        - pygobject-object: Fix Python GC collecting a ref cycle too early (Christoph Reiter) (#731501)
+        - Fix potential uninitialized memory access during GC (Daniel Colascione) (#786872)
+        - test: revert parts of the previous test as it's broken on 32 bit builds (Christoph Reiter) (#786948)
+        - flags: Add testcase for bug 786948 (Christoph Reiter) (#786948)
+        - fix potential overflow when marshalling flags from py interface (Philippe Renon) (#786948)
+        - to_py_array: Properly handle enum array items (Christoph Reiter) (#788890)
+        - closure: Fix unaligned and out-of-bounds access (James Clarke) (#788894)
+        - build: Fix not installing .egg-info file (Christoph Reiter) (#777719)
+        - configure.ac: version bump to 3.26.1 (Christoph Reiter)
+
 3.26.0  12-Sep-2017
         - configure.ac: pre-release version bump to 3.26.0 (Christoph Reiter)
         - closure: silence a new compiler warning (Christoph Reiter)
index 5ee6f40..ff24db0 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: PyGObject
-Version: 3.26.0
+Version: 3.26.1
 Summary: Python bindings for GObject
 Home-page: http://www.pygtk.org/
 Author: James Henstridge
@@ -8,7 +8,7 @@ Author-email: james@daa.com.au
 Maintainer: Simon Feltman
 Maintainer-email: sfeltman@src.gnome.org
 License: GNU LGPL
-Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.26/pygobject-3.26.0.tar.gz
+Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.26/pygobject-3.26.1.tar.gz
 Description: Python bindings for GLib and GObject
 Platform: POSIX, Windows
 Classifier: Development Status :: 5 - Production/Stable
index efbf805..752e07a 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pygobject 3.26.0.
+# Generated by GNU Autoconf 2.69 for pygobject 3.26.1.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='pygobject'
 PACKAGE_TARNAME='pygobject'
-PACKAGE_VERSION='3.26.0'
-PACKAGE_STRING='pygobject 3.26.0'
+PACKAGE_VERSION='3.26.1'
+PACKAGE_STRING='pygobject 3.26.1'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject'
 PACKAGE_URL='https://wiki.gnome.org/Projects/PyGObject/'
 
@@ -1419,7 +1419,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures pygobject 3.26.0 to adapt to many kinds of systems.
+\`configure' configures pygobject 3.26.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1490,7 +1490,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pygobject 3.26.0:";;
+     short | recursive ) echo "Configuration of pygobject 3.26.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1635,7 +1635,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pygobject configure 3.26.0
+pygobject configure 3.26.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1913,7 +1913,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by pygobject $as_me 3.26.0, which was
+It was created by pygobject $as_me 3.26.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2288,9 +2288,9 @@ $as_echo "#define PYGOBJECT_MINOR_VERSION 26" >>confdefs.h
 PYGOBJECT_MINOR_VERSION=26
 
 
-$as_echo "#define PYGOBJECT_MICRO_VERSION 0" >>confdefs.h
+$as_echo "#define PYGOBJECT_MICRO_VERSION 1" >>confdefs.h
 
-PYGOBJECT_MICRO_VERSION=0
+PYGOBJECT_MICRO_VERSION=1
 
 
 ac_config_headers="$ac_config_headers config.h"
@@ -2810,7 +2810,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pygobject'
- VERSION='3.26.0'
+ VERSION='3.26.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13892,7 +13892,7 @@ else
 #include <stdlib.h>
 
 int
-main ()
+main (void)
 {
   unsigned int major, minor, micro;
 
@@ -15008,7 +15008,7 @@ done
 
 
 
-for flag in              -Wall             -Wextra             -Wundef             -Wnested-externs             -Wwrite-strings             -Wpointer-arith             -Wmissing-declarations             -Wmissing-prototypes             -Wstrict-prototypes             -Wredundant-decls             -Wno-unused-parameter             -Wno-missing-field-initializers             -Wdeclaration-after-statement             -Wformat=2             -Wold-style-definition             -Wcast-align             -Wformat-nonliteral             -Wformat-security             -Wsign-compare             -Wstrict-aliasing             -Wshadow             -Winline             -Wpacked             -Wmissing-format-attribute             -Wmissing-noreturn             -Winit-self             -Wredundant-decls             -Wmissing-include-dirs             -Wunused-but-set-variable             -Warray-bounds             -Wimplicit-function-declaration             -Wreturn-type             -Wswitch-enum             -Wswitch-default                                                                ; do
+for flag in              -Wall             -Wextra             -Wundef             -Wnested-externs             -Wwrite-strings             -Wpointer-arith             -Wmissing-declarations             -Wmissing-prototypes             -Wstrict-prototypes             -Wredundant-decls             -Wno-unused-parameter             -Wno-missing-field-initializers             -Wdeclaration-after-statement             -Wformat=2             -Wold-style-definition             -Wcast-align             -Wformat-nonliteral             -Wformat-security             -Wsign-compare             -Wstrict-aliasing             -Wshadow             -Winline             -Wpacked             -Wmissing-format-attribute             -Wmissing-noreturn             -Winit-self             -Wredundant-decls             -Wmissing-include-dirs             -Wunused-but-set-variable             -Warray-bounds             -Wimplicit-function-declaration             -Wreturn-type             -Wswitch-enum             -Wswitch-default             -Wduplicated-cond             -Wduplicated-branches             -Wlogical-op             -Wrestrict             -Wnull-dereference             -Wjump-misses-init             -Wdouble-promotion                                                                ; do
   as_CACHEVAR=`$as_echo "ax_cv_check_cflags_$ax_compiler_flags_test_$flag" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
 $as_echo_n "checking whether C compiler accepts $flag... " >&6; }
@@ -16333,6 +16333,9 @@ $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
 CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
 CODE_COVERAGE_IGNORE_PATTERN ?=
 
+GITIGNOREFILES ?=
+GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
+
 code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
 code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
 code_coverage_v_lcov_cap_0 = @echo "  LCOV   --capture"\
@@ -16362,9 +16365,6 @@ code-coverage-capture-hook:
 
 '"$CODE_COVERAGE_RULES_CLEAN"'
 
-GITIGNOREFILES ?=
-GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
-
 A''M_DISTCHECK_CONFIGURE_FLAGS ?=
 A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
 
@@ -16931,7 +16931,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by pygobject $as_me 3.26.0, which was
+This file was extended by pygobject $as_me 3.26.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16998,7 +16998,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-pygobject config.status 3.26.0
+pygobject config.status 3.26.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 1ee54c2..3ad8da1 100644 (file)
@@ -18,7 +18,7 @@ m4_define(python3_min_ver, 3.3)
 dnl the pygobject version number
 m4_define(pygobject_major_version, 3)
 m4_define(pygobject_minor_version, 26)
-m4_define(pygobject_micro_version, 0)
+m4_define(pygobject_micro_version, 1)
 m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version)
 
 dnl versions of packages we require ...
index e14b4f6..5f8853c 100644 (file)
@@ -730,7 +730,7 @@ PYGLIB_MODULE_START(_gi, "_gi")
     /* Place holder object used to fill in "from Python" argument lists
      * for values not supplied by the caller but support a GI default.
      */
-    _PyGIDefaultArgPlaceholder = PyObject_New(PyObject, &PyType_Type);
+    _PyGIDefaultArgPlaceholder = PyList_New(0);
 
     Py_INCREF (PyGIWarning);
     PyModule_AddObject (module, "PyGIWarning", PyGIWarning);
index 8dfab12..e55f9f6 100644 (file)
@@ -618,6 +618,9 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
                                 item_arg.v_pointer = array_->data + i * item_size;
                             }
                             break;
+                        case GI_INFO_TYPE_ENUM:
+                            memcpy (&item_arg, array_->data + i * item_size, item_size);
+                            break;
                         default:
                             item_arg.v_pointer = g_array_index (array_, gpointer, i);
                             break;
index 03bd050..b51c04c 100644 (file)
@@ -208,6 +208,7 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
 
     for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
         PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
+        gpointer arg_pointer;
 
         if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
             state[i].arg_value.v_pointer = * (gpointer *) args[i];
@@ -216,46 +217,47 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
                 continue;
 
             state[i].arg_pointer.v_pointer = state[i].arg_value.v_pointer;
-            state[i].arg_value = *(GIArgument *) state[i].arg_value.v_pointer;
-            continue;
+            arg_pointer = state[i].arg_value.v_pointer;
+        } else {
+            arg_pointer = args[i];
         }
 
         switch (arg_cache->type_tag) {
             case GI_TYPE_TAG_BOOLEAN:
-                state[i].arg_value.v_boolean = * (gboolean *) args[i];
+                state[i].arg_value.v_boolean = * (gboolean *) arg_pointer;
                 break;
             case GI_TYPE_TAG_INT8:
-                state[i].arg_value.v_int8 = * (gint8 *) args[i];
+                state[i].arg_value.v_int8 = * (gint8 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_UINT8:
-                state[i].arg_value.v_uint8 = * (guint8 *) args[i];
+                state[i].arg_value.v_uint8 = * (guint8 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_INT16:
-                state[i].arg_value.v_int16 = * (gint16 *) args[i];
+                state[i].arg_value.v_int16 = * (gint16 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_UINT16:
-                state[i].arg_value.v_uint16 = * (guint16 *) args[i];
+                state[i].arg_value.v_uint16 = * (guint16 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_INT32:
-                state[i].arg_value.v_int32 = * (gint32 *) args[i];
+                state[i].arg_value.v_int32 = * (gint32 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_UINT32:
-                state[i].arg_value.v_uint32 = * (guint32 *) args[i];
+                state[i].arg_value.v_uint32 = * (guint32 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_INT64:
-                state[i].arg_value.v_int64 = * (glong *) args[i];
+                state[i].arg_value.v_int64 = * (glong *) arg_pointer;
                 break;
             case GI_TYPE_TAG_UINT64:
-                state[i].arg_value.v_uint64 = * (glong *) args[i];
+                state[i].arg_value.v_uint64 = * (glong *) arg_pointer;
                 break;
             case GI_TYPE_TAG_FLOAT:
-                state[i].arg_value.v_float = * (gfloat *) args[i];
+                state[i].arg_value.v_float = * (gfloat *) arg_pointer;
                 break;
             case GI_TYPE_TAG_DOUBLE:
-                state[i].arg_value.v_double = * (gdouble *) args[i];
+                state[i].arg_value.v_double = * (gdouble *) arg_pointer;
                 break;
             case GI_TYPE_TAG_UTF8:
-                state[i].arg_value.v_string = * (gchar **) args[i];
+                state[i].arg_value.v_string = * (gchar **) arg_pointer;
                 break;
             case GI_TYPE_TAG_INTERFACE:
             {
@@ -266,16 +268,16 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
                 interface_type = g_base_info_get_type (interface);
 
                 if (interface_type == GI_INFO_TYPE_ENUM) {
-                    state[i].arg_value.v_int = * (gint *) args[i];
+                    state[i].arg_value.v_int = * (gint *) arg_pointer;
                 } else if (interface_type == GI_INFO_TYPE_FLAGS) {
-                    state[i].arg_value.v_uint = * (guint *) args[i];
+                    state[i].arg_value.v_uint = * (guint *) arg_pointer;
                 } else {
-                    state[i].arg_value.v_pointer = * (gpointer *) args[i];
+                    state[i].arg_value.v_pointer = * (gpointer *) arg_pointer;
                 }
                 break;
             }
             case GI_TYPE_TAG_UNICHAR:
-                state[i].arg_value.v_uint32 = * (guint32 *) args[i];
+                state[i].arg_value.v_uint32 = * (guint32 *) arg_pointer;
                 break;
             case GI_TYPE_TAG_ERROR:
             case GI_TYPE_TAG_GHASH:
@@ -283,7 +285,7 @@ _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
             case GI_TYPE_TAG_GSLIST:
             case GI_TYPE_TAG_ARRAY:
             case GI_TYPE_TAG_VOID:
-                state[i].arg_value.v_pointer = * (gpointer *) args[i];
+                state[i].arg_value.v_pointer = * (gpointer *) arg_pointer;
                 break;
             default:
                 g_warning ("Unhandled type tag %s",
index 11c2049..44eb009 100644 (file)
@@ -182,7 +182,7 @@ _pygi_marshal_from_py_interface_flags (PyGIInvokeState   *state,
                                        gpointer          *cleanup_data)
 {
     PyObject *py_long;
-    long c_long;
+    unsigned long c_ulong;
     gint is_instance;
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
     GIBaseInfo *interface;
@@ -195,17 +195,17 @@ _pygi_marshal_from_py_interface_flags (PyGIInvokeState   *state,
         goto err;
     }
 
-    c_long = PYGLIB_PyLong_AsLong (py_long);
+    c_ulong = PYGLIB_PyLong_AsUnsignedLong (py_long);
     Py_DECREF (py_long);
 
     /* only 0 or argument of type Flag is allowed */
-    if (!is_instance && c_long != 0)
+    if (!is_instance && c_ulong != 0)
         goto err;
 
     /* Write c_long into arg */
     interface = g_type_info_get_interface (arg_cache->type_info);
     g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
-    if (!gi_argument_from_c_long(arg, c_long,
+    if (!gi_argument_from_c_long(arg, c_ulong,
                                  g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
         g_base_info_unref (interface);
         return FALSE;
index ca82ffb..729bb4d 100644 (file)
@@ -1168,8 +1168,10 @@ pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
     if (self->inst_dict) ret = visit(self->inst_dict, arg);
     if (ret != 0) return ret;
 
-    if (data) {
-
+    /* Only let the GC track the closures when tp_clear() would free them.
+     * https://bugzilla.gnome.org/show_bug.cgi?id=731501
+     */
+    if (data && self->obj->ref_count == 1) {
         for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
             PyGClosure *closure = tmp->data;
 
index 03f2c95..6484f03 100644 (file)
@@ -75,7 +75,7 @@
 #   You should have received a copy of the GNU Lesser General Public License
 #   along with this program. If not, see <https://www.gnu.org/licenses/>.
 
-#serial 24
+#serial 25
 
 AC_DEFUN([AX_CODE_COVERAGE],[
        dnl Check for --enable-code-coverage
@@ -221,6 +221,9 @@ $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
 CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
 CODE_COVERAGE_IGNORE_PATTERN ?=
 
+GITIGNOREFILES ?=
+GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
+
 code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
 code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
 code_coverage_v_lcov_cap_0 = @echo "  LCOV   --capture"\
@@ -250,9 +253,6 @@ code-coverage-capture-hook:
 
 '"$CODE_COVERAGE_RULES_CLEAN"'
 
-GITIGNOREFILES ?=
-GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
-
 A''M_DISTCHECK_CONFIGURE_FLAGS ?=
 A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
 
index aeb16e3..9767e6a 100644 (file)
 # LICENSE
 #
 #   Copyright (c) 2014, 2015 Philip Withnall <philip@tecnocode.co.uk>
+#   Copyright (c) 2017 Reini Urban <rurban@cpan.org>
 #
 #   Copying and distribution of this file, with or without modification, are
 #   permitted in any medium without royalty provided the copyright notice
 #   and this notice are preserved.  This file is offered as-is, without any
 #   warranty.
 
-#serial 14
+#serial 15
 
 AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[
     AC_REQUIRE([AC_PROG_SED])
@@ -100,6 +101,13 @@ AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[
             -Wreturn-type dnl
             -Wswitch-enum dnl
             -Wswitch-default dnl
+            -Wduplicated-cond dnl
+            -Wduplicated-branches dnl
+            -Wlogical-op dnl
+            -Wrestrict dnl
+            -Wnull-dereference dnl
+            -Wjump-misses-init dnl
+            -Wdouble-promotion dnl
             $4 dnl
             $5 dnl
             $6 dnl
index d8f03d4..4b19019 100644 (file)
@@ -1,6 +1,9 @@
 # Configure paths for GLIB
 # Owen Taylor     1997-2001
 
+# Increment this whenever this file is changed.
+#serial 1
+
 dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
 dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject,
 dnl gthread, or gio is specified in MODULES, pass to pkg-config
@@ -90,7 +93,7 @@ dnl
 #include <stdlib.h>
 
 int 
-main ()
+main (void)
 {
   unsigned int major, minor, micro;
 
index eee3a14..ae6a033 100644 (file)
@@ -104,3 +104,53 @@ gi_marshalling_tests_filename_exists (gchar *path)
 {
   return g_file_test (path, G_FILE_TEST_EXISTS);
 }
+
+
+/**
+ * gi_marshalling_tests_enum_array_return_type:
+ * @n_members: (out): The number of members
+ *
+ * Returns: (array length=n_members) (transfer full): An array of enum values
+ */
+GIMarshallingTestsExtraEnum *
+gi_marshalling_tests_enum_array_return_type (gsize *n_members)
+{
+  GIMarshallingTestsExtraEnum *res = g_new0(GIMarshallingTestsExtraEnum, 3);
+
+  *n_members = 3;
+
+  res[0] = GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE1;
+  res[1] = GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE2;
+  res[2] = GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE3;
+
+  return res;
+}
+
+GType
+gi_marshalling_tests_extra_flags_get_type (void)
+{
+  static GType type = 0;
+  if (G_UNLIKELY (type == 0))
+    {
+      static const GFlagsValue values[] = {
+        {GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE1,
+         "GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE1", "value1"},
+        {GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE2,
+         "GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE2", "value2"},
+        {0, NULL, NULL}
+      };
+      type = g_flags_register_static (
+        g_intern_static_string ("GIMarshallingTestsExtraFlags"), values);
+    }
+
+  return type;
+}
+
+/**
+ * gi_marshalling_tests_extra_flags_large_in:
+ */
+void
+gi_marshalling_tests_extra_flags_large_in (GIMarshallingTestsExtraFlags value)
+{
+  g_assert_cmpint (value, ==, GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE2);
+}
index 5452688..57f52f4 100644 (file)
@@ -29,6 +29,15 @@ typedef enum
 } GIMarshallingTestsExtraEnum;
 
 
+typedef enum
+{
+  GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE1 = 0,
+  GI_MARSHALLING_TESTS_EXTRA_FLAGS_VALUE2 = (gint)(1 << 31),
+} GIMarshallingTestsExtraFlags;
+
+GType gi_marshalling_tests_extra_flags_get_type (void) G_GNUC_CONST;
+#define GI_MARSHALLING_TESTS_TYPE_EXTRA_FLAGS (gi_marshalling_tests_extra_flags_get_type ())
+
 void gi_marshalling_tests_compare_two_gerrors_in_gvalue (GValue *v, GValue *v1);
 void gi_marshalling_tests_ghashtable_enum_none_in (GHashTable *hash_table);
 GHashTable * gi_marshalling_tests_ghashtable_enum_none_return (void);
@@ -37,4 +46,8 @@ gchar * gi_marshalling_tests_filename_copy (gchar *path_in);
 gboolean gi_marshalling_tests_filename_exists (gchar *path);
 gchar * gi_marshalling_tests_filename_to_glib_repr (gchar *path_in, gsize *len);
 
+GIMarshallingTestsExtraEnum * gi_marshalling_tests_enum_array_return_type (gsize *n_members);
+
+void gi_marshalling_tests_extra_flags_large_in (GIMarshallingTestsExtraFlags value);
+
 #endif /* EXTRA_TESTS */
index 8a9bb2c..d1b0cfd 100644 (file)
@@ -1071,6 +1071,12 @@ class TestArray(unittest.TestCase):
         self.assertEqual((True, ['hello']),
                          GIMarshallingTests.init_function(['hello', 'world']))
 
+    def test_enum_array_return_type(self):
+        self.assertEqual(GIMarshallingTests.enum_array_return_type(),
+                         [GIMarshallingTests.ExtraEnum.VALUE1,
+                          GIMarshallingTests.ExtraEnum.VALUE2,
+                          GIMarshallingTests.ExtraEnum.VALUE3])
+
 
 class TestGStrv(unittest.TestCase):
 
@@ -1858,6 +1864,10 @@ class TestGFlags(unittest.TestCase):
                          "<flags GI_MARSHALLING_TESTS_FLAGS_VALUE2 of type "
                          "GIMarshallingTests.Flags>")
 
+    def test_flags_large_in(self):
+        GIMarshallingTests.extra_flags_large_in(
+            GIMarshallingTests.ExtraFlags.VALUE2)
+
 
 class TestNoTypeFlags(unittest.TestCase):
 
index 4e81c1e..b2f121a 100644 (file)
@@ -5,7 +5,7 @@ import unittest
 import sys
 import weakref
 
-from gi.repository import GObject, GLib, Regress
+from gi.repository import GObject, GLib, Regress, Gio
 from gi import _signalhelper as signalhelper
 import testhelper
 from compathelper import _long
@@ -1466,5 +1466,32 @@ class TestRefCountsIntrospected(unittest.TestCase, _RefCountTestBase):
     Object = Regress.TestObj
 
 
+class TestClosureRefCycle(unittest.TestCase):
+
+    def test_closure_ref_cycle_unreachable(self):
+        # https://bugzilla.gnome.org/show_bug.cgi?id=731501
+
+        called = []
+
+        def on_add(store, *args):
+            called.append(store)
+
+        store = Gio.ListStore()
+        store.connect_object('items-changed', on_add, store)
+
+        # Remove all Python references to the object and keep it alive
+        # on the C level.
+        x = Gio.FileInfo()
+        x.set_attribute_object('store', store)
+        del store
+        gc.collect()
+
+        # get it back and trigger the signal
+        x.get_attribute_object('store').append(Gio.FileInfo())
+
+        self.assertEqual(len(called), 1)
+        self.assertTrue(called[0].__grefcount__ > 0)
+
+
 if __name__ == '__main__':
     unittest.main()