Skip to content

Commit 39b65fc

Browse files
committed
avoid use-after-free
1 parent c05d147 commit 39b65fc

1 file changed

Lines changed: 21 additions & 19 deletions

File tree

‎Python/symtable.c‎

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -895,39 +895,41 @@ finalize_inlined_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
895895
}
896896
continue;
897897
}
898+
int is_def_bound = 0;
899+
if (existing) {
900+
long flags = PyLong_AsLong(existing);
901+
if (flags == -1 && PyErr_Occurred()) {
902+
goto error;
903+
}
904+
is_def_bound = flags & DEF_BOUND;
905+
}
898906
// Loads here are in the enclosing compilation unit.
899907
if (scope == FREE && (comp_flags & USE) &&
900908
!symtable_add_flag(ste->ste_symbols, k, USE)) {
901909
goto error;
902910
}
903-
if (existing) {
904-
long flags = PyLong_AsLong(existing);
905-
if (flags == -1 && PyErr_Occurred()) {
911+
if (is_def_bound && ste->ste_type != ClassBlock) {
912+
// free vars in comprehension that are locals in outer scope can
913+
// now simply be locals, unless they are free in comp children,
914+
// needed as cells by sibling nested scopes, or if the outer
915+
// scope is a class block
916+
int ok = is_free_in_any_child(comp, k);
917+
if (ok < 0) {
906918
goto error;
907919
}
908-
if ((flags & DEF_BOUND) && ste->ste_type != ClassBlock) {
909-
// free vars in comprehension that are locals in outer scope can
910-
// now simply be locals, unless they are free in comp children,
911-
// needed as cells by sibling nested scopes, or if the outer
912-
// scope is a class block
913-
int ok = is_free_in_any_child(comp, k);
914-
if (ok < 0) {
920+
if (!ok) {
921+
int in_newfree = PySet_Contains(outer_newfree, k);
922+
if (in_newfree < 0) {
915923
goto error;
916924
}
917-
if (!ok) {
918-
int in_newfree = PySet_Contains(outer_newfree, k);
919-
if (in_newfree < 0) {
925+
if (!in_newfree) {
926+
if (PySet_Discard(comp_free, k) < 0) {
920927
goto error;
921928
}
922-
if (!in_newfree) {
923-
if (PySet_Discard(comp_free, k) < 0) {
924-
goto error;
925-
}
926-
}
927929
}
928930
}
929931
}
930-
else {
932+
else if (!existing) {
931933
assert(scope != FREE || PySet_Contains(comp_free, k) == 1);
932934
}
933935
}

0 commit comments

Comments
 (0)