From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 16 Jun 2023 18:29:55 +0000 (-0700) Subject: [3.12] GH-105840: Fix assertion failures when specializing calls with too many __defa... X-Git-Tag: v3.12.0b3~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=560adb01f97015a6778568e057aa3eeaace3b5f4;p=thirdparty%2FPython%2Fcpython.git [3.12] GH-105840: Fix assertion failures when specializing calls with too many __defaults__ (GH-105863) GH-105840: Fix assertion failures when specializing calls with too many __defaults__ (GH-105847) (cherry picked from commit 2beab5bdef5fa2a00a59371e6137f769586b7404) Co-authored-by: Brandt Bucher --- diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 57fed5d09fd7..5281eb77c02d 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -452,6 +452,35 @@ class TestLoadMethodCache(unittest.TestCase): self.assertFalse(f()) +class TestCallCache(unittest.TestCase): + def test_too_many_defaults_0(self): + def f(): + pass + + f.__defaults__ = (None,) + for _ in range(1025): + f() + + def test_too_many_defaults_1(self): + def f(x): + pass + + f.__defaults__ = (None, None) + for _ in range(1025): + f(None) + f() + + def test_too_many_defaults_2(self): + def f(x, y): + pass + + f.__defaults__ = (None, None, None) + for _ in range(1025): + f(None, None) + f(None) + f() + + if __name__ == "__main__": import unittest unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst new file mode 100644 index 000000000000..5225031292e6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst @@ -0,0 +1,2 @@ +Fix possible crashes when specializing function calls with too many +``__defaults__``. diff --git a/Python/specialize.c b/Python/specialize.c index f1684913b1bc..63b44461007c 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1666,9 +1666,9 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, } int argcount = code->co_argcount; int defcount = func->func_defaults == NULL ? 0 : (int)PyTuple_GET_SIZE(func->func_defaults); - assert(defcount <= argcount); int min_args = argcount-defcount; - if (nargs > argcount || nargs < min_args) { + // GH-105840: min_args is negative when somebody sets too many __defaults__! + if (min_args < 0 || nargs > argcount || nargs < min_args) { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; }