]> granicus.if.org Git - python/commitdiff
Patch #1542451: disallow continue anywhere under a finally
authorNeal Norwitz <nnorwitz@gmail.com>
Mon, 21 Aug 2006 19:47:08 +0000 (19:47 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Mon, 21 Aug 2006 19:47:08 +0000 (19:47 +0000)
I'm undecided if this should be backported to 2.5 or 2.5.1.
Armin suggested to wait (I'm of the same opinion).  Thomas W thinks
it's fine to go in 2.5.

Lib/test/test_syntax.py
Misc/NEWS
Python/compile.c

index dc7a16d1e26330867e79be93b48697f61fff6ad3..692ba57a3eae5ca85af94bbe4290a1192918ad04 100644 (file)
@@ -235,6 +235,93 @@ SyntaxError: assignment to None (<doctest test.test_syntax[32]>, line 1)
 >>> f() += 1
 Traceback (most recent call last):
 SyntaxError: illegal expression for augmented assignment (<doctest test.test_syntax[33]>, line 1)
+
+
+Test continue in finally in weird combinations.
+
+continue in for loop under finally shouuld be ok.
+
+    >>> def test():
+    ...     try:
+    ...         pass
+    ...     finally:
+    ...         for abc in range(10):
+    ...             continue
+    ...     print abc
+    >>> test()
+    9
+
+Start simple, a continue in a finally should not be allowed.
+
+    >>> def test():
+    ...    for abc in range(10):
+    ...        try:
+    ...            pass
+    ...        finally:
+    ...            continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[36]>, line 6)
+
+This is essentially a continue in a finally which should not be allowed.
+
+    >>> def test():
+    ...    for abc in range(10):
+    ...        try:
+    ...            pass
+    ...        finally:
+    ...            try:
+    ...                continue
+    ...            except:
+    ...                pass
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[37]>, line 7)
+
+    >>> def foo():
+    ...     try:
+    ...         pass
+    ...     finally:
+    ...         continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[38]>, line 5)
+
+    >>> def foo():
+    ...     for a in ():
+    ...       try:
+    ...           pass
+    ...       finally:
+    ...           continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[39]>, line 6)
+
+    >>> def foo():
+    ...     for a in ():
+    ...         try:
+    ...             pass
+    ...         finally:
+    ...             try:
+    ...                 continue
+    ...             finally:
+    ...                 pass
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[40]>, line 7)
+
+    >>> def foo():
+    ...  for a in ():
+    ...   try: pass
+    ...   finally:
+    ...    try:
+    ...     pass
+    ...    except:
+    ...     continue
+    Traceback (most recent call last):
+      ...
+    SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[41]>, line 8)
+
 """
 
 import re
index f304314ff08033d2cc3b54f6041db911b3e94dac..757e28b44d35ed68f095175fba7b9d5b3f72058b 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.6?
 Core and builtins
 -----------------
 
+- Patch #1542451: disallow continue anywhere under a finally.
+
 
 Library
 -------
index 5aaf809cd48799f4d7e548be12a0c3daf8cb9cd5..a03de0d663a9ad47b30d70c46b0b4bc612908aa9 100644 (file)
@@ -1682,6 +1682,8 @@ static int
 compiler_continue(struct compiler *c)
 {
        static const char LOOP_ERROR_MSG[] = "'continue' not properly in loop";
+       static const char IN_FINALLY_ERROR_MSG[] = 
+                       "'continue' not supported inside 'finally' clause";
        int i;
 
        if (!c->u->u_nfblocks)
@@ -1693,15 +1695,18 @@ compiler_continue(struct compiler *c)
                break;
        case EXCEPT:
        case FINALLY_TRY:
-               while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP)
-                       ;
+               while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP) {
+                       /* Prevent continue anywhere under a finally
+                             even if hidden in a sub-try or except. */
+                       if (c->u->u_fblock[i].fb_type == FINALLY_END)
+                               return compiler_error(c, IN_FINALLY_ERROR_MSG);
+               }
                if (i == -1)
                        return compiler_error(c, LOOP_ERROR_MSG);
                ADDOP_JABS(c, CONTINUE_LOOP, c->u->u_fblock[i].fb_block);
                break;
        case FINALLY_END:
-               return compiler_error(c,
-                       "'continue' not supported inside 'finally' clause");
+               return compiler_error(c, IN_FINALLY_ERROR_MSG);
        }
 
        return 1;