From e77e8654b1fba99c468a4de0e513bf78447917ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tau=20G=C3=A4rtli?= Date: Tue, 3 Feb 2026 18:24:31 +0100 Subject: [PATCH 1/2] fix: Do not call unref on a borrowed pointer `gi_base_info_get_container` returns a borrowed pointer, so we should not call `gi_base_info_unref` on it. This caused a segfault when repeatedly accessing an array field with length annotation on a struct. Fixes #738 --- gi/pygi-info.c | 3 +-- tests/test_fields.py | 14 +++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/gi/pygi-info.c b/gi/pygi-info.c index dc34090b1..5ffb217e6 100644 --- a/gi/pygi-info.c +++ b/gi/pygi-info.c @@ -1897,7 +1897,7 @@ field_array_length (GIFieldInfo *info, void *struct_data_ptr, gi_base_info_unref (type_info); - container_info = gi_base_info_get_container ((GIBaseInfo *)info); + container_info = gi_base_info_get_container ((GIBaseInfo *)info); /* borrowed! */ if (GI_IS_UNION_INFO (container_info)) { array_len_field = gi_union_info_get_field ( @@ -1912,7 +1912,6 @@ field_array_length (GIFieldInfo *info, void *struct_data_ptr, /* Other types don't have fields. */ g_assert_not_reached (); } - gi_base_info_unref (container_info); if (array_len_field == NULL) { return FALSE; diff --git a/tests/test_fields.py b/tests/test_fields.py index 3236486ac..d83dbdceb 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1,9 +1,7 @@ import math import unittest -from gi.repository import GLib -from gi.repository import Regress -from gi.repository import GIMarshallingTests +from gi.repository import GIMarshallingTests, GLib, Regress class Number: @@ -177,3 +175,13 @@ class TestFields(unittest.TestCase): def test_ghashtable(self): obj = Regress.TestObj() self.assertTrue(obj.hash_table is None) + + def test_array_field_with_length_annotation(self): + """Regression test for + Every time an array field was accessed, the reference count of the struct info would be decreased. + This was only the case for array fields with a length annotation. + """ + ITERATIONS = 100 # mostly arbitrarily chosen, but should be high enough to drop the reference count to zero. + obj = Regress.AnnotationFields() + for _ in range(0, ITERATIONS): + obj.arr -- GitLab From 8b58098189abea50db2d25cf59a9c553d0199198 Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Tue, 3 Feb 2026 22:03:59 +0100 Subject: [PATCH 2/2] fix formatting --- gi/pygi-info.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gi/pygi-info.c b/gi/pygi-info.c index 5ffb217e6..e378a7536 100644 --- a/gi/pygi-info.c +++ b/gi/pygi-info.c @@ -1897,7 +1897,8 @@ field_array_length (GIFieldInfo *info, void *struct_data_ptr, gi_base_info_unref (type_info); - container_info = gi_base_info_get_container ((GIBaseInfo *)info); /* borrowed! */ + container_info = + gi_base_info_get_container ((GIBaseInfo *)info); /* borrowed! */ if (GI_IS_UNION_INFO (container_info)) { array_len_field = gi_union_info_get_field ( -- GitLab