[Python-checkins] [3.11] GH-105840: Fix assertion failures when specializing calls with too many __defaults__ (GH-105864)
brandtbucher
webhook-mailer at python.org
Fri Jun 16 14:30:25 EDT 2023
https://github.com/python/cpython/commit/2944a6cc0a4d572288d328b2caa1fc8f3a582863
commit: 2944a6cc0a4d572288d328b2caa1fc8f3a582863
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: brandtbucher <brandtbucher at gmail.com>
date: 2023-06-16T18:30:22Z
summary:
[3.11] GH-105840: Fix assertion failures when specializing calls with too many __defaults__ (GH-105864)
GH-105840: Fix assertion failures when specializing calls with too many __defaults__ (GH-105847)
(cherry picked from commit 2beab5bdef5fa2a00a59371e6137f769586b7404)
Co-authored-by: Brandt Bucher <brandtbucher at microsoft.com>
files:
A Misc/NEWS.d/next/Core and Builtins/2023-06-15-22-11-43.gh-issue-105840.Fum_g_.rst
M Lib/test/test_opcache.py
M Python/specialize.c
diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py
index e39b72606248..5def58ca97bb 100644
--- a/Lib/test/test_opcache.py
+++ b/Lib/test/test_opcache.py
@@ -429,6 +429,35 @@ def f():
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 9d182fd31b08..4a5213c31c7b 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -1500,9 +1500,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;
}
More information about the Python-checkins
mailing list