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
Expand all
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:
def
load_put
(
self
):
i
=
int
(
self
.
readline
()[:
-
1
])
if
i
<
0
:
raise
ValueError
(
"negative PUT argument"
)
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
dispatch
[
PUT
[
0
]]
=
load_put
def
load_binput
(
self
):
i
=
self
.
read
(
1
)[
0
]
if
i
<
0
:
raise
ValueError
(
"negative BINPUT argument"
)
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
dispatch
[
BINPUT
[
0
]]
=
load_binput
def
load_long_binput
(
self
):
i
=
mloads
(
b'i'
+
self
.
read
(
4
))
if
i
<
0
:
raise
ValueError
(
"negative LONG_BINPUT argument"
)
self
.
memo
[
i
]
=
self
.
stack
[
-
1
]
dispatch
[
LONG_BINPUT
[
0
]]
=
load_long_binput
...
...
Lib/test/pickletester.py
View file @
110d5b50
...
...
@@ -2,10 +2,14 @@ import io
import
unittest
import
pickle
import
pickletools
import
sys
import
copyreg
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
...
...
@@ -14,6 +18,8 @@ from pickle import bytes_types
# kind of outer loop.
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.
def
opcode_in_pickle
(
code
,
pickle
):
...
...
@@ -1098,6 +1104,112 @@ class AbstractPickleTests(unittest.TestCase):
empty
=
self
.
loads
(
b'
\
x80
\
x03
U
\
x00
q
\
x00
.'
,
encoding
=
'koi8-r'
)
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
class
REX_one
(
object
):
...
...
Lib/test/support.py
View file @
110d5b50
...
...
@@ -1089,7 +1089,7 @@ def bigmemtest(minsize, memuse):
return
wrapper
return
decorator
def
precisionbigmemtest
(
size
,
memuse
):
def
precisionbigmemtest
(
size
,
memuse
,
dry_run
=
True
):
def
decorator
(
f
):
def
wrapper
(
self
):
size
=
wrapper
.
size
...
...
@@ -1099,10 +1099,11 @@ def precisionbigmemtest(size, memuse):
else
:
maxsize
=
size
if
real_max_memuse
and
real_max_memuse
<
maxsize
*
memuse
:
raise
unittest
.
SkipTest
(
"not enough memory: %.1fG minimum needed"
%
(
size
*
memuse
/
(
1024
**
3
)))
if
((
real_max_memuse
or
not
dry_run
)
and
real_max_memuse
<
maxsize
*
memuse
):
raise
unittest
.
SkipTest
(
"not enough memory: %.1fG minimum needed"
%
(
size
*
memuse
/
(
1024
**
3
)))
return
f
(
self
,
maxsize
)
wrapper
.
size
=
size
...
...
Lib/test/test_pickle.py
View file @
110d5b50
...
...
@@ -7,6 +7,7 @@ from test.pickletester import AbstractPickleTests
from
test.pickletester
import
AbstractPickleModuleTests
from
test.pickletester
import
AbstractPersistentPicklerTests
from
test.pickletester
import
AbstractPicklerUnpicklerObjectTests
from
test.pickletester
import
BigmemPickleTests
try
:
import
_pickle
...
...
@@ -37,13 +38,13 @@ class PyPicklerTests(AbstractPickleTests):
return
u
.
load
()
class
InMemoryPickleTests
(
AbstractPickleTests
):
class
InMemoryPickleTests
(
AbstractPickleTests
,
BigmemPickleTests
):
pickler
=
pickle
.
_Pickler
unpickler
=
pickle
.
_Unpickler
def
dumps
(
self
,
arg
,
proto
=
None
):
return
pickle
.
dumps
(
arg
,
proto
)
def
dumps
(
self
,
arg
,
proto
col
=
None
):
return
pickle
.
dumps
(
arg
,
proto
col
)
def
loads
(
self
,
buf
,
**
kwds
):
return
pickle
.
loads
(
buf
,
**
kwds
)
...
...
Misc/NEWS
View file @
110d5b50
...
...
@@ -25,6 +25,12 @@ Library
- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi
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
greater than FD_SETSIZE.
...
...
Modules/_pickle.c
View file @
110d5b50
This diff is collapsed.
Click to expand it.
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