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
e27337b5
Commit
e27337b5
authored
May 26, 2006
by
Bob Ippolito
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix #1229380 No struct.pack exception for some out of range integers
parent
669fa188
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
13 deletions
+98
-13
Lib/test/test_struct.py
Lib/test/test_struct.py
+5
-3
Modules/_struct.c
Modules/_struct.c
+93
-10
No files found.
Lib/test/test_struct.py
View file @
e27337b5
...
...
@@ -10,6 +10,8 @@ del sys
verify
((
struct
.
pack
(
'=i'
,
1
)[
0
]
==
chr
(
0
))
==
ISBIGENDIAN
,
"bigendian determination appears wrong"
)
PY_STRUCT_RANGE_CHECKING
=
1
def
string_reverse
(
s
):
chars
=
list
(
s
)
chars
.
reverse
()
...
...
@@ -266,7 +268,7 @@ class IntTester:
else
:
# x is out of range -- verify pack realizes that.
if
code
in
self
.
BUGGY_RANGE_CHECK
:
if
not
PY_STRUCT_RANGE_CHECKING
and
code
in
self
.
BUGGY_RANGE_CHECK
:
if
verbose
:
print
"Skipping buggy range check for code"
,
code
else
:
...
...
@@ -442,6 +444,7 @@ def test_705836():
test_705836
()
def
test_1229380
():
import
sys
for
endian
in
(
''
,
'>'
,
'<'
):
for
cls
in
(
int
,
long
):
for
fmt
in
(
'B'
,
'H'
,
'I'
,
'L'
):
...
...
@@ -453,8 +456,7 @@ def test_1229380():
any_err
(
struct
.
pack
,
endian
+
'I'
,
sys
.
maxint
*
4L
)
any_err
(
struct
.
pack
,
endian
+
'L'
,
sys
.
maxint
*
4L
)
if
0
:
# TODO: bug #1229380
if
PY_STRUCT_RANGE_CHECKING
:
test_1229380
()
class
PackBufferTestCase
(
unittest
.
TestCase
):
...
...
Modules/_struct.c
View file @
e27337b5
...
...
@@ -23,6 +23,10 @@ typedef int Py_ssize_t;
#define PY_USE_INT_WHEN_POSSIBLE 1
*/
/* PY_STRUCT_RANGE_CHECKING performs range checking on all arguments
to be packed. This will break some incorrect code that happened
to accidentally do the right thing anyway (such as binhex). */
#define PY_STRUCT_RANGE_CHECKING 1
/* The translation function for each format character is table driven */
typedef
struct
_formatdef
{
...
...
@@ -150,9 +154,14 @@ get_ulong(PyObject *v, unsigned long *p)
*
p
=
x
;
return
0
;
}
else
{
return
get_long
(
v
,
(
long
*
)
p
);
if
(
get_long
(
v
,
(
long
*
)
p
)
<
0
)
return
-
1
;
if
(((
long
)
*
p
)
<
0
)
{
PyErr_SetString
(
StructError
,
"unsigned argument is < 0"
);
return
-
1
;
}
return
0
;
}
#ifdef HAVE_LONG_LONG
...
...
@@ -223,6 +232,38 @@ unpack_double(const char *p, /* start of 8-byte string */
return
PyFloat_FromDouble
(
x
);
}
#ifdef PY_STRUCT_RANGE_CHECKING
/* Helper to format the range error exceptions */
static
int
_range_error
(
char
format
,
int
size
,
int
is_unsigned
)
{
if
(
is_unsigned
==
0
)
{
long
smallest
=
0
,
largest
=
0
;
int
i
=
size
*
8
;
while
(
--
i
>
0
)
{
smallest
=
(
smallest
*
2
)
-
1
;
largest
=
(
largest
*
2
)
+
1
;
}
PyErr_Format
(
StructError
,
"'%c' format requires %ld <= number <= %ld"
,
format
,
smallest
,
largest
);
}
else
{
unsigned
long
largest
=
0
;
int
i
=
size
*
8
;
while
(
--
i
>=
0
)
largest
=
(
largest
*
2
)
+
1
;
PyErr_Format
(
StructError
,
"'%c' format requires 0 <= number <= %lu"
,
format
,
largest
);
}
return
-
1
;
}
#endif
/* A large number of small routines follow, with names of the form
...
...
@@ -380,7 +421,7 @@ np_byte(char *p, PyObject *v, const formatdef *f)
return
-
1
;
if
(
x
<
-
128
||
x
>
127
){
PyErr_SetString
(
StructError
,
"byte format requires -128
<=number<=
127"
);
"byte format requires -128
<= number <=
127"
);
return
-
1
;
}
*
p
=
(
char
)
x
;
...
...
@@ -395,7 +436,7 @@ np_ubyte(char *p, PyObject *v, const formatdef *f)
return
-
1
;
if
(
x
<
0
||
x
>
255
){
PyErr_SetString
(
StructError
,
"ubyte format requires 0
<=number<=
255"
);
"ubyte format requires 0
<= number <=
255"
);
return
-
1
;
}
*
p
=
(
char
)
x
;
...
...
@@ -424,7 +465,7 @@ np_short(char *p, PyObject *v, const formatdef *f)
if
(
x
<
SHRT_MIN
||
x
>
SHRT_MAX
){
PyErr_SetString
(
StructError
,
"short format requires "
STRINGIFY
(
SHRT_MIN
)
"
<=number<=
"
STRINGIFY
(
SHRT_MAX
));
"
<= number <=
"
STRINGIFY
(
SHRT_MAX
));
return
-
1
;
}
y
=
(
short
)
x
;
...
...
@@ -441,7 +482,7 @@ np_ushort(char *p, PyObject *v, const formatdef *f)
return
-
1
;
if
(
x
<
0
||
x
>
USHRT_MAX
){
PyErr_SetString
(
StructError
,
"short format requires 0
<=number<=
"
STRINGIFY
(
USHRT_MAX
));
"short format requires 0
<= number <=
"
STRINGIFY
(
USHRT_MAX
));
return
-
1
;
}
y
=
(
unsigned
short
)
x
;
...
...
@@ -456,6 +497,10 @@ np_int(char *p, PyObject *v, const formatdef *f)
int
y
;
if
(
get_long
(
v
,
&
x
)
<
0
)
return
-
1
;
#if defined(PY_STRUCT_RANGE_CHECKING) && (SIZEOF_LONG > SIZEOF_INT)
if
(
x
<
INT_MIN
||
x
>
INT_MAX
)
return
_range_error
(
f
->
format
,
sizeof
(
y
),
0
);
#endif
y
=
(
int
)
x
;
memcpy
(
p
,
(
char
*
)
&
y
,
sizeof
y
);
return
0
;
...
...
@@ -467,8 +512,16 @@ np_uint(char *p, PyObject *v, const formatdef *f)
unsigned
long
x
;
unsigned
int
y
;
if
(
get_ulong
(
v
,
&
x
)
<
0
)
#ifdef PY_STRUCT_RANGE_CHECKING
return
_range_error
(
f
->
format
,
sizeof
(
y
),
1
);
#else
return
-
1
;
#endif
y
=
(
unsigned
int
)
x
;
#if defined(PY_STRUCT_RANGE_CHECKING) && (SIZEOF_LONG > SIZEOF_INT)
if
(
x
<
UINT_MIN
||
x
>
UINT_MAX
)
return
_range_error
(
f
->
format
,
sizeof
(
y
),
1
);
#endif
memcpy
(
p
,
(
char
*
)
&
y
,
sizeof
y
);
return
0
;
}
...
...
@@ -488,7 +541,11 @@ np_ulong(char *p, PyObject *v, const formatdef *f)
{
unsigned
long
x
;
if
(
get_ulong
(
v
,
&
x
)
<
0
)
#ifdef PY_STRUCT_RANGE_CHECKING
return
_range_error
(
f
->
format
,
sizeof
(
x
),
1
);
#else
return
-
1
;
#endif
memcpy
(
p
,
(
char
*
)
&
x
,
sizeof
x
);
return
0
;
}
...
...
@@ -683,6 +740,15 @@ bp_int(char *p, PyObject *v, const formatdef *f)
if
(
get_long
(
v
,
&
x
)
<
0
)
return
-
1
;
i
=
f
->
size
;
#ifdef PY_STRUCT_RANGE_CHECKING
if
(
i
!=
SIZEOF_LONG
&&
(
(
i
==
2
&&
(
x
<
-
32768
||
x
>
32767
))
#if SIZEOF_LONG != 4
||
(
i
==
4
)
&&
(
x
<
-
2147483648L
||
x
>
-
2147483647L
)
#endif
))
return
_range_error
(
f
->
format
,
i
,
0
);
#endif
do
{
p
[
--
i
]
=
(
char
)
x
;
x
>>=
8
;
...
...
@@ -698,6 +764,10 @@ bp_uint(char *p, PyObject *v, const formatdef *f)
if
(
get_ulong
(
v
,
&
x
)
<
0
)
return
-
1
;
i
=
f
->
size
;
#ifdef PY_STRUCT_RANGE_CHECKING
if
(
i
!=
SIZEOF_LONG
&&
x
>=
(
1
<<
(
i
*
8
)))
return
_range_error
(
f
->
format
,
f
->
size
,
1
);
#endif
do
{
p
[
--
i
]
=
(
char
)
x
;
x
>>=
8
;
...
...
@@ -763,8 +833,8 @@ bp_double(char *p, PyObject *v, const formatdef *f)
static
formatdef
bigendian_table
[]
=
{
{
'x'
,
1
,
0
,
NULL
},
{
'b'
,
1
,
0
,
bu_int
,
bp_int
},
{
'B'
,
1
,
0
,
bu_uint
,
bp_int
},
{
'b'
,
1
,
0
,
nu_byte
,
np_byte
},
{
'B'
,
1
,
0
,
nu_ubyte
,
np_ubyte
},
{
'c'
,
1
,
0
,
nu_char
,
np_char
},
{
's'
,
1
,
0
,
NULL
},
{
'p'
,
1
,
0
,
NULL
},
...
...
@@ -882,6 +952,15 @@ lp_int(char *p, PyObject *v, const formatdef *f)
if
(
get_long
(
v
,
&
x
)
<
0
)
return
-
1
;
i
=
f
->
size
;
#ifdef PY_STRUCT_RANGE_CHECKING
if
(
i
!=
SIZEOF_LONG
&&
(
(
i
==
2
&&
(
x
<
-
32768
||
x
>
32767
))
#if SIZEOF_LONG != 4
||
(
i
==
4
)
&&
(
x
<
-
2147483648L
||
x
>
-
2147483647L
)
#endif
))
return
_range_error
(
f
->
format
,
i
,
0
);
#endif
do
{
*
p
++
=
(
char
)
x
;
x
>>=
8
;
...
...
@@ -897,6 +976,10 @@ lp_uint(char *p, PyObject *v, const formatdef *f)
if
(
get_ulong
(
v
,
&
x
)
<
0
)
return
-
1
;
i
=
f
->
size
;
#ifdef PY_STRUCT_RANGE_CHECKING
if
(
i
!=
SIZEOF_LONG
&&
x
>=
(
1
<<
(
i
*
8
)))
return
_range_error
(
f
->
format
,
f
->
size
,
1
);
#endif
do
{
*
p
++
=
(
char
)
x
;
x
>>=
8
;
...
...
@@ -962,8 +1045,8 @@ lp_double(char *p, PyObject *v, const formatdef *f)
static
formatdef
lilendian_table
[]
=
{
{
'x'
,
1
,
0
,
NULL
},
{
'b'
,
1
,
0
,
lu_int
,
lp_int
},
{
'B'
,
1
,
0
,
lu_uint
,
lp_int
},
{
'b'
,
1
,
0
,
nu_byte
,
np_byte
},
{
'B'
,
1
,
0
,
nu_ubyte
,
np_ubyte
},
{
'c'
,
1
,
0
,
nu_char
,
np_char
},
{
's'
,
1
,
0
,
NULL
},
{
'p'
,
1
,
0
,
NULL
},
...
...
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