Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e898626
gh-143543: Fix re-entrant use-after-free in itertools.groupby
VanshAgarwal24036 Jan 12, 2026
ba974bc
Fix whitespace per prek
VanshAgarwal24036 Jan 12, 2026
0debc2a
Add NEWS entry for itertools.groupby crash fix
VanshAgarwal24036 Jan 13, 2026
8d83176
Fix NEWS filename for gh-143543
VanshAgarwal24036 Jan 13, 2026
ca932bf
Fix NEWS entry type for gh-143543
VanshAgarwal24036 Jan 13, 2026
0e86303
Remove incorrect NEWS files for gh-143543
VanshAgarwal24036 Jan 13, 2026
740218c
Avoid borrowed references during groupby key comparison
VanshAgarwal24036 Jan 13, 2026
e3a54be
Clarify NEWS entry wording
VanshAgarwal24036 Jan 13, 2026
9983345
Fix refcounting during groupby key comparison
VanshAgarwal24036 Jan 13, 2026
1ea51c0
Add NEWS entry via blurb for itertools.groupby crash
VanshAgarwal24036 Jan 13, 2026
336c367
Fix duplicate variable declarations in groupby_next
VanshAgarwal24036 Jan 13, 2026
9cbe1a6
itertools: hold strong references during groupby key comparison
VanshAgarwal24036 Jan 13, 2026
8c61450
Clarify re-entrant groupby key comparison comment
VanshAgarwal24036 Jan 14, 2026
90e995b
Update Modules/itertoolsmodule.c
VanshAgarwal24036 Jan 14, 2026
4f2338f
Update Lib/test/test_itertools.py
VanshAgarwal24036 Jan 14, 2026
2cac26b
Simplify groupby re-entrancy test
VanshAgarwal24036 Jan 14, 2026
fed7db7
Move rcmp declaration and clarify re-entrancy comment
VanshAgarwal24036 Jan 14, 2026
4939083
Move comment before declarations and inline rcmp
VanshAgarwal24036 Jan 14, 2026
e42b9b4
Remove Extra lines
VanshAgarwal24036 Jan 14, 2026
e29c818
Remove extra Lines
VanshAgarwal24036 Jan 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Lib/test/test_itertools.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,19 @@ def keyfunc(obj):
keyfunc.skip = 1
self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)

def test_groupby_reentrant_eq_does_not_crash(self):
class Key(bytearray):
seen = False
def __eq__(self, other):
if not Key.seen:
Key.seen = True
next(g)
return False

g = itertools.groupby([Key(b"a"), Key(b"b")])
next(g)
next(g) # must not segfault

def test_filter(self):
self.assertEqual(list(filter(isEven, range(6))), [0,2,4])
self.assertEqual(list(filter(None, [0,1,0,2,0])), [1,2])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a crash in itertools.groupby that could occur when a user-defined
:meth:`~object.__eq__` method re-enters the iterator during key comparison.
14 changes: 12 additions & 2 deletions Modules/itertoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,19 @@ groupby_next(PyObject *op)
else if (gbo->tgtkey == NULL)
break;
else {
int rcmp;
/* A user-defined __eq__ can re-enter groupby and advance the iterator,
mutating gbo->tgtkey / gbo->currkey while we are comparing them.
Take local snapshots and hold strong references so INCREF/DECREF
apply to the same objects even under re-entrancy. */
PyObject *tgtkey = gbo->tgtkey;
PyObject *currkey = gbo->currkey;

Py_INCREF(tgtkey);
Py_INCREF(currkey);
int rcmp = PyObject_RichCompareBool(tgtkey, currkey, Py_EQ);
Py_DECREF(tgtkey);
Py_DECREF(currkey);

rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ);
if (rcmp == -1)
return NULL;
else if (rcmp == 0)
Expand Down
Loading