Commits

Lenard Lindstrom committed aa398be

Add pygame.Surface unit tests for PyBUF_* flags: surface_test.py crashes

Changed the Surface.get_buffer() BufferProxy object to set Py_buffer.ndim to 0
for a '&' buffer kind. This leads to a crash.

Comments (0)

Files changed (2)

     VIEWKIND_RAW
 } SurfViewKind;
 
+#define PyBUF_HAS_FLAG(f, F) (((f) & (F)) == (F))
+#define PyBUF_NO_DIM (PyBUF_WRITABLE | PyBUF_FORMAT)
+#define PyBUF_IS_DIMLESS(f) (((f) | PyBUF_NO_DIM) == PyBUF_NO_DIM)
+
 /* To avoid problems with non-const Py_buffer format field */
 static char FormatUint8[] = "B";
 static char FormatUint16[] = "=H";
     view_p->buf = surface->pixels;
     view_p->itemsize = 1;
     view_p->len = surface->pitch * surface->h;
-    view_p->ndim = 1;
+    if (!PyBUF_IS_DIMLESS(flags)) {
+        view_p->ndim = 1;
+    }
     view_p->readonly = 0;
     if (flags & PyBUF_FORMAT) {
         view_p->format = FormatUint8;
         ((Py_buffer *)pg_view_p)->shape = 0;
         ((Py_buffer *)pg_view_p)->strides = 0;
     }
+    ((Py_buffer *)pg_view_p)->ndim = 0;
     ((Py_buffer *)pg_view_p)->format = 0;
     ((Py_buffer *)pg_view_p)->suboffsets = 0;
     ((Py_buffer *)pg_view_p)->internal = internal;

test/surface_test.py

         surf.scroll(dx=-3, dy=-3)
         self.failUnlessEqual(surf.get_at((0, 0)), spot_color)
 
-class SurfaceGetViewTest (unittest.TestCase):
+class SurfaceGetBufferTest (unittest.TestCase):
 
     # These tests requires ctypes. They are disabled if ctypes
     # is not installed.
                 s = pygame.Surface((4, 2), 0, 32)
                 self._check_interface_rgba(s, plane)
 
+    if pygame.HAVE_NEWBUF:
+        def test_newbuf_PyBUF_flags_bytes(self):
+            self.NEWBUF_test_newbuf_PyBUF_flags_bytes()
+        def test_newbuf_PyBUF_flags_0D(self):
+            self.NEWBUF_test_newbuf_PyBUF_flags_2D()
+        def test_newbuf_PyBUF_flags_1D(self):
+            self.NEWBUF_test_newbuf_PyBUF_flags_2D()
+        def test_newbuf_PyBUF_flags_2D(self):
+            self.NEWBUF_test_newbuf_PyBUF_flags_2D()
+        def test_newbuf_PyBUF_flags_3D(self):
+            self.NEWBUF_test_newbuf_PyBUF_flags_2D()
+        def test_newbuf_PyBUF_flags_rgba(self):
+            self.NEWBUF_test_newbuf_PyBUF_flags_2D()
+        if is_pygame_pkg:
+            from pygame.tests.test_utils import buftools
+        else:
+            from test.test_utils import buftools
+
+    def NEWBUF_test_newbuf_PyBUF_flags_bytes(self):
+        buftools = self.buftools
+        BufferImporter = buftools.BufferImporter
+        s = pygame.Surface((10, 6), 0, 32)
+        a = s.get_buffer('&')
+        b = BufferImporter(a, buftools.PyBUF_SIMPLE)
+        self.assertEqual(b.ndim, 0)
+        self.assertTrue(b.format is None)
+        self.assertEqual(b.len, a.length)
+        self.assertEqual(b.itemsize, 1)
+        self.assertTrue(b.shape is None)
+        self.assertTrue(b.strides is None)
+        self.assertTrue(b.suboffsets is None)
+        self.assertFalse(b.readonly)
+        self.assertEqual(b.buf, s._pixels_address)
+        b = BufferImporter(a, buftools.PyBUF_WRITABLE)
+        self.assertEqual(b.ndim, 0)
+        self.assertTrue(b.format is None)
+        self.assertFalse(b.readonly)
+        b = BufferImporter(a, buftools.PyBUF_FORMAT)
+        self.assertEqual(b.ndim, 0)
+        self.assertEqual(b.format, 'B')
+        b = BufferImporter(a, buftools.PyBUF_ND)
+        self.assertEqual(b.ndim, 1)
+        self.assertTrue(b.format is None)
+        self.assertEqual(b.len, a.length)
+        self.assertEqual(b.itemsize, 1)
+        self.assertEqual(b.shape, (a.length,))
+        self.assertTrue(b.strides is None)
+        self.assertTrue(b.suboffsets is None)
+        self.assertFalse(b.readonly)
+        self.assertEqual(b.buf, s._pixels_address)
+        b = BufferImporter(a, buftools.PyBUF_STRIDES)
+        self.assertEqual(b.ndim, 1)
+        self.assertTrue(b.format is None)
+        self.assertEqual(b.strides, (1,))
+        s2 = s.subsurface((1, 1, 7, 4)) # Not contiguous
+        a = s.get_buffer('&')
+        b = BufferImporter(a, buftools.PyBUF_SIMPLE)
+        self.assertEqual(b.ndim, 0)
+        self.assertTrue(b.format is None)
+        self.assertEqual(b.len, a.length)
+        self.assertEqual(b.itemsize, 1)
+        self.assertTrue(b.shape is None)
+        self.assertTrue(b.strides is None)
+        self.assertTrue(b.suboffsets is None)
+        self.assertFalse(b.readonly)
+        self.assertEqual(b.buf, s2._pixels_address)
+        b = BufferImporter(a, buftools.PyBUF_C_CONTIGUOUS)
+        self.assertEqual(b.ndim, 0)
+        b = BufferImporter(a, buftools.PyBUF_F_CONTIGUOUS)
+        self.assertEqual(b.ndim, 0)
+        b = BufferImporter(a, buftools.PyBUF_ANY_CONTIGUOUS)
+        self.assertEqual(b.ndim, 0)
+
+    def NEWBUF_test_newbuf_PyBUF_flags_0D(self):
+        self.fail()
+    def NEWBUF_test_newbuf_PyBUF_flags_1D(self):
+        self.fail()
+    def NEWBUF_test_newbuf_PyBUF_flags_2D(self):
+        self.fail()
+    def NEWBUF_test_newbuf_PyBUF_flags_3D(self):
+        self.fail()
+    def NEWBUF_test_newbuf_PyBUF_flags_rgba(self):
+        self.fail()
+
 class SurfaceBlendTest (unittest.TestCase):
 
     _test_palette = [(0, 0, 0, 255),
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.