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
110d5b50
Commit
110d5b50
authored
Aug 30, 2011
by
Éric Araujo
Browse files
Options
Browse Files
Download
Plain Diff
Branch merge
parents
266e8a19
5fc6f0ad
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
248 additions
and
82 deletions
+248
-82
Lib/pickle.py
Lib/pickle.py
+6
-0
Lib/test/pickletester.py
Lib/test/pickletester.py
+113
-1
Lib/test/support.py
Lib/test/support.py
+6
-5
Lib/test/test_pickle.py
Lib/test/test_pickle.py
+4
-3
Misc/NEWS
Misc/NEWS
+6
-0
Modules/_pickle.c
Modules/_pickle.c
+113
-73
No files found.
Lib/pickle.py
View file @
110d5b50
...
@@ -1156,16 +1156,22 @@ class _Unpickler:
...
@@ -1156,16 +1156,22 @@ class _Unpickler:
def
load_put
(
self
):
def
load_put
(
self
):
i
=
int
(
self
.
readline
()[:
-
1
])
i
=
int
(
self
.
readline
()[:
-
1
])
if
i
<
0
:
raise
ValueError
(
"negative PUT argument"
)
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
dispatch
[
PUT
[
0
]]
=
load_put
dispatch
[
PUT
[
0
]]
=
load_put
def
load_binput
(
self
):
def
load_binput
(
self
):
i
=
self
.
read
(
1
)[
0
]
i
=
self
.
read
(
1
)[
0
]
if
i
<
0
:
raise
ValueError
(
"negative BINPUT argument"
)
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
dispatch
[
BINPUT
[
0
]]
=
load_binput
dispatch
[
BINPUT
[
0
]]
=
load_binput
def
load_long_binput
(
self
):
def
load_long_binput
(
self
):
i
=
mloads
(
b'i'
+
self
.
read
(
4
))
i
=
mloads
(
b'i'
+
self
.
read
(
4
))
if
i
<
0
:
raise
ValueError
(
"negative LONG_BINPUT argument"
)
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
dispatch
[
LONG_BINPUT
[
0
]]
=
load_long_binput
dispatch
[
LONG_BINPUT
[
0
]]
=
load_long_binput
...
...
Lib/test/pickletester.py
View file @
110d5b50
...
@@ -2,10 +2,14 @@ import io
...
@@ -2,10 +2,14 @@ import io
import
unittest
import
unittest
import
pickle
import
pickle
import
pickletools
import
pickletools
import
sys
import
copyreg
import
copyreg
from
http.cookies
import
SimpleCookie
from
http.cookies
import
SimpleCookie
from
test.support
import
TestFailed
,
TESTFN
,
run_with_locale
from
test.support
import
(
TestFailed
,
TESTFN
,
run_with_locale
,
_2G
,
_4G
,
precisionbigmemtest
,
)
from
pickle
import
bytes_types
from
pickle
import
bytes_types
...
@@ -14,6 +18,8 @@ from pickle import bytes_types
...
@@ -14,6 +18,8 @@ from pickle import bytes_types
# kind of outer loop.
# kind of outer loop.
protocols
=
range
(
pickle
.
HIGHEST_PROTOCOL
+
1
)
protocols
=
range
(
pickle
.
HIGHEST_PROTOCOL
+
1
)
character_size
=
4
if
sys
.
maxunicode
>
0xFFFF
else
2
# Return True if opcode code appears in the pickle, else False.
# Return True if opcode code appears in the pickle, else False.
def
opcode_in_pickle
(
code
,
pickle
):
def
opcode_in_pickle
(
code
,
pickle
):
...
@@ -1098,6 +1104,112 @@ class AbstractPickleTests(unittest.TestCase):
...
@@ -1098,6 +1104,112 @@ class AbstractPickleTests(unittest.TestCase):
empty
=
self
.
loads
(
b'
\
x80
\
x03
U
\
x00
q
\
x00
.'
,
encoding
=
'koi8-r'
)
empty
=
self
.
loads
(
b'
\
x80
\
x03
U
\
x00
q
\
x00
.'
,
encoding
=
'koi8-r'
)
self
.
assertEqual
(
empty
,
''
)
self
.
assertEqual
(
empty
,
''
)
def
check_negative_32b_binXXX
(
self
,
dumped
):
if
sys
.
maxsize
>
2
**
32
:
self
.
skipTest
(
"test is only meaningful on 32-bit builds"
)
# XXX Pure Python pickle reads lengths as signed and passes
# them directly to read() (hence the EOFError)
with
self
.
assertRaises
((
pickle
.
UnpicklingError
,
EOFError
,
ValueError
,
OverflowError
)):
self
.
loads
(
dumped
)
def
test_negative_32b_binbytes
(
self
):
# On 32-bit builds, a BINBYTES of 2**31 or more is refused
self
.
check_negative_32b_binXXX
(
b'
\
x80
\
x03
B
\
xff
\
xff
\
xff
\
xff
xyzq
\
x00
.'
)
def
test_negative_32b_binunicode
(
self
):
# On 32-bit builds, a BINUNICODE of 2**31 or more is refused
self
.
check_negative_32b_binXXX
(
b'
\
x80
\
x03
X
\
xff
\
xff
\
xff
\
xff
xyzq
\
x00
.'
)
def
test_negative_put
(
self
):
# Issue #12847
dumped
=
b'Va
\
n
p-1
\
n
.'
self
.
assertRaises
(
ValueError
,
self
.
loads
,
dumped
)
def
test_negative_32b_binput
(
self
):
# Issue #12847
if
sys
.
maxsize
>
2
**
32
:
self
.
skipTest
(
"test is only meaningful on 32-bit builds"
)
dumped
=
b'
\
x80
\
x03
X
\
x01
\
x00
\
x00
\
x00
ar
\
xff
\
xff
\
xff
\
xff
.'
self
.
assertRaises
(
ValueError
,
self
.
loads
,
dumped
)
class
BigmemPickleTests
(
unittest
.
TestCase
):
# Binary protocols can serialize longs of up to 2GB-1
@
precisionbigmemtest
(
size
=
_2G
,
memuse
=
1
+
1
,
dry_run
=
False
)
def
test_huge_long_32b
(
self
,
size
):
data
=
1
<<
(
8
*
size
)
try
:
for
proto
in
protocols
:
if
proto
<
2
:
continue
with
self
.
assertRaises
((
ValueError
,
OverflowError
)):
self
.
dumps
(
data
,
protocol
=
proto
)
finally
:
data
=
None
# Protocol 3 can serialize up to 4GB-1 as a bytes object
# (older protocols don't have a dedicated opcode for bytes and are
# too inefficient)
@
precisionbigmemtest
(
size
=
_2G
,
memuse
=
1
+
1
,
dry_run
=
False
)
def
test_huge_bytes_32b
(
self
,
size
):
data
=
b"abcd"
*
(
size
//
4
)
try
:
for
proto
in
protocols
:
if
proto
<
3
:
continue
try
:
pickled
=
self
.
dumps
(
data
,
protocol
=
proto
)
self
.
assertTrue
(
b"abcd"
in
pickled
[:
15
])
self
.
assertTrue
(
b"abcd"
in
pickled
[
-
15
:])
finally
:
pickled
=
None
finally
:
data
=
None
@
precisionbigmemtest
(
size
=
_4G
,
memuse
=
1
+
1
,
dry_run
=
False
)
def
test_huge_bytes_64b
(
self
,
size
):
data
=
b"a"
*
size
try
:
for
proto
in
protocols
:
if
proto
<
3
:
continue
with
self
.
assertRaises
((
ValueError
,
OverflowError
)):
self
.
dumps
(
data
,
protocol
=
proto
)
finally
:
data
=
None
# All protocols use 1-byte per printable ASCII character; we add another
# byte because the encoded form has to be copied into the internal buffer.
@
precisionbigmemtest
(
size
=
_2G
,
memuse
=
2
+
character_size
,
dry_run
=
False
)
def
test_huge_str_32b
(
self
,
size
):
data
=
"abcd"
*
(
size
//
4
)
try
:
for
proto
in
protocols
:
try
:
pickled
=
self
.
dumps
(
data
,
protocol
=
proto
)
self
.
assertTrue
(
b"abcd"
in
pickled
[:
15
])
self
.
assertTrue
(
b"abcd"
in
pickled
[
-
15
:])
finally
:
pickled
=
None
finally
:
data
=
None
@
precisionbigmemtest
(
size
=
_4G
,
memuse
=
1
+
character_size
,
dry_run
=
False
)
def
test_huge_str_64b
(
self
,
size
):
data
=
"a"
*
size
try
:
for
proto
in
protocols
:
with
self
.
assertRaises
((
ValueError
,
OverflowError
)):
self
.
dumps
(
data
,
protocol
=
proto
)
finally
:
data
=
None
# Test classes for reduce_ex
# Test classes for reduce_ex
class
REX_one
(
object
):
class
REX_one
(
object
):
...
...
Lib/test/support.py
View file @
110d5b50
...
@@ -1089,7 +1089,7 @@ def bigmemtest(minsize, memuse):
...
@@ -1089,7 +1089,7 @@ def bigmemtest(minsize, memuse):
return
wrapper
return
wrapper
return
decorator
return
decorator
def
precisionbigmemtest
(
size
,
memuse
):
def
precisionbigmemtest
(
size
,
memuse
,
dry_run
=
True
):
def
decorator
(
f
):
def
decorator
(
f
):
def
wrapper
(
self
):
def
wrapper
(
self
):
size
=
wrapper
.
size
size
=
wrapper
.
size
...
@@ -1099,10 +1099,11 @@ def precisionbigmemtest(size, memuse):
...
@@ -1099,10 +1099,11 @@ def precisionbigmemtest(size, memuse):
else
:
else
:
maxsize
=
size
maxsize
=
size
if
real_max_memuse
and
real_max_memuse
<
maxsize
*
memuse
:
if
((
real_max_memuse
or
not
dry_run
)
raise
unittest
.
SkipTest
(
and
real_max_memuse
<
maxsize
*
memuse
):
"not enough memory: %.1fG minimum needed"
raise
unittest
.
SkipTest
(
%
(
size
*
memuse
/
(
1024
**
3
)))
"not enough memory: %.1fG minimum needed"
%
(
size
*
memuse
/
(
1024
**
3
)))
return
f
(
self
,
maxsize
)
return
f
(
self
,
maxsize
)
wrapper
.
size
=
size
wrapper
.
size
=
size
...
...
Lib/test/test_pickle.py
View file @
110d5b50
...
@@ -7,6 +7,7 @@ from test.pickletester import AbstractPickleTests
...
@@ -7,6 +7,7 @@ from test.pickletester import AbstractPickleTests
from
test.pickletester
import
AbstractPickleModuleTests
from
test.pickletester
import
AbstractPickleModuleTests
from
test.pickletester
import
AbstractPersistentPicklerTests
from
test.pickletester
import
AbstractPersistentPicklerTests
from
test.pickletester
import
AbstractPicklerUnpicklerObjectTests
from
test.pickletester
import
AbstractPicklerUnpicklerObjectTests
from
test.pickletester
import
BigmemPickleTests
try
:
try
:
import
_pickle
import
_pickle
...
@@ -37,13 +38,13 @@ class PyPicklerTests(AbstractPickleTests):
...
@@ -37,13 +38,13 @@ class PyPicklerTests(AbstractPickleTests):
return
u
.
load
()
return
u
.
load
()
class
InMemoryPickleTests
(
AbstractPickleTests
):
class
InMemoryPickleTests
(
AbstractPickleTests
,
BigmemPickleTests
):
pickler
=
pickle
.
_Pickler
pickler
=
pickle
.
_Pickler
unpickler
=
pickle
.
_Unpickler
unpickler
=
pickle
.
_Unpickler
def
dumps
(
self
,
arg
,
proto
=
None
):
def
dumps
(
self
,
arg
,
proto
col
=
None
):
return
pickle
.
dumps
(
arg
,
proto
)
return
pickle
.
dumps
(
arg
,
proto
col
)
def
loads
(
self
,
buf
,
**
kwds
):
def
loads
(
self
,
buf
,
**
kwds
):
return
pickle
.
loads
(
buf
,
**
kwds
)
return
pickle
.
loads
(
buf
,
**
kwds
)
...
...
Misc/NEWS
View file @
110d5b50
...
@@ -25,6 +25,12 @@ Library
...
@@ -25,6 +25,12 @@ Library
- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi
- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi
now respect a --skip-build option given to bdist.
now respect a --skip-build option given to bdist.
- Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
the C pickle implementation.
- Issue #11564: Avoid crashes when trying to pickle huge objects or containers
(more than 2**31 items). Instead, in most cases, an OverflowError is raised.
- Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is
- Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is
greater than FD_SETSIZE.
greater than FD_SETSIZE.
...
...
Modules/_pickle.c
View file @
110d5b50
...
@@ -153,7 +153,7 @@ typedef struct {
...
@@ -153,7 +153,7 @@ typedef struct {
static
void
static
void
Pdata_dealloc
(
Pdata
*
self
)
Pdata_dealloc
(
Pdata
*
self
)
{
{
in
t
i
=
Py_SIZE
(
self
);
Py_ssize_
t
i
=
Py_SIZE
(
self
);
while
(
--
i
>=
0
)
{
while
(
--
i
>=
0
)
{
Py_DECREF
(
self
->
data
[
i
]);
Py_DECREF
(
self
->
data
[
i
]);
}
}
...
@@ -190,9 +190,9 @@ Pdata_New(void)
...
@@ -190,9 +190,9 @@ Pdata_New(void)
* number of items, this is a (non-erroneous) NOP.
* number of items, this is a (non-erroneous) NOP.
*/
*/
static
int
static
int
Pdata_clear
(
Pdata
*
self
,
in
t
clearto
)
Pdata_clear
(
Pdata
*
self
,
Py_ssize_
t
clearto
)
{
{
in
t
i
=
Py_SIZE
(
self
);
Py_ssize_
t
i
=
Py_SIZE
(
self
);
if
(
clearto
<
0
)
if
(
clearto
<
0
)
return
stack_underflow
();
return
stack_underflow
();
...
@@ -303,7 +303,7 @@ Pdata_poplist(Pdata *self, Py_ssize_t start)
...
@@ -303,7 +303,7 @@ Pdata_poplist(Pdata *self, Py_ssize_t start)
typedef
struct
{
typedef
struct
{
PyObject
*
me_key
;
PyObject
*
me_key
;
long
me_value
;
Py_ssize_t
me_value
;
}
PyMemoEntry
;
}
PyMemoEntry
;
typedef
struct
{
typedef
struct
{
...
@@ -328,7 +328,7 @@ typedef struct PicklerObject {
...
@@ -328,7 +328,7 @@ typedef struct PicklerObject {
Py_ssize_t
max_output_len
;
/* Allocation size of output_buffer. */
Py_ssize_t
max_output_len
;
/* Allocation size of output_buffer. */
int
proto
;
/* Pickle protocol number, >= 0 */
int
proto
;
/* Pickle protocol number, >= 0 */
int
bin
;
/* Boolean, true if proto > 0 */
int
bin
;
/* Boolean, true if proto > 0 */
in
t
buf_size
;
/* Size of the current buffered pickle data */
Py_ssize_
t
buf_size
;
/* Size of the current buffered pickle data */
int
fast
;
/* Enable fast mode if set to a true value.
int
fast
;
/* Enable fast mode if set to a true value.
The fast mode disable the usage of memo,
The fast mode disable the usage of memo,
therefore speeding the pickling process by
therefore speeding the pickling process by
...
@@ -369,7 +369,7 @@ typedef struct UnpicklerObject {
...
@@ -369,7 +369,7 @@ typedef struct UnpicklerObject {
char
*
errors
;
/* Name of errors handling scheme to used when
char
*
errors
;
/* Name of errors handling scheme to used when
decoding strings. The default value is
decoding strings. The default value is
"strict". */
"strict". */
in
t
*
marks
;
/* Mark stack, used for unpickling container
Py_ssize_
t
*
marks
;
/* Mark stack, used for unpickling container
objects. */
objects. */
Py_ssize_t
num_marks
;
/* Number of marks in the mark stack. */
Py_ssize_t
num_marks
;
/* Number of marks in the mark stack. */
Py_ssize_t
marks_size
;
/* Current allocated size of the mark stack. */
Py_ssize_t
marks_size
;
/* Current allocated size of the mark stack. */
...
@@ -556,7 +556,7 @@ _PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size)
...
@@ -556,7 +556,7 @@ _PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size)
}
}
/* Returns NULL on failure, a pointer to the value otherwise. */
/* Returns NULL on failure, a pointer to the value otherwise. */
static
long
*
static
Py_ssize_t
*
PyMemoTable_Get
(
PyMemoTable
*
self
,
PyObject
*
key
)
PyMemoTable_Get
(
PyMemoTable
*
self
,
PyObject
*
key
)
{
{
PyMemoEntry
*
entry
=
_PyMemoTable_Lookup
(
self
,
key
);
PyMemoEntry
*
entry
=
_PyMemoTable_Lookup
(
self
,
key
);
...
@@ -567,7 +567,7 @@ PyMemoTable_Get(PyMemoTable *self, PyObject *key)
...
@@ -567,7 +567,7 @@ PyMemoTable_Get(PyMemoTable *self, PyObject *key)
/* Returns -1 on failure, 0 on success. */
/* Returns -1 on failure, 0 on success. */
static
int
static
int
PyMemoTable_Set
(
PyMemoTable
*
self
,
PyObject
*
key
,
long
value
)
PyMemoTable_Set
(
PyMemoTable
*
self
,
PyObject
*
key
,
Py_ssize_t
value
)
{
{
PyMemoEntry
*
entry
;
PyMemoEntry
*
entry
;
...
@@ -700,7 +700,7 @@ _Pickler_FlushToFile(PicklerObject *self)
...
@@ -700,7 +700,7 @@ _Pickler_FlushToFile(PicklerObject *self)
return
(
result
==
NULL
)
?
-
1
:
0
;
return
(
result
==
NULL
)
?
-
1
:
0
;
}
}
static
in
t
static
Py_ssize_
t
_Pickler_Write
(
PicklerObject
*
self
,
const
char
*
s
,
Py_ssize_t
n
)
_Pickler_Write
(
PicklerObject
*
self
,
const
char
*
s
,
Py_ssize_t
n
)
{
{
Py_ssize_t
i
,
required
;
Py_ssize_t
i
,
required
;
...
@@ -735,7 +735,7 @@ _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t n)
...
@@ -735,7 +735,7 @@ _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t n)
PyErr_NoMemory
();
PyErr_NoMemory
();
return
-
1
;
return
-
1
;
}
}
self
->
max_output_len
=
(
self
->
output_len
+
n
)
*
2
;
self
->
max_output_len
=
(
self
->
output_len
+
n
)
/
2
*
3
;
if
(
_PyBytes_Resize
(
&
self
->
output_buffer
,
self
->
max_output_len
)
<
0
)
if
(
_PyBytes_Resize
(
&
self
->
output_buffer
,
self
->
max_output_len
)
<
0
)
return
-
1
;
return
-
1
;
}
}
...
@@ -1219,9 +1219,9 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self,
...
@@ -1219,9 +1219,9 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self,
static
int
static
int
memo_get
(
PicklerObject
*
self
,
PyObject
*
key
)
memo_get
(
PicklerObject
*
self
,
PyObject
*
key
)
{
{
long
*
value
;
Py_ssize_t
*
value
;
char
pdata
[
30
];
char
pdata
[
30
];
in
t
len
;
Py_ssize_
t
len
;
value
=
PyMemoTable_Get
(
self
->
memo
,
key
);
value
=
PyMemoTable_Get
(
self
->
memo
,
key
);
if
(
value
==
NULL
)
{
if
(
value
==
NULL
)
{
...
@@ -1231,8 +1231,9 @@ memo_get(PicklerObject *self, PyObject *key)
...
@@ -1231,8 +1231,9 @@ memo_get(PicklerObject *self, PyObject *key)
if
(
!
self
->
bin
)
{
if
(
!
self
->
bin
)
{
pdata
[
0
]
=
GET
;
pdata
[
0
]
=
GET
;
PyOS_snprintf
(
pdata
+
1
,
sizeof
(
pdata
)
-
1
,
"%ld
\n
"
,
*
value
);
PyOS_snprintf
(
pdata
+
1
,
sizeof
(
pdata
)
-
1
,
len
=
(
int
)
strlen
(
pdata
);
"%"
PY_FORMAT_SIZE_T
"d
\n
"
,
*
value
);
len
=
strlen
(
pdata
);
}
}
else
{
else
{
if
(
*
value
<
256
)
{
if
(
*
value
<
256
)
{
...
@@ -1266,9 +1267,9 @@ memo_get(PicklerObject *self, PyObject *key)
...
@@ -1266,9 +1267,9 @@ memo_get(PicklerObject *self, PyObject *key)
static
int
static
int
memo_put
(
PicklerObject
*
self
,
PyObject
*
obj
)
memo_put
(
PicklerObject
*
self
,
PyObject
*
obj
)
{
{
long
x
;
Py_ssize_t
x
;
char
pdata
[
30
];
char
pdata
[
30
];
in
t
len
;
Py_ssize_
t
len
;
int
status
=
0
;
int
status
=
0
;
if
(
self
->
fast
)
if
(
self
->
fast
)
...
@@ -1280,7 +1281,8 @@ memo_put(PicklerObject *self, PyObject *obj)
...
@@ -1280,7 +1281,8 @@ memo_put(PicklerObject *self, PyObject *obj)
if
(
!
self
->
bin
)
{
if
(
!
self
->
bin
)
{
pdata
[
0
]
=
PUT
;
pdata
[
0
]
=
PUT
;
PyOS_snprintf
(
pdata
+
1
,
sizeof
(
pdata
)
-
1
,
"%ld
\n
"
,
x
);
PyOS_snprintf
(
pdata
+
1
,
sizeof
(
pdata
)
-
1
,
"%"
PY_FORMAT_SIZE_T
"d
\n
"
,
x
);
len
=
strlen
(
pdata
);
len
=
strlen
(
pdata
);
}
}
else
{
else
{
...
@@ -1482,7 +1484,7 @@ static int
...
@@ -1482,7 +1484,7 @@ static int
save_int
(
PicklerObject
*
self
,
long
x
)
save_int
(
PicklerObject
*
self
,
long
x
)
{
{
char
pdata
[
32
];
char
pdata
[
32
];
in
t
len
=
0
;
Py_ssize_
t
len
=
0
;
if
(
!
self
->
bin
if
(
!
self
->
bin
#if SIZEOF_LONG > 4
#if SIZEOF_LONG > 4
...
@@ -1609,7 +1611,7 @@ save_long(PicklerObject *self, PyObject *obj)
...
@@ -1609,7 +1611,7 @@ save_long(PicklerObject *self, PyObject *obj)
}
}
else
{
else
{
header
[
0
]
=
LONG4
;
header
[
0
]
=
LONG4
;
size
=
(
int
)
nbytes
;
size
=
(
Py_ssize_t
)
nbytes
;
for
(
i
=
1
;
i
<
5
;
i
++
)
{
for
(
i
=
1
;
i
<
5
;
i
++
)
{
header
[
i
]
=
(
unsigned
char
)(
size
&
0xff
);
header
[
i
]
=
(
unsigned
char
)(
size
&
0xff
);
size
>>=
8
;
size
>>=
8
;
...
@@ -1723,7 +1725,7 @@ save_bytes(PicklerObject *self, PyObject *obj)
...
@@ -1723,7 +1725,7 @@ save_bytes(PicklerObject *self, PyObject *obj)
else
{
else
{
Py_ssize_t
size
;
Py_ssize_t
size
;
char
header
[
5
];
char
header
[
5
];
in
t
len
;
Py_ssize_
t
len
;
size
=
PyBytes_Size
(
obj
);
size
=
PyBytes_Size
(
obj
);
if
(
size
<
0
)
if
(
size
<
0
)
...
@@ -1743,6 +1745,8 @@ save_bytes(PicklerObject *self, PyObject *obj)
...
@@ -1743,6 +1745,8 @@ save_bytes(PicklerObject *self, PyObject *obj)
len
=
5
;
len
=
5
;
}
}
else
{
else
{
PyErr_SetString
(
PyExc_OverflowError
,
"cannot serialize a bytes object larger than 4GB"
);
return
-
1
;
/* string too large */
return
-
1
;
/* string too large */
}
}
...
@@ -1867,8 +1871,11 @@ save_unicode(PicklerObject *self, PyObject *obj)
...
@@ -1867,8 +1871,11 @@ save_unicode(PicklerObject *self, PyObject *obj)
goto
error
;
goto
error
;
size
=
PyBytes_GET_SIZE
(
encoded
);
size
=
PyBytes_GET_SIZE
(
encoded
);
if
(
size
<
0
||
size
>
0xffffffffL
)
if
(
size
>
0xffffffffL
)
{
PyErr_SetString
(
PyExc_OverflowError
,
"cannot serialize a string larger than 4GB"
);
goto
error
;
/* string too large */
goto
error
;
/* string too large */
}
pdata
[
0
]
=
BINUNICODE
;
pdata
[
0
]
=
BINUNICODE
;
pdata
[
1
]
=
(
unsigned
char
)(
size
&
0xff
);
pdata
[
1
]
=
(
unsigned
char
)(
size
&
0xff
);
...
@@ -1913,9 +1920,9 @@ save_unicode(PicklerObject *self, PyObject *obj)
...
@@ -1913,9 +1920,9 @@ save_unicode(PicklerObject *self, PyObject *obj)
/* A helper for save_tuple. Push the len elements in tuple t on the stack. */
/* A helper for save_tuple. Push the len elements in tuple t on the stack. */
static
int
static
int
store_tuple_elements
(
PicklerObject
*
self
,
PyObject
*
t
,
in
t
len
)
store_tuple_elements
(
PicklerObject
*
self
,
PyObject
*
t
,
Py_ssize_
t
len
)
{
{
in
t
i
;
Py_ssize_
t
i
;
assert
(
PyTuple_Size
(
t
)
==
len
);
assert
(
PyTuple_Size
(
t
)
==
len
);
...
@@ -1940,7 +1947,7 @@ store_tuple_elements(PicklerObject *self, PyObject *t, int len)
...
@@ -1940,7 +1947,7 @@ store_tuple_elements(PicklerObject *self, PyObject *t, int len)
static
int
static
int
save_tuple
(
PicklerObject
*
self
,
PyObject
*
obj
)
save_tuple
(
PicklerObject
*
self
,
PyObject
*
obj
)
{
{
in
t
len
,
i
;
Py_ssize_
t
len
,
i
;
const
char
mark_op
=
MARK
;
const
char
mark_op
=
MARK
;
const
char
tuple_op
=
TUPLE
;
const
char
tuple_op
=
TUPLE
;
...
@@ -2163,7 +2170,7 @@ static int
...
@@ -2163,7 +2170,7 @@ static int
batch_list_exact
(
PicklerObject
*
self
,
PyObject
*
obj
)
batch_list_exact
(
PicklerObject
*
self
,
PyObject
*
obj
)
{
{
PyObject
*
item
=
NULL
;
PyObject
*
item
=
NULL
;
in
t
this_batch
,
total
;
Py_ssize_
t
this_batch
,
total
;
const
char
append_op
=
APPEND
;
const
char
append_op
=
APPEND
;
const
char
appends_op
=
APPENDS
;
const
char
appends_op
=
APPENDS
;
...
@@ -2208,7 +2215,7 @@ static int
...
@@ -2208,7 +2215,7 @@ static int
save_list
(
PicklerObject
*
self
,
PyObject
*
obj
)
save_list
(
PicklerObject
*
self
,
PyObject
*
obj
)
{
{
char
header
[
3
];
char
header
[
3
];
in
t
len
;
Py_ssize_
t
len
;
int
status
=
0
;
int
status
=
0
;
if
(
self
->
fast
&&
!
fast_save_enter
(
self
,
obj
))
if
(
self
->
fast
&&
!
fast_save_enter
(
self
,
obj
))
...
@@ -2468,7 +2475,7 @@ save_dict(PicklerObject *self, PyObject *obj)
...
@@ -2468,7 +2475,7 @@ save_dict(PicklerObject *self, PyObject *obj)
{
{
PyObject
*
items
,
*
iter
;
PyObject
*
items
,
*
iter
;
char
header
[
3
];
char
header
[
3
];
in
t
len
;
Py_ssize_
t
len
;
int
status
=
0
;
int
status
=
0
;
if
(
self
->
fast
&&
!
fast_save_enter
(
self
,
obj
))
if
(
self
->
fast
&&
!
fast_save_enter
(
self
,
obj
))
...
@@ -2603,7 +2610,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
...
@@ -2603,7 +2610,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
PyObject
*
code_obj
;
/* extension code as Python object */
PyObject
*
code_obj
;
/* extension code as Python object */
long
code
;
/* extension code as C value */
long
code
;
/* extension code as C value */
char
pdata
[
5
];
char
pdata
[
5
];
in
t
n
;
Py_ssize_
t
n
;
PyTuple_SET_ITEM
(
two_tuple
,
0
,
module_name
);
PyTuple_SET_ITEM
(
two_tuple
,
0
,
module_name
);
PyTuple_SET_ITEM
(
two_tuple
,
1
,
global_name
);
PyTuple_SET_ITEM
(
two_tuple
,
1
,
global_name
);
...
@@ -2626,9 +2633,10 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
...
@@ -2626,9 +2633,10 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
}
}
code
=
PyLong_AS_LONG
(
code_obj
);
code
=
PyLong_AS_LONG
(
code_obj
);
if
(
code
<=
0
||
code
>
0x7fffffffL
)
{
if
(
code
<=
0
||
code
>
0x7fffffffL
)
{
PyErr_Format
(
PicklingError
,
if
(
!
PyErr_Occurred
())
"Can't pickle %R: extension code %ld is out of range"
,
PyErr_Format
(
PicklingError
,
obj
,
code
);
"Can't pickle %R: extension code %ld is out of range"
,
obj
,
code
);
goto
error
;
goto
error
;
}
}
...
@@ -3477,7 +3485,7 @@ pmp_copy(PicklerMemoProxyObject *self)
...
@@ -3477,7 +3485,7 @@ pmp_copy(PicklerMemoProxyObject *self)
PyObject
*
key
,
*
value
;
PyObject
*
key
,
*
value
;
key
=
PyLong_FromVoidPtr
(
entry
.
me_key
);
key
=
PyLong_FromVoidPtr
(
entry
.
me_key
);
value
=
Py_BuildValue
(
"
l
O"
,
entry
.
me_value
,
entry
.
me_key
);
value
=
Py_BuildValue
(
"
n
O"
,
entry
.
me_value
,
entry
.
me_key
);
if
(
key
==
NULL
||
value
==
NULL
)
{
if
(
key
==
NULL
||
value
==
NULL
)
{
Py_XDECREF
(
key
);
Py_XDECREF
(
key
);
...
@@ -3638,7 +3646,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
...
@@ -3638,7 +3646,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
return
-
1
;
return
-
1
;
while
(
PyDict_Next
(
obj
,
&
i
,
&
key
,
&
value
))
{
while
(
PyDict_Next
(
obj
,
&
i
,
&
key
,
&
value
))
{
long
memo_id
;
Py_ssize_t
memo_id
;
PyObject
*
memo_obj
;
PyObject
*
memo_obj
;
if
(
!
PyTuple_Check
(
value
)
||
Py_SIZE
(
value
)
!=
2
)
{
if
(
!
PyTuple_Check
(
value
)
||
Py_SIZE
(
value
)
!=
2
)
{
...
@@ -3646,7 +3654,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
...
@@ -3646,7 +3654,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
"'memo' values must be 2-item tuples"
);
"'memo' values must be 2-item tuples"
);
goto
error
;
goto
error
;
}
}
memo_id
=
PyLong_As
Long
(
PyTuple_GET_ITEM
(
value
,
0
));
memo_id
=
PyLong_As
Ssize_t
(
PyTuple_GET_ITEM
(
value
,
0
));
if
(
memo_id
==
-
1
&&
PyErr_Occurred
())
if
(
memo_id
==
-
1
&&
PyErr_Occurred
())
goto
error
;
goto
error
;
memo_obj
=
PyTuple_GET_ITEM
(
value
,
1
);
memo_obj
=
PyTuple_GET_ITEM
(
value
,
1
);
...
@@ -3777,7 +3785,7 @@ find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
...
@@ -3777,7 +3785,7 @@ find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
module_name
,
global_name
);
module_name
,
global_name
);
}
}
static
in
t
static
Py_ssize_
t
marker
(
UnpicklerObject
*
self
)
marker
(
UnpicklerObject
*
self
)
{
{
if
(
self
->
num_marks
<
1
)
{
if
(
self
->
num_marks
<
1
)
{
...
@@ -3855,6 +3863,28 @@ load_bool(UnpicklerObject *self, PyObject *boolean)
...
@@ -3855,6 +3863,28 @@ load_bool(UnpicklerObject *self, PyObject *boolean)
return
0
;
return
0
;
}
}
/* s contains x bytes of an unsigned little-endian integer. Return its value
* as a C Py_ssize_t, or -1 if it's higher than PY_SSIZE_T_MAX.
*/
static
Py_ssize_t
calc_binsize
(
char
*
bytes
,
int
size
)
{
unsigned
char
*
s
=
(
unsigned
char
*
)
bytes
;
size_t
x
=
0
;
assert
(
size
==
4
);
x
=
(
size_t
)
s
[
0
];
x
|=
(
size_t
)
s
[
1
]
<<
8
;
x
|=
(
size_t
)
s
[
2
]
<<
16
;
x
|=
(
size_t
)
s
[
3
]
<<
24
;
if
(
x
>
PY_SSIZE_T_MAX
)
return
-
1
;
else
return
(
Py_ssize_t
)
x
;
}
/* s contains x bytes of a little-endian integer. Return its value as a
/* s contains x bytes of a little-endian integer. Return its value as a
* C int. Obscure: when x is 1 or 2, this is an unsigned little-endian
* C int. Obscure: when x is 1 or 2, this is an unsigned little-endian
* int, but when x is 4 it's a signed one. This is an historical source
* int, but when x is 4 it's a signed one. This is an historical source
...
@@ -4099,16 +4129,18 @@ static int
...
@@ -4099,16 +4129,18 @@ static int
load_binbytes
(
UnpicklerObject
*
self
)
load_binbytes
(
UnpicklerObject
*
self
)
{
{
PyObject
*
bytes
;
PyObject
*
bytes
;
long
x
;
Py_ssize_t
x
;
char
*
s
;
char
*
s
;
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
return
-
1
;
return
-
1
;
x
=
calc_bin
int
(
s
,
4
);
x
=
calc_bin
size
(
s
,
4
);
if
(
x
<
0
)
{
if
(
x
<
0
)
{
PyErr_SetString
(
UnpicklingError
,
PyErr_Format
(
PyExc_OverflowError
,
"BINBYTES pickle has negative byte count"
);
"BINBYTES exceeds system's maximum size of %zd bytes"
,
PY_SSIZE_T_MAX
);
return
-
1
;
return
-
1
;
}
}
...
@@ -4126,7 +4158,7 @@ static int
...
@@ -4126,7 +4158,7 @@ static int
load_short_binbytes
(
UnpicklerObject
*
self
)
load_short_binbytes
(
UnpicklerObject
*
self
)
{
{
PyObject
*
bytes
;
PyObject
*
bytes
;
unsigned
char
x
;
Py_ssize_t
x
;
char
*
s
;
char
*
s
;
if
(
_Unpickler_Read
(
self
,
&
s
,
1
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
1
)
<
0
)
...
@@ -4149,7 +4181,7 @@ static int
...
@@ -4149,7 +4181,7 @@ static int
load_binstring
(
UnpicklerObject
*
self
)
load_binstring
(
UnpicklerObject
*
self
)
{
{
PyObject
*
str
;
PyObject
*
str
;
long
x
;
Py_ssize_t
x
;
char
*
s
;
char
*
s
;
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
...
@@ -4178,7 +4210,7 @@ static int
...
@@ -4178,7 +4210,7 @@ static int
load_short_binstring
(
UnpicklerObject
*
self
)
load_short_binstring
(
UnpicklerObject
*
self
)
{
{
PyObject
*
str
;
PyObject
*
str
;
unsigned
char
x
;
Py_ssize_t
x
;
char
*
s
;
char
*
s
;
if
(
_Unpickler_Read
(
self
,
&
s
,
1
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
1
)
<
0
)
...
@@ -4222,19 +4254,22 @@ static int
...
@@ -4222,19 +4254,22 @@ static int
load_binunicode
(
UnpicklerObject
*
self
)
load_binunicode
(
UnpicklerObject
*
self
)
{
{
PyObject
*
str
;
PyObject
*
str
;
long
size
;
Py_ssize_t
size
;
char
*
s
;
char
*
s
;
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
return
-
1
;
return
-
1
;
size
=
calc_bin
int
(
s
,
4
);
size
=
calc_bin
size
(
s
,
4
);
if
(
size
<
0
)
{
if
(
size
<
0
)
{
PyErr_SetString
(
UnpicklingError
,
PyErr_Format
(
PyExc_OverflowError
,
"BINUNICODE pickle has negative byte count"
);
"BINUNICODE exceeds system's maximum size of %zd bytes"
,
PY_SSIZE_T_MAX
);
return
-
1
;
return
-
1
;
}
}
if
(
_Unpickler_Read
(
self
,
&
s
,
size
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
size
)
<
0
)
return
-
1
;
return
-
1
;
...
@@ -4250,7 +4285,7 @@ static int
...
@@ -4250,7 +4285,7 @@ static int
load_tuple
(
UnpicklerObject
*
self
)
load_tuple
(
UnpicklerObject
*
self
)
{
{
PyObject
*
tuple
;
PyObject
*
tuple
;
in
t
i
;
Py_ssize_
t
i
;
if
((
i
=
marker
(
self
))
<
0
)
if
((
i
=
marker
(
self
))
<
0
)
return
-
1
;
return
-
1
;
...
@@ -4309,7 +4344,7 @@ static int
...
@@ -4309,7 +4344,7 @@ static int
load_list
(
UnpicklerObject
*
self
)
load_list
(
UnpicklerObject
*
self
)
{
{
PyObject
*
list
;
PyObject
*
list
;
in
t
i
;
Py_ssize_
t
i
;
if
((
i
=
marker
(
self
))
<
0
)
if
((
i
=
marker
(
self
))
<
0
)
return
-
1
;
return
-
1
;
...
@@ -4325,7 +4360,7 @@ static int
...
@@ -4325,7 +4360,7 @@ static int
load_dict
(
UnpicklerObject
*
self
)
load_dict
(
UnpicklerObject
*
self
)
{
{
PyObject
*
dict
,
*
key
,
*
value
;
PyObject
*
dict
,
*
key
,
*
value
;
in
t
i
,
j
,
k
;
Py_ssize_
t
i
,
j
,
k
;
if
((
i
=
marker
(
self
))
<
0
)
if
((
i
=
marker
(
self
))
<
0
)
return
-
1
;
return
-
1
;
...
@@ -4369,7 +4404,7 @@ static int
...
@@ -4369,7 +4404,7 @@ static int
load_obj
(
UnpicklerObject
*
self
)
load_obj
(
UnpicklerObject
*
self
)
{
{
PyObject
*
cls
,
*
args
,
*
obj
=
NULL
;
PyObject
*
cls
,
*
args
,
*
obj
=
NULL
;
in
t
i
;
Py_ssize_
t
i
;
if
((
i
=
marker
(
self
))
<
0
)
if
((
i
=
marker
(
self
))
<
0
)
return
-
1
;
return
-
1
;
...
@@ -4400,7 +4435,7 @@ load_inst(UnpicklerObject *self)
...
@@ -4400,7 +4435,7 @@ load_inst(UnpicklerObject *self)
PyObject
*
module_name
;
PyObject
*
module_name
;
PyObject
*
class_name
;
PyObject
*
class_name
;
Py_ssize_t
len
;
Py_ssize_t
len
;
in
t
i
;
Py_ssize_
t
i
;
char
*
s
;
char
*
s
;
if
((
i
=
marker
(
self
))
<
0
)
if
((
i
=
marker
(
self
))
<
0
)
...
@@ -4594,7 +4629,7 @@ load_binpersid(UnpicklerObject *self)
...
@@ -4594,7 +4629,7 @@ load_binpersid(UnpicklerObject *self)
static
int
static
int
load_pop
(
UnpicklerObject
*
self
)
load_pop
(
UnpicklerObject
*
self
)
{
{
in
t
len
=
Py_SIZE
(
self
->
stack
);
Py_ssize_
t
len
=
Py_SIZE
(
self
->
stack
);
/* Note that we split the (pickle.py) stack into two stacks,
/* Note that we split the (pickle.py) stack into two stacks,
* an object stack and a mark stack. We have to be clever and
* an object stack and a mark stack. We have to be clever and
...
@@ -4618,7 +4653,7 @@ load_pop(UnpicklerObject *self)
...
@@ -4618,7 +4653,7 @@ load_pop(UnpicklerObject *self)
static
int
static
int
load_pop_mark
(
UnpicklerObject
*
self
)
load_pop_mark
(
UnpicklerObject
*
self
)
{
{
in
t
i
;
Py_ssize_
t
i
;
if
((
i
=
marker
(
self
))
<
0
)
if
((
i
=
marker
(
self
))
<
0
)
return
-
1
;
return
-
1
;
...
@@ -4632,7 +4667,7 @@ static int
...
@@ -4632,7 +4667,7 @@ static int
load_dup
(
UnpicklerObject
*
self
)
load_dup
(
UnpicklerObject
*
self
)
{
{
PyObject
*
last
;
PyObject
*
last
;
in
t
len
;
Py_ssize_
t
len
;
if
((
len
=
Py_SIZE
(
self
->
stack
))
<=
0
)
if
((
len
=
Py_SIZE
(
self
->
stack
))
<=
0
)
return
stack_underflow
();
return
stack_underflow
();
...
@@ -4711,10 +4746,7 @@ load_long_binget(UnpicklerObject *self)
...
@@ -4711,10 +4746,7 @@ load_long_binget(UnpicklerObject *self)
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
if
(
_Unpickler_Read
(
self
,
&
s
,
4
)
<
0
)
return
-
1
;
return
-
1
;
idx
=
(
long
)
Py_CHARMASK
(
s
[
0
]);
idx
=
calc_binsize
(
s
,
4
);
idx
|=
(
long
)
Py_CHARMASK
(
s
[
1
])
<<
8
;
idx
|=
(
long
)
Py_CHARMASK
(
s
[
2
])
<<
16
;
idx
|=
(
long
)
Py_CHARMASK
(
s
[
3
])
<<
24
;
value
=
_Unpickler_MemoGet
(
self
,
idx
);
value
=
_Unpickler_MemoGet
(
self
,
idx
);
if
(
value
==
NULL
)
{
if
(
value
==
NULL
)
{
...
@@ -4821,8 +4853,12 @@ load_put(UnpicklerObject *self)
...
@@ -4821,8 +4853,12 @@ load_put(UnpicklerObject *self)
return
-
1
;
return
-
1
;
idx
=
PyLong_AsSsize_t
(
key
);
idx
=
PyLong_AsSsize_t
(
key
);
Py_DECREF
(
key
);
Py_DECREF
(
key
);
if
(
idx
==
-
1
&&
PyErr_Occurred
())
if
(
idx
<
0
)
{
if
(
!
PyErr_Occurred
())
PyErr_SetString
(
PyExc_ValueError
,
"negative PUT argument"
);
return
-
1
;
return
-
1
;
}
return
_Unpickler_MemoPut
(
self
,
idx
,
value
);
return
_Unpickler_MemoPut
(
self
,
idx
,
value
);
}
}
...
@@ -4860,20 +4896,22 @@ load_long_binput(UnpicklerObject *self)
...
@@ -4860,20 +4896,22 @@ load_long_binput(UnpicklerObject *self)
return
stack_underflow
();
return
stack_underflow
();
value
=
self
->
stack
->
data
[
Py_SIZE
(
self
->
stack
)
-
1
];
value
=
self
->
stack
->
data
[
Py_SIZE
(
self
->
stack
)
-
1
];
idx
=
(
long
)
Py_CHARMASK
(
s
[
0
]);
idx
=
calc_binsize
(
s
,
4
);
idx
|=
(
long
)
Py_CHARMASK
(
s
[
1
])
<<
8
;
if
(
idx
<
0
)
{
idx
|=
(
long
)
Py_CHARMASK
(
s
[
2
])
<<
16
;
PyErr_SetString
(
PyExc_ValueError
,
idx
|=
(
long
)
Py_CHARMASK
(
s
[
3
])
<<
24
;
"negative LONG_BINPUT argument"
);
return
-
1
;
}
return
_Unpickler_MemoPut
(
self
,
idx
,
value
);
return
_Unpickler_MemoPut
(
self
,
idx
,
value
);
}
}
static
int
static
int
do_append
(
UnpicklerObject
*
self
,
in
t
x
)
do_append
(
UnpicklerObject
*
self
,
Py_ssize_
t
x
)
{
{
PyObject
*
value
;
PyObject
*
value
;
PyObject
*
list
;
PyObject
*
list
;
in
t
len
,
i
;
Py_ssize_
t
len
,
i
;
len
=
Py_SIZE
(
self
->
stack
);
len
=
Py_SIZE
(
self
->
stack
);
if
(
x
>
len
||
x
<=
0
)
if
(
x
>
len
||
x
<=
0
)
...
@@ -4886,14 +4924,15 @@ do_append(UnpicklerObject *self, int x)
...
@@ -4886,14 +4924,15 @@ do_append(UnpicklerObject *self, int x)
if
(
PyList_Check
(
list
))
{
if
(
PyList_Check
(
list
))
{
PyObject
*
slice
;
PyObject
*
slice
;
Py_ssize_t
list_len
;
Py_ssize_t
list_len
;
int
ret
;
slice
=
Pdata_poplist
(
self
->
stack
,
x
);
slice
=
Pdata_poplist
(
self
->
stack
,
x
);
if
(
!
slice
)
if
(
!
slice
)
return
-
1
;
return
-
1
;
list_len
=
PyList_GET_SIZE
(
list
);
list_len
=
PyList_GET_SIZE
(
list
);
i
=
PyList_SetSlice
(
list
,
list_len
,
list_len
,
slice
);
ret
=
PyList_SetSlice
(
list
,
list_len
,
list_len
,
slice
);
Py_DECREF
(
slice
);
Py_DECREF
(
slice
);
return
i
;
return
ret
;
}
}
else
{
else
{
PyObject
*
append_func
;
PyObject
*
append_func
;
...
@@ -4932,11 +4971,11 @@ load_appends(UnpicklerObject *self)
...
@@ -4932,11 +4971,11 @@ load_appends(UnpicklerObject *self)
}
}
static
int
static
int
do_setitems
(
UnpicklerObject
*
self
,
in
t
x
)
do_setitems
(
UnpicklerObject
*
self
,
Py_ssize_
t
x
)
{
{
PyObject
*
value
,
*
key
;
PyObject
*
value
,
*
key
;
PyObject
*
dict
;
PyObject
*
dict
;
in
t
len
,
i
;
Py_ssize_
t
len
,
i
;
int
status
=
0
;
int
status
=
0
;
len
=
Py_SIZE
(
self
->
stack
);
len
=
Py_SIZE
(
self
->
stack
);
...
@@ -5104,20 +5143,21 @@ load_mark(UnpicklerObject *self)
...
@@ -5104,20 +5143,21 @@ load_mark(UnpicklerObject *self)
if
((
self
->
num_marks
+
1
)
>=
self
->
marks_size
)
{
if
((
self
->
num_marks
+
1
)
>=
self
->
marks_size
)
{
size_t
alloc
;
size_t
alloc
;
in
t
*
marks
;
Py_ssize_
t
*
marks
;
/* Use the size_t type to check for overflow. */
/* Use the size_t type to check for overflow. */
alloc
=
((
size_t
)
self
->
num_marks
<<
1
)
+
20
;
alloc
=
((
size_t
)
self
->
num_marks
<<
1
)
+
20
;
if
(
alloc
>
PY_SSIZE_T_MAX
||
if
(
alloc
>
(
PY_SSIZE_T_MAX
/
sizeof
(
Py_ssize_t
))
||
alloc
<=
((
size_t
)
self
->
num_marks
+
1
))
{
alloc
<=
((
size_t
)
self
->
num_marks
+
1
))
{
PyErr_NoMemory
();
PyErr_NoMemory
();
return
-
1
;
return
-
1
;
}
}
if
(
self
->
marks
==
NULL
)
if
(
self
->
marks
==
NULL
)
marks
=
(
int
*
)
PyMem_Malloc
(
alloc
*
sizeof
(
in
t
));
marks
=
(
Py_ssize_t
*
)
PyMem_Malloc
(
alloc
*
sizeof
(
Py_ssize_
t
));
else
else
marks
=
(
int
*
)
PyMem_Realloc
(
self
->
marks
,
alloc
*
sizeof
(
int
));
marks
=
(
Py_ssize_t
*
)
PyMem_Realloc
(
self
->
marks
,
alloc
*
sizeof
(
Py_ssize_t
));
if
(
marks
==
NULL
)
{
if
(
marks
==
NULL
)
{
PyErr_NoMemory
();
PyErr_NoMemory
();
return
-
1
;
return
-
1
;
...
...
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