diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 36fa7e3572a5ac..1925d655ae4fb0 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -598,6 +598,30 @@ def __next__(self): with self.assertRaises(csv.Error): next(reader) + def test_reader_reentrant_iterator_eof_in_quoted_field(self): + # gh-157379: the re-entrant call leaves an open quoted field, then + # the outer call reaches the end of input. + class ReentrantIter: + def __init__(self): + self.reader = None + self.n = 0 + def __iter__(self): + return self + def __next__(self): + self.n += 1 + if self.n == 1: + next(self.reader) + raise StopIteration + if self.n == 2: + return '"x' + raise StopIteration + + it = ReentrantIter() + reader = csv.reader(it) + it.reader = reader + with self.assertRaises(csv.Error): + next(reader) + class TestDialectRegistry(unittest.TestCase): def test_registry_badargs(self): diff --git a/Misc/NEWS.d/next/Library/2026-09-14-18-15-54.gh-issue-157379.Tq4vRw.rst b/Misc/NEWS.d/next/Library/2026-09-14-18-15-54.gh-issue-157379.Tq4vRw.rst new file mode 100644 index 00000000000000..be20c3f7ba044b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-14-18-15-54.gh-issue-157379.Tq4vRw.rst @@ -0,0 +1,2 @@ +Fix a crash in :mod:`csv` reader when a re-entrant iterator reaches the end +of input while a quoted field is still open. diff --git a/Modules/_csv.c b/Modules/_csv.c index 6af66c3f09a03b..8bf32e4d4454f4 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -1029,6 +1029,10 @@ Reader_iternext_lock_held(PyObject *op) if (self->dialect->strict) PyErr_SetString(module_state->error_obj, "unexpected end of data"); + else if (self->fields == NULL) + PyErr_SetString(module_state->error_obj, + "iterator has already advanced " + "the reader"); else if (parse_save_field(self) >= 0) break; }