Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c10b288f
Commit
c10b288f
authored
Mar 11, 2018
by
Xiang Zhang
Committed by
GitHub
Mar 11, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-30249: Improve struct.unpack_from() error messages (GH-6059)
parent
67ee0779
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
67 additions
and
15 deletions
+67
-15
Doc/library/struct.rst
Doc/library/struct.rst
+3
-3
Lib/test/test_struct.py
Lib/test/test_struct.py
+30
-4
Misc/NEWS.d/next/Library/2018-03-11-00-20-26.bpo-30249.KSkgLB.rst
...S.d/next/Library/2018-03-11-00-20-26.bpo-30249.KSkgLB.rst
+2
-0
Modules/_struct.c
Modules/_struct.c
+29
-6
Modules/clinic/_struct.c.h
Modules/clinic/_struct.c.h
+3
-2
No files found.
Doc/library/struct.rst
View file @
c10b288f
...
...
@@ -74,8 +74,8 @@ The module defines the following exception and functions:
Unpack from *buffer* starting at position *offset*, according to the format
string *format*. The result is a tuple even if it contains exactly one
item. The buffer's size in bytes,
minus *offset*, must be at leas
t
the size required by the format, as reflected by :func:`calcsize`.
item. The buffer's size in bytes,
starting at position *offset*, must be a
t
least
the size required by the format, as reflected by :func:`calcsize`.
.. function:: iter_unpack(format, buffer)
...
...
@@ -428,7 +428,7 @@ The :mod:`struct` module also defines the following type:
.. method:: unpack_from(buffer, offset=0)
Identical to the :func:`unpack_from` function, using the compiled format.
The buffer's size in bytes,
minus
*offset*, must be at least
The buffer's size in bytes,
starting at position
*offset*, must be at least
:attr:`size`.
...
...
Lib/test/test_struct.py
View file @
c10b288f
...
...
@@ -579,14 +579,22 @@ class StructTest(unittest.TestCase):
self
.
check_sizeof
(
'0c'
,
0
)
def
test_boundary_error_message
(
self
):
regex
=
(
regex
1
=
(
r'pack_into requires a buffer of at least 6 '
r'bytes for packing 1 bytes at offset 5 '
r'\
(
actual buffer size is 1\
)
'
)
with self.assertRaisesRegex(struct.error, regex):
with self.assertRaisesRegex(struct.error, regex
1
):
struct.pack_into('b', bytearray(1), 5, 1)
regex2 = (
r'
unpack_from
requires
a
buffer
of
at
least
6
'
r'
bytes
for
unpacking
1
bytes
at
offset
5
'
r'
\
(
actual
buffer
size
is
1
\
)
'
)
with self.assertRaisesRegex(struct.error, regex2):
struct.unpack_from('b', bytearray(1), 5)
def test_boundary_error_message_with_negative_offset(self):
byte_list = bytearray(10)
with self.assertRaisesRegex(
...
...
@@ -599,16 +607,34 @@ class StructTest(unittest.TestCase):
'
offset
-
11
out
of
range
for
10
-
byte
buffer
'):
struct.pack_into('
<
B', byte_list, -11, 123)
with self.assertRaisesRegex(
struct.error,
r'
not
enough
data
to
unpack
4
bytes
at
offset
-
2
'):
struct.unpack_from('
<
I
', byte_list, -2)
with self.assertRaisesRegex(
struct.error,
"offset -11 out of range for 10-byte buffer"):
struct.unpack_from('
<
B', byte_list, -11)
def test_boundary_error_message_with_large_offset(self):
# Test overflows cause by large offset and value size (issue 30245)
regex = (
regex
1
= (
r'
pack_into
requires
a
buffer
of
at
least
' + str(sys.maxsize + 4) +
r'
bytes
for
packing
4
bytes
at
offset
' + str(sys.maxsize) +
r'
\
(
actual
buffer
size
is
10
\
)
'
)
with self.assertRaisesRegex(struct.error, regex):
with self.assertRaisesRegex(struct.error, regex
1
):
struct.pack_into('
<
I
', bytearray(10), sys.maxsize, 1)
regex2 = (
r'
unpack_from
requires
a
buffer
of
at
least
' + str(sys.maxsize + 4) +
r'
bytes
for
unpacking
4
bytes
at
offset
' + str(sys.maxsize) +
r'
\
(
actual
buffer
size
is
10
\
)
'
)
with self.assertRaisesRegex(struct.error, regex2):
struct.unpack_from('
<
I
', bytearray(10), sys.maxsize)
def test_issue29802(self):
# When the second argument of struct.unpack() was of wrong type
# the Struct object was decrefed twice and the reference to
...
...
Misc/NEWS.d/next/Library/2018-03-11-00-20-26.bpo-30249.KSkgLB.rst
0 → 100644
View file @
c10b288f
Improve struct.unpack_from() exception messages for problems with the buffer
size and offset.
Modules/_struct.c
View file @
c10b288f
...
...
@@ -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
);
...
...
Modules/clinic/_struct.c.h
View file @
c10b288f
...
...
@@ -79,7 +79,8 @@ PyDoc_STRVAR(Struct_unpack_from__doc__,
"
\n
"
"Values are unpacked according to the format string Struct.format.
\n
"
"
\n
"
"The buffer
\'
s size in bytes, minus offset, must be at least Struct.size.
\n
"
"The buffer
\'
s size in bytes, starting at position offset, must be
\n
"
"at least Struct.size.
\n
"
"
\n
"
"See help(struct) for more on format strings."
);
...
...
@@ -302,4 +303,4 @@ exit:
return
return_value
;
}
/*[clinic end generated code: output=
9119f213a951e4cc
input=a9049054013a1b77]*/
/*[clinic end generated code: output=
d79b009652ae0b89
input=a9049054013a1b77]*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment