]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-126594: Fix typeobject.c wrap_buffer() cast (GH-126754) (#127005)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 19 Nov 2024 08:33:18 +0000 (09:33 +0100)
committerGitHub <noreply@github.com>
Tue, 19 Nov 2024 08:33:18 +0000 (08:33 +0000)
gh-126594: Fix typeobject.c wrap_buffer() cast (GH-126754)

Reject flags smaller than INT_MIN.

(cherry picked from commit 84f07c3a4cbcfe488ccfb4030571be0bc4de7e45)

Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Lib/test/test_buffer.py
Objects/typeobject.c

index 84a34bccbc9af156aba1add2de6853a913569caa..5f3e8b0ff59f8dbe4830570a7da4ae2c6cb6757e 100644 (file)
@@ -4442,6 +4442,21 @@ class TestBufferProtocol(unittest.TestCase):
             self.assertEqual(_testcapi.PyBuffer_SizeFromFormat(format),
                              struct.calcsize(format))
 
+    @support.cpython_only
+    def test_flags_overflow(self):
+        # gh-126594: Check for integer overlow on large flags
+        try:
+            from _testcapi import INT_MIN, INT_MAX
+        except ImportError:
+            INT_MIN = -(2 ** 31)
+            INT_MAX = 2 ** 31 - 1
+
+        obj = b'abc'
+        for flags in (INT_MIN - 1, INT_MAX + 1):
+            with self.subTest(flags=flags):
+                with self.assertRaises(OverflowError):
+                    obj.__buffer__(flags)
+
 
 class TestPythonBufferProtocol(unittest.TestCase):
     def test_basic(self):
index 7c678907ed56026ccaa3b3ca2c92109920169340..5bca4b4e788608d0fd5671d9dc7eb1c5d64de8d4 100644 (file)
@@ -8207,13 +8207,13 @@ wrap_buffer(PyObject *self, PyObject *args, void *wrapped)
     if (flags == -1 && PyErr_Occurred()) {
         return NULL;
     }
-    if (flags > INT_MAX) {
+    if (flags > INT_MAX || flags < INT_MIN) {
         PyErr_SetString(PyExc_OverflowError,
-                        "buffer flags too large");
+                        "buffer flags out of range");
         return NULL;
     }
 
-    return _PyMemoryView_FromBufferProc(self, Py_SAFE_DOWNCAST(flags, Py_ssize_t, int),
+    return _PyMemoryView_FromBufferProc(self, (int)flags,
                                         (getbufferproc)wrapped);
 }