Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
e27337b5
Kaydet (Commit)
e27337b5
authored
May 26, 2006
tarafından
Bob Ippolito
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
fix #1229380 No struct.pack exception for some out of range integers
üst
669fa188
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
13 deletions
+98
-13
test_struct.py
Lib/test/test_struct.py
+5
-3
_struct.c
Modules/_struct.c
+93
-10
No files found.
Lib/test/test_struct.py
Dosyayı görüntüle @
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
Dosyayı görüntüle @
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