]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Fix a SystemError in code.replace() (#27771)
authorGuido van Rossum <guido@python.org>
Mon, 16 Aug 2021 18:34:23 +0000 (11:34 -0700)
committerGitHub <noreply@github.com>
Mon, 16 Aug 2021 18:34:23 +0000 (11:34 -0700)
While the comment said 'We don't bother resizing localspluskinds',
this would cause .replace() to crash when it happened.
(Also types.CodeType(), but testing that is tedious, and this tests all
code paths.)

Lib/test/test_code.py
Objects/codeobject.c

index 2bdd7e749434d04a30ffaf65e6926159f517f168..9d6b465115ca269656ab8dd545458f71b35c26fc 100644 (file)
@@ -320,6 +320,15 @@ class CodeTest(unittest.TestCase):
         with self.assertRaises(ValueError):
             co.replace(co_nlocals=co.co_nlocals + 1)
 
+    def test_shrinking_localsplus(self):
+        # Check that PyCode_NewWithPosOnlyArgs resizes both
+        # localsplusnames and localspluskinds, if an argument is a cell.
+        def func(arg):
+            return lambda: arg
+        code = func.__code__
+        newcode = code.replace(co_name="func")  # Should not raise SystemError
+        self.assertEqual(code, newcode)
+
     def test_empty_linetable(self):
         def func():
             pass
index 3dc9fd787f3859f8183805d54858780fcadca9bc..ad8f13a781b94af47927a2469db7643d5b420a95 100644 (file)
@@ -471,9 +471,11 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
                                localsplusnames, localspluskinds);
     }
     // If any cells were args then nlocalsplus will have shrunk.
-    // We don't bother resizing localspluskinds.
-    if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0) {
-        goto error;
+    if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) {
+        if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0
+                || _PyBytes_Resize(&localspluskinds, nlocalsplus) < 0) {
+            goto error;
+        }
     }
 
     struct _PyCodeConstructor con = {