Commits

Lenard Lindstrom  committed f7a9049

Fix handling of new buffer format verification in base.c

The format '1x' was not recognized (a bug accidently introduced in changeset
0ecf23052547). Also allow an item count prefix of '1' for other supported
formats. In the process, clean up and add comments to the format checking code.
Finally, add further format checking unit tests to base_test.py.

  • Participants
  • Parent commits 8e732f6

Comments (0)

Files changed (2)

             return -1;
         }
         pg_view_p->release_buffer = PyBuffer_Release;
+
+        /* Check the format is a numeric type or pad bytes
+         */
         fchar_p = view_p->format;
+        /* Skip valid size/byte order code */
         switch (*fchar_p) {
 
         case '@':
         case '!':
             ++fchar_p;
             break;
-        default:
+
+        /* default: assume it is a format type character or item count */
+        }
+        /* Skip a leading digit */
+        switch (*fchar_p) {
+
+        case '1':
+            /* valid count for all item types */
+            ++fchar_p;
             break;
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            /* only valid as a pad byte count */
+            if (*(fchar_p + 1) == 'x') {
+                ++fchar_p;
+            }
+            break;
+
+        /* default: assume it is a format character */
         }
-        /* Skip a leading count of 1 */
-        if (*fchar_p == '1') {
-            ++fchar_p;
-        }
+        /* verify is a format type character */
         switch (*fchar_p) {
 
         case 'b':
         case 'Q':
         case 'f':
         case 'd':
+        case 'x':
             ++fchar_p;
             break;
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-            ++fchar_p;
-            if (*fchar_p == 'x') {
-                ++fchar_p;
-            }
-            break;
         default:
             PgBuffer_Release (pg_view_p);
             PyErr_SetString (PyExc_ValueError,

File test/base_test.py

             self.NEWBUF_test_PgDict_AsBuffer_PyBUF_flags()
         def test_PgObject_AsBuffer_PyBUF_flags(self):
             self.NEWBUF_test_PgObject_AsBuffer_PyBUF_flags()
+        def test_bad_format(self):
+            self.NEWBUF_test_bad_format()
         if is_pygame_pkg:
             from pygame.tests.test_utils import buftools
         else:
         ndim = 2
         shape = _shape[0:ndim]
         for format in ['b', 'B', '=h', '=H', '=i', '=I', '=q', '=Q', 'f', 'd',
-                       '1h', '=1h']:
+                       '1h', '=1h', 'x', '1x', '2x', '3x', '4x', '5x', '6x',
+                       '7x', '8x', '9x']:
             o = Exporter(shape, format)
             v = BufferProxy(o)
             self.NEWBUF_assertSame(v, o)
 
+    def NEWBUF_test_bad_format(self):
+        from pygame.bufferproxy import BufferProxy
+        from pygame.newbuffer import BufferMixin
+        from ctypes import create_string_buffer, addressof
+
+        buftools = self.buftools
+        Importer = buftools.Importer
+        PyBUF_FORMAT = buftools.PyBUF_FORMAT
+
+        class Exporter(BufferMixin):
+            def __init__(self, format):
+                self.format = create_string_buffer(format)
+            def _get_buffer(self, view, flags):
+                view.obj = self
+                view.format = addressof(self.format)
+
+        for format in ['', '=', '1', ' ', '2h', '=2h',
+                       '0x', '11x', '=!', 'h ', ' h', 'hh', '?']:
+            exp = Exporter(format)
+            b = BufferProxy(exp)
+            self.assertRaises(ValueError, Importer, b, PyBUF_FORMAT)
+
     def NEWBUF_test_PgDict_AsBuffer_PyBUF_flags(self):
         from pygame.bufferproxy import BufferProxy