bpo-31829: Make protocol 0 pickles be loadable in text mode in Python 2. (GH-11859)
Escape ``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) in Unicode strings.
This commit is contained in:
parent
ba0430211f
commit
38ab7d4721
|
@ -852,7 +852,10 @@ class _Pickler:
|
|||
self.write(BINUNICODE + pack("<I", n) + encoded)
|
||||
else:
|
||||
obj = obj.replace("\\", "\\u005c")
|
||||
obj = obj.replace("\0", "\\u0000")
|
||||
obj = obj.replace("\n", "\\u000a")
|
||||
obj = obj.replace("\r", "\\u000d")
|
||||
obj = obj.replace("\x1a", "\\u001a") # EOF on DOS
|
||||
self.write(UNICODE + obj.encode('raw-unicode-escape') +
|
||||
b'\n')
|
||||
self.memoize(obj)
|
||||
|
|
|
@ -3067,22 +3067,20 @@ class BadGetattr:
|
|||
class AbstractPickleModuleTests(unittest.TestCase):
|
||||
|
||||
def test_dump_closed_file(self):
|
||||
import os
|
||||
f = open(TESTFN, "wb")
|
||||
try:
|
||||
f.close()
|
||||
self.assertRaises(ValueError, self.dump, 123, f)
|
||||
finally:
|
||||
os.remove(TESTFN)
|
||||
support.unlink(TESTFN)
|
||||
|
||||
def test_load_closed_file(self):
|
||||
import os
|
||||
f = open(TESTFN, "wb")
|
||||
try:
|
||||
f.close()
|
||||
self.assertRaises(ValueError, self.dump, 123, f)
|
||||
finally:
|
||||
os.remove(TESTFN)
|
||||
support.unlink(TESTFN)
|
||||
|
||||
def test_load_from_and_dump_to_file(self):
|
||||
stream = io.BytesIO()
|
||||
|
@ -3106,6 +3104,19 @@ class AbstractPickleModuleTests(unittest.TestCase):
|
|||
self.Pickler(f, -1)
|
||||
self.Pickler(f, protocol=-1)
|
||||
|
||||
def test_dump_text_file(self):
|
||||
f = open(TESTFN, "w")
|
||||
try:
|
||||
for proto in protocols:
|
||||
self.assertRaises(TypeError, self.dump, 123, f, proto)
|
||||
finally:
|
||||
f.close()
|
||||
support.unlink(TESTFN)
|
||||
|
||||
def test_incomplete_input(self):
|
||||
s = io.BytesIO(b"X''.")
|
||||
self.assertRaises((EOFError, struct.error, pickle.UnpicklingError), self.load, s)
|
||||
|
||||
def test_bad_init(self):
|
||||
# Test issue3664 (pickle can segfault from a badly initialized Pickler).
|
||||
# Override initialization without calling __init__() of the superclass.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) are now escaped in
|
||||
protocol 0 pickles of Unicode strings. This allows to load them without loss
|
||||
from files open in text mode in Python 2.
|
|
@ -2588,7 +2588,10 @@ raw_unicode_escape(PyObject *obj)
|
|||
*p++ = Py_hexdigits[ch & 15];
|
||||
}
|
||||
/* Map 16-bit characters, '\\' and '\n' to '\uxxxx' */
|
||||
else if (ch >= 256 || ch == '\\' || ch == '\n') {
|
||||
else if (ch >= 256 ||
|
||||
ch == '\\' || ch == 0 || ch == '\n' || ch == '\r' ||
|
||||
ch == 0x1a)
|
||||
{
|
||||
/* -1: subtract 1 preallocated byte */
|
||||
p = _PyBytesWriter_Prepare(&writer, p, 6-1);
|
||||
if (p == NULL)
|
||||
|
|
Loading…
Reference in New Issue