Skip to content

Commit cfbf1a3

Browse files
committed
Fix an issue that was reported in but unrelated to the main problem of
SF bug 535905 (Evil Trashcan and GC interaction). The SETLOCAL() macro should not DECREF the local variable in-place and then store the new value; it should copy the old value to a temporary value, then store the new value, and then DECREF the temporary value. This is because it is possible that during the DECREF the frame is accessed by other code (e.g. a __del__ method or gc.collect()) and the variable would be pointing to already-freed memory. BUGFIX CANDIDATE!
1 parent 47cdf6f commit cfbf1a3

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

Python/ceval.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,16 @@ eval_frame(PyFrameObject *f)
554554
/* Local variable macros */
555555

556556
#define GETLOCAL(i) (fastlocals[i])
557-
#define SETLOCAL(i, value) do { Py_XDECREF(GETLOCAL(i)); \
558-
GETLOCAL(i) = value; } while (0)
557+
558+
/* The SETLOCAL() macro must not DECREF the local variable in-place and
559+
then store the new value; it must copy the old value to a temporary
560+
value, then store the new value, and then DECREF the temporary value.
561+
This is because it is possible that during the DECREF the frame is
562+
accessed by other code (e.g. a __del__ method or gc.collect()) and the
563+
variable would be pointing to already-freed memory. */
564+
#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
565+
GETLOCAL(i) = value; \
566+
Py_XDECREF(tmp); } while (0)
559567

560568
/* Start of code */
561569

0 commit comments

Comments
 (0)