Quellcode durchsuchen

Prevent self-catching loops when an `except` clause references an undefined name (#544)

* Initial plan

* fix undefined except handler loop

Co-authored-by: blueloveTH <28104173+blueloveTH@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: blueloveTH <28104173+blueloveTH@users.noreply.github.com>
Copilot vor 1 Tag
Ursprung
Commit
1783dc1562
2 geänderte Dateien mit 12 neuen und 2 gelöschten Zeilen
  1. 3 2
      src/interpreter/frame.c
  2. 9 0
      tests/280_exception.py

+ 3 - 2
src/interpreter/frame.c

@@ -63,9 +63,10 @@ void Frame__delete(py_Frame* self) {
 int Frame__goto_exception_handler(py_Frame* self, ValueStack* value_stack, py_Ref exc) {
     FrameExcInfo* p = self->exc_stack.data;
     for(int i = self->exc_stack.length - 1; i >= 0; i--) {
-        if(py_isnil(&p[i].exc)) {
+        CodeBlock* block = c11__at(CodeBlock, &self->co->blocks, p[i].iblock);
+        if(py_isnil(&p[i].exc) && self->ip >= block->start && self->ip < block->end) {
             value_stack->sp = (self->p0 + p[i].offset);  // unwind the stack
-            return c11__at(CodeBlock, &self->co->blocks, p[i].iblock)->end;
+            return block->end;
         } else {
             self->exc_stack.length--;
         }

+ 9 - 0
tests/280_exception.py

@@ -220,6 +220,15 @@ except Exception as e:
     if type(e) != TypeError:
         exit(1)
 
+try:
+    try:
+        x, y = [1]
+        exit(1)
+    except undefinedfoo:
+        exit(1)
+except NameError:
+    pass
+
 """
 # finally, only
 def finally_only():