8000 Merge pull request #4882 from pv/fix-unpickle-latin1-crash · numpy/numpy@4e32035 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4e32035

Browse files
committed
Merge pull request #4882 from pv/fix-unpickle-latin1-crash
BUG: core: fix crash when unpickling data on Py3 under non-latin1 encoding
2 parents d75c549 + cd062f5 commit 4e32035

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

numpy/core/src/multiarray/methods.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,13 @@ array_setstate(PyArrayObject *self, PyObject *args)
16701670
tmp = PyUnicode_AsLatin1String(rawdata);
16711671
Py_DECREF(rawdata);
16721672
rawdata = tmp;
1673+
if (tmp == NULL) {
1674+
/* More informative error message */
1675+
PyErr_SetString(PyExc_ValueError,
1676+
("Failed to encode latin1 string when unpickling a Numpy array. "
1677+
"pickle.load(a, encoding='latin1') is assumed."));
1678+
return NULL;
1679+
}
16731680
}
16741681
#endif
16751682

numpy/core/tests/test_regression.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,22 @@ def test_pickle_bytes_overwrite(self):
17981798
bytestring = "\x01 ".encode('ascii')
17991799
assert_equal(bytestring[0:1], '\x01'.encode('ascii'))
18001800

1801+
def test_pickle_py2_array_latin1_hack(self):
1802+
# Check that unpickling hacks in Py3 that support
1803+
# encoding='latin1' work correctly.
1804+
1805+
# Python2 output for pickle.dumps(numpy.array([129], dtype='b'))
1806+
data = asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\n"
1807+
"tp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'i1'\np8\n"
1808+
"I0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nNNNI-1\nI-1\nI0\ntp12\nbI00\nS'\\x81'\n"
1809+
"p13\ntp14\nb.")
1810+
if sys.version_info[0] >= 3:
1811+
# This should work:
1812+
result = pickle.loads(data, encoding='latin1')
1813+
assert_array_equal(result, np.array([129], dtype='b'))
1814+
# Should not segfault:
1815+
assert_raises(Exception, pickle.loads, data, encoding='koi8-r')
1816+
18011817
def test_structured_type_to_object(self):
18021818
a_rec = np.array([(0, 1), (3, 2)], dtype='i4,i8')
18031819
a_obj = np.empty((2,), dtype=object)

0 commit comments

Comments
 (0)
0