Commits

Anonymous committed 4c7ebc3

Bug #1563759: struct.unpack doens't support buffer protocol objects

  • Participants
  • Parent commits b001b65
  • Branches 2.5

Comments (0)

Files changed (3)

File Lib/test/test_struct.py

     assertRaises(struct.error, pack_into, small_buf, 0, test_string)
     assertRaises(struct.error, pack_into, small_buf, 2, test_string)
 
+def test_unpack_with_buffer():
+    # SF bug 1563759: struct.unpack doens't support buffer protocol objects
+    data = array.array('B', '\x12\x34\x56\x78')
+    value, = struct.unpack('>I', data)
+    vereq(value, 0x12345678)
 
 # Test methods to pack and unpack from buffers rather than strings.
 test_unpack_from()
 test_pack_into()
 test_pack_into_fn()
+test_unpack_with_buffer()
 Extension Modules
 -----------------
 
+- Bug #1563759: struct.unpack doens't support buffer protocol objects
+
 - Bug #1686475: Support stat'ing open files on Windows again.
 
 - Bug #1647541: Array module's buffer interface can now handle empty arrays.

File Modules/_struct.c

 static PyObject *
 s_unpack(PyObject *self, PyObject *inputstr)
 {
+	char *start;
+	int len;
+	PyObject * args;
 	PyStructObject *soself = (PyStructObject *)self;
 	assert(PyStruct_Check(self));
 	assert(soself->s_codes != NULL);
-	if (inputstr == NULL || !PyString_Check(inputstr) ||
-		PyString_GET_SIZE(inputstr) != soself->s_size) {
+	if (inputstr != NULL && PyString_Check(inputstr) &&
+		PyString_GET_SIZE(inputstr) == soself->s_size) {
+			return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+	}
+	args = PyTuple_Pack(1, inputstr);
+	if (args == NULL)
+		return NULL;
+	if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len)) {
+		Py_DECREF(args);
+		return NULL;
+	}
+	Py_DECREF(args);
+	if (soself->s_size != len) {
 		PyErr_Format(StructError,
 			"unpack requires a string argument of length %zd",
 			soself->s_size);
 		return NULL;
 	}
-	return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+	return s_unpack_internal(soself, start);
 }
 
 PyDoc_STRVAR(s_unpack_from__doc__,