From f9a7458e8c5f62b6c5393c9c5616d289adf79298 Mon Sep 17 00:00:00 2001 From: David Glick Date: Sun, 25 Aug 2024 22:28:55 -0700 Subject: [PATCH 1/2] Fix refcounting bug in module initialization PyModule_AddObject steals a reference, so we have to Py_INCREF the values that we are passing to it but also owned by the _zic_module_state. --- CHANGES.rst | 3 ++- src/zope/interface/_zope_interface_coptimizations.c | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index fbf108c4..a39b7d30 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ 7.0.2 (unreleased) ================== -- TBD +- Fix reference-counting bug in C module initialization (broken in 7.0). + (`#316 `_) 7.0.1 (2024-08-06) diff --git a/src/zope/interface/_zope_interface_coptimizations.c b/src/zope/interface/_zope_interface_coptimizations.c index c66f4cb3..bbfc2181 100644 --- a/src/zope/interface/_zope_interface_coptimizations.c +++ b/src/zope/interface/_zope_interface_coptimizations.c @@ -2517,6 +2517,7 @@ _zic_module_exec(PyObject* module) _zic_module_state* rec = _zic_state_init(module); rec->adapter_hooks = PyList_New(0); + Py_INCREF(rec->adapter_hooks); if (rec->adapter_hooks == NULL) return -1; @@ -2569,26 +2570,32 @@ _zic_module_exec(PyObject* module) */ sb_class = PyType_FromModuleAndSpec(module, &SB_type_spec, NULL); if (sb_class == NULL) { return -1; } + Py_INCREF(sb_class); rec->specification_base_class = TYPE(sb_class); osd_class = PyType_FromModuleAndSpec(module, &OSD_type_spec, NULL); if (osd_class == NULL) { return -1; } + Py_INCREF(osd_class); rec->object_specification_descriptor_class = TYPE(osd_class); cpb_class = PyType_FromModuleAndSpec(module, &CPB_type_spec, sb_class); if (cpb_class == NULL) { return -1; } + Py_INCREF(cpb_class); rec->class_provides_base_class = TYPE(cpb_class); ib_class = PyType_FromModuleAndSpec(module, &IB_type_spec, sb_class); if (ib_class == NULL) { return -1; } + Py_INCREF(ib_class); rec->interface_base_class = TYPE(ib_class); lb_class = PyType_FromModuleAndSpec(module, &LB_type_spec, NULL); if (lb_class == NULL) { return -1; } + Py_INCREF(lb_class); rec->lookup_base_class = TYPE(lb_class); vb_class = PyType_FromModuleAndSpec(module, &VB_type_spec, lb_class); if (vb_class == NULL) { return -1; } + Py_INCREF(vb_class); rec->verifying_base_class = TYPE(vb_class); #endif From c8ada7e211c01153ff24549b4a2cc28461c57b86 Mon Sep 17 00:00:00 2001 From: David Glick Date: Mon, 26 Aug 2024 08:09:25 -0700 Subject: [PATCH 2/2] call Py_INCREF after null check --- src/zope/interface/_zope_interface_coptimizations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zope/interface/_zope_interface_coptimizations.c b/src/zope/interface/_zope_interface_coptimizations.c index bbfc2181..ed7c5a5f 100644 --- a/src/zope/interface/_zope_interface_coptimizations.c +++ b/src/zope/interface/_zope_interface_coptimizations.c @@ -2517,9 +2517,9 @@ _zic_module_exec(PyObject* module) _zic_module_state* rec = _zic_state_init(module); rec->adapter_hooks = PyList_New(0); - Py_INCREF(rec->adapter_hooks); if (rec->adapter_hooks == NULL) return -1; + Py_INCREF(rec->adapter_hooks); #if USE_STATIC_TYPES