Commit 7a3d41f4 authored by Raymond Hettinger's avatar Raymond Hettinger

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

parent 18ffe42b
...@@ -614,11 +614,19 @@ def test_pack_into_fn(): ...@@ -614,11 +614,19 @@ def test_pack_into_fn():
assertRaises(struct.error, pack_into, small_buf, 0, test_string) assertRaises(struct.error, pack_into, small_buf, 0, test_string)
assertRaises(struct.error, pack_into, small_buf, 2, 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
data1 = array.array('B', '\x12\x34\x56\x78')
data2 = buffer('......\x12\x34\x56\x78......', 6, 4)
for data in [data1, data2]:
value, = struct.unpack('>I', data)
vereq(value, 0x12345678)
# Test methods to pack and unpack from buffers rather than strings. # Test methods to pack and unpack from buffers rather than strings.
test_unpack_from() test_unpack_from()
test_pack_into() test_pack_into()
test_pack_into_fn() test_pack_into_fn()
test_unpack_with_buffer()
def test_bool(): def test_bool():
for prefix in tuple("<>!=")+('',): for prefix in tuple("<>!=")+('',):
......
...@@ -1534,17 +1534,35 @@ strings."); ...@@ -1534,17 +1534,35 @@ strings.");
static PyObject * static PyObject *
s_unpack(PyObject *self, PyObject *inputstr) s_unpack(PyObject *self, PyObject *inputstr)
{ {
char *start;
Py_ssize_t len;
PyObject *args=NULL, *result;
PyStructObject *soself = (PyStructObject *)self; PyStructObject *soself = (PyStructObject *)self;
assert(PyStruct_Check(self)); assert(PyStruct_Check(self));
assert(soself->s_codes != NULL); assert(soself->s_codes != NULL);
if (inputstr == NULL || !PyString_Check(inputstr) || if (inputstr == NULL)
PyString_GET_SIZE(inputstr) != soself->s_size) { goto fail;
PyErr_Format(StructError, if (PyString_Check(inputstr) &&
"unpack requires a string argument of length %zd", PyString_GET_SIZE(inputstr) == soself->s_size) {
soself->s_size); return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
return NULL;
} }
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))
goto fail;
if (soself->s_size != len)
goto fail;
result = s_unpack_internal(soself, start);
Py_DECREF(args);
return result;
fail:
Py_XDECREF(args);
PyErr_Format(StructError,
"unpack requires a string argument of length %zd",
soself->s_size);
return NULL;
} }
PyDoc_STRVAR(s_unpack_from__doc__, PyDoc_STRVAR(s_unpack_from__doc__,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment