]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Fix integer overflow for formats "s" and "p" in the struct module (GH-145750)
authorStan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
Tue, 10 Mar 2026 16:57:34 +0000 (16:57 +0000)
committerGitHub <noreply@github.com>
Tue, 10 Mar 2026 16:57:34 +0000 (18:57 +0200)
Lib/test/test_struct.py
Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst [new file with mode: 0644]
Modules/_struct.c

index 6904572d095d317375b54c969b03087867f218e8..55e2ce590a257749956a70e225bc318ac50dde60 100644 (file)
@@ -555,6 +555,12 @@ class StructTest(ComplexesAreIdenticalMixin, unittest.TestCase):
         hugecount3 = '{}i{}q'.format(sys.maxsize // 4, sys.maxsize // 8)
         self.assertRaises(struct.error, struct.calcsize, hugecount3)
 
+        hugecount4 = '{}?s'.format(sys.maxsize)
+        self.assertRaises(struct.error, struct.calcsize, hugecount4)
+
+        hugecount5 = '{}?p'.format(sys.maxsize)
+        self.assertRaises(struct.error, struct.calcsize, hugecount5)
+
     def test_trailing_counter(self):
         store = array.array('b', b' '*100)
 
diff --git a/Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst b/Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst
new file mode 100644 (file)
index 0000000..a909bea
--- /dev/null
@@ -0,0 +1,3 @@
+Avoid undefined behaviour from signed integer overflow when parsing format
+strings in the :mod:`struct` module. Found by OSS Fuzz in
+:oss-fuzz:`488466741`.
index c2f7b1fe0e800a5b8ffe59e20248582670550d05..f8574322b40c8de706d17e327c34946df461554e 100644 (file)
@@ -1676,7 +1676,13 @@ prepare_s(PyStructObject *self, PyObject *format)
 
         switch (c) {
             case 's': _Py_FALLTHROUGH;
-            case 'p': len++; ncodes++; break;
+            case 'p':
+                if (len == PY_SSIZE_T_MAX) {
+                    goto overflow;
+                }
+                len++;
+                ncodes++;
+                break;
             case 'x': break;
             default:
                 if (num > PY_SSIZE_T_MAX - len) {