diff options
author | Xiang Zhang <angwerzx@126.com> | 2018-03-11 02:58:52 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-11 02:58:52 +0800 |
commit | c10b288f345aaef66d2c844924b9a576f9ea4f8b (patch) | |
tree | 30d64745d62c991b5d18bfc1c381f31b165c7c4d /Modules/_struct.c | |
parent | 67ee07795bcd84b679c000780212d4d81a1490a3 (diff) | |
download | cpython-git-c10b288f345aaef66d2c844924b9a576f9ea4f8b.tar.gz |
bpo-30249: Improve struct.unpack_from() error messages (GH-6059)
Diffstat (limited to 'Modules/_struct.c')
-rw-r--r-- | Modules/_struct.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/Modules/_struct.c b/Modules/_struct.c index 66f74d63b7..053970671f 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1553,7 +1553,8 @@ Return a tuple containing unpacked values. Values are unpacked according to the format string Struct.format. -The buffer's size in bytes, minus offset, must be at least Struct.size. +The buffer's size in bytes, starting at position offset, must be +at least Struct.size. See help(struct) for more on format strings. [clinic start generated code]*/ @@ -1561,16 +1562,38 @@ See help(struct) for more on format strings. static PyObject * Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, Py_ssize_t offset) -/*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/ +/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ { assert(self->s_codes != NULL); - if (offset < 0) + if (offset < 0) { + if (offset + self->s_size > 0) { + PyErr_Format(StructError, + "not enough data to unpack %zd bytes at offset %zd", + self->s_size, + offset); + return NULL; + } + + if (offset + buffer->len < 0) { + PyErr_Format(StructError, + "offset %zd out of range for %zd-byte buffer", + offset, + buffer->len); + return NULL; + } offset += buffer->len; - if (offset < 0 || buffer->len - offset < self->s_size) { + } + + if ((buffer->len - offset) < self->s_size) { PyErr_Format(StructError, - "unpack_from requires a buffer of at least %zd bytes", - self->s_size); + "unpack_from requires a buffer of at least %zu bytes for " + "unpacking %zd bytes at offset %zd " + "(actual buffer size is %zd)", + (size_t)self->s_size + (size_t)offset, + self->s_size, + offset, + buffer->len); return NULL; } return s_unpack_internal(self, (char*)buffer->buf + offset); |