From 7599c2f63ff4385cc28b7df1593781ef725a2f96 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Tue, 30 Oct 2018 10:29:38 +0900 Subject: [PATCH] Imported Upstream version 3.26.1 --- ChangeLog | 181 ++++++++++++++++++++++++++++++++ Makefile.am | 7 ++ Makefile.in | 34 +++--- NEWS | 11 ++ PKG-INFO | 4 +- configure | 34 +++--- configure.ac | 2 +- gi/gimodule.c | 2 +- gi/pygi-array.c | 3 + gi/pygi-closure.c | 40 +++---- gi/pygi-enum-marshal.c | 8 +- gi/pygobject-object.c | 6 +- m4/ax_code_coverage.m4 | 8 +- m4/ax_compiler_flags_cflags.m4 | 10 +- m4/glib-2.0.m4 | 5 +- tests/gimarshallingtestsextra.c | 50 +++++++++ tests/gimarshallingtestsextra.h | 13 +++ tests/test_gi.py | 10 ++ tests/test_signal.py | 29 ++++- 19 files changed, 390 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index c41ba69..23d0994 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,184 @@ +commit 17b4ba8707a8c6c24cd52e59a1f107dccfa9fd55 +Author: Christoph Reiter +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 Date: Tue Sep 12 08:25:25 2017 +0200 diff --git a/Makefile.am b/Makefile.am index 4d1fdda..c3ba1a8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/Makefile.in b/Makefile.in index 59f490a..08ce9e1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 --- 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) diff --git a/PKG-INFO b/PKG-INFO index 5ee6f40..ff24db0 100644 --- 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 diff --git a/configure b/configure index efbf805..752e07a 100755 --- 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 . # @@ -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 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\\" diff --git a/configure.ac b/configure.ac index 1ee54c2..3ad8da1 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ... diff --git a/gi/gimodule.c b/gi/gimodule.c index e14b4f6..5f8853c 100644 --- a/gi/gimodule.c +++ b/gi/gimodule.c @@ -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); diff --git a/gi/pygi-array.c b/gi/pygi-array.c index 8dfab12..e55f9f6 100644 --- a/gi/pygi-array.c +++ b/gi/pygi-array.c @@ -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; diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c index 03bd050..b51c04c 100644 --- a/gi/pygi-closure.c +++ b/gi/pygi-closure.c @@ -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", diff --git a/gi/pygi-enum-marshal.c b/gi/pygi-enum-marshal.c index 11c2049..44eb009 100644 --- a/gi/pygi-enum-marshal.c +++ b/gi/pygi-enum-marshal.c @@ -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; diff --git a/gi/pygobject-object.c b/gi/pygobject-object.c index ca82ffb..729bb4d 100644 --- a/gi/pygobject-object.c +++ b/gi/pygobject-object.c @@ -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; diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4 index 03f2c95..6484f03 100644 --- a/m4/ax_code_coverage.m4 +++ b/m4/ax_code_coverage.m4 @@ -75,7 +75,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -#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 diff --git a/m4/ax_compiler_flags_cflags.m4 b/m4/ax_compiler_flags_cflags.m4 index aeb16e3..9767e6a 100644 --- a/m4/ax_compiler_flags_cflags.m4 +++ b/m4/ax_compiler_flags_cflags.m4 @@ -19,13 +19,14 @@ # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall +# Copyright (c) 2017 Reini Urban # # 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 diff --git a/m4/glib-2.0.m4 b/m4/glib-2.0.m4 index d8f03d4..4b19019 100644 --- a/m4/glib-2.0.m4 +++ b/m4/glib-2.0.m4 @@ -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 int -main () +main (void) { unsigned int major, minor, micro; diff --git a/tests/gimarshallingtestsextra.c b/tests/gimarshallingtestsextra.c index eee3a14..ae6a033 100644 --- a/tests/gimarshallingtestsextra.c +++ b/tests/gimarshallingtestsextra.c @@ -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); +} diff --git a/tests/gimarshallingtestsextra.h b/tests/gimarshallingtestsextra.h index 5452688..57f52f4 100644 --- a/tests/gimarshallingtestsextra.h +++ b/tests/gimarshallingtestsextra.h @@ -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 */ diff --git a/tests/test_gi.py b/tests/test_gi.py index 8a9bb2c..d1b0cfd 100644 --- a/tests/test_gi.py +++ b/tests/test_gi.py @@ -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): "") + def test_flags_large_in(self): + GIMarshallingTests.extra_flags_large_in( + GIMarshallingTests.ExtraFlags.VALUE2) + class TestNoTypeFlags(unittest.TestCase): diff --git a/tests/test_signal.py b/tests/test_signal.py index 4e81c1e..b2f121a 100644 --- a/tests/test_signal.py +++ b/tests/test_signal.py @@ -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() -- 2.34.1