Skip to content

Commit 713d992

Browse files
authored
Merge branch 'main' into patch-2
2 parents 5365e93 + 49b1fb4 commit 713d992

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

Lib/test/test_import/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,20 @@ class Spec2:
12531253
origin = "a\x00b"
12541254
_imp.create_dynamic(Spec2())
12551255

1256+
def test_create_builtin(self):
1257+
class Spec:
1258+
name = None
1259+
spec = Spec()
1260+
1261+
with self.assertRaisesRegex(TypeError, 'name must be string, not NoneType'):
1262+
_imp.create_builtin(spec)
1263+
1264+
spec.name = ""
1265+
1266+
# gh-142029
1267+
with self.assertRaisesRegex(ValueError, 'name must not be empty'):
1268+
_imp.create_builtin(spec)
1269+
12561270
def test_filter_syntax_warnings_by_module(self):
12571271
module_re = r'test\.test_import\.data\.syntax_warnings\z'
12581272
unload('test.test_import.data.syntax_warnings')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Raise :exc:`ValueError` instead of crashing when empty string is used as a name
2+
in ``_imp.create_builtin()``.

Python/import.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4420,6 +4420,12 @@ _imp_create_builtin(PyObject *module, PyObject *spec)
44204420
return NULL;
44214421
}
44224422

4423+
if (PyUnicode_GetLength(name) == 0) {
4424+
PyErr_Format(PyExc_ValueError, "name must not be empty");
4425+
Py_DECREF(name);
4426+
return NULL;
4427+
}
4428+
44234429
PyObject *mod = create_builtin(tstate, name, spec, NULL);
44244430
Py_DECREF(name);
44254431
return mod;

Python/pystate.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,16 +1765,23 @@ PyThreadState_Clear(PyThreadState *tstate)
17651765
struct _Py_freelists *freelists = _Py_freelists_GET();
17661766
_PyObject_ClearFreeLists(freelists, 1);
17671767

1768+
// Flush the thread's local GC allocation count to the global count
1769+
// before the thread state is cleared, otherwise the count is lost.
1770+
_PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)tstate;
1771+
_Py_atomic_add_int(&tstate->interp->gc.young.count,
1772+
(int)tstate_impl->gc.alloc_count);
1773+
tstate_impl->gc.alloc_count = 0;
1774+
17681775
// Merge our thread-local refcounts into the type's own refcount and
17691776
// free our local refcount array.
1770-
_PyObject_FinalizePerThreadRefcounts((_PyThreadStateImpl *)tstate);
1777+
_PyObject_FinalizePerThreadRefcounts(tstate_impl);
17711778

17721779
// Remove ourself from the biased reference counting table of threads.
17731780
_Py_brc_remove_thread(tstate);
17741781

17751782
// Release our thread-local copies of the bytecode for reuse by another
17761783
// thread
1777-
_Py_ClearTLBCIndex((_PyThreadStateImpl *)tstate);
1784+
_Py_ClearTLBCIndex(tstate_impl);
17781785
#endif
17791786

17801787
// Merge our queue of pointers to be freed into the interpreter queue.

0 commit comments

Comments
 (0)