From 9d21cd7e1ac79097a87654ec2ed9c85d3b963e5e Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 12 Jun 2002 03:48:46 +0000 Subject: [PATCH] Backport: SF bug 567538: Generator can crash the interpreter (Finn Bock). This was a simple typo. Strange that the compiler didn't catch it! Instead of WHY_CONTINUE, two tests used CONTINUE_LOOP, which isn't a why_code at all, but an opcode; but even though 'why' is declared as an enum, comparing it to an int is apparently not even worth a warning -- not in gcc, and not in VC++. :-( --- Lib/test/test_generators.py | 20 ++++++++++++++++++++ Misc/NEWS | 3 +++ Python/ceval.c | 4 ++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 2c319e5db982..410f043fd363 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -807,6 +807,26 @@ SyntaxError: invalid syntax ... yield 2 # because it's a generator Traceback (most recent call last): SyntaxError: 'return' with argument inside generator (, line 8) + +This one caused a crash (see SF bug 567538): + +>>> def f(): +... for i in range(3): +... try: +... continue +... finally: +... yield i +... +>>> g = f() +>>> print g.next() +0 +>>> print g.next() +1 +>>> print g.next() +2 +>>> print g.next() +Traceback (most recent call last): +StopIteration """ # conjoin is a simple backtracking generator, named in honor of Icon's diff --git a/Misc/NEWS b/Misc/NEWS index 1e81675ba43c..cf5f9e1fdc57 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -4,6 +4,9 @@ Release date: dd-mmm-2002 Core and builtins +- Fixed a bug with a continue inside a try block and a yield in the + finally clause. [SF bug 567538] + - Cycles going through the __class__ link of a new-style instance are now detected by the garbage collector. diff --git a/Python/ceval.c b/Python/ceval.c index 0fa588778191..914431afb183 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1497,7 +1497,7 @@ eval_frame(PyFrameObject *f) why = (enum why_code) PyInt_AsLong(v); if (why == WHY_RETURN || why == WHY_YIELD || - why == CONTINUE_LOOP) + why == WHY_CONTINUE) retval = POP(); } else if (PyString_Check(v) || PyClass_Check(v)) { @@ -2293,7 +2293,7 @@ eval_frame(PyFrameObject *f) } else { if (why == WHY_RETURN || - why == CONTINUE_LOOP) + why == WHY_CONTINUE) PUSH(retval); v = PyInt_FromLong((long)why); PUSH(v); -- 2.47.3