f744a9
From 0fcfa065d900040c80628b31b8b6ea606c131086 Mon Sep 17 00:00:00 2001
f744a9
From: Paul Ivanov <pivanov5@bloomberg.net>
f744a9
Date: Wed, 30 Jan 2019 14:22:44 -0800
f744a9
Subject: [PATCH] BUG: load fails when using pickle without allow_pickle=True
f744a9
f744a9
a partial mitigation of #12759.
f744a9
f744a9
see also https://nvd.nist.gov/vuln/detail/CVE-2019-6446
f744a9
---
f744a9
 numpy/core/tests/test_regression.py |  2 +-
f744a9
 numpy/lib/format.py                 |  8 ++++++--
f744a9
 numpy/lib/npyio.py                  | 17 ++++++++++++-----
f744a9
 numpy/lib/tests/test_format.py      | 15 +++++++++------
f744a9
 numpy/lib/tests/test_io.py          |  2 +-
f744a9
 5 files changed, 29 insertions(+), 15 deletions(-)
f744a9
f744a9
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
f744a9
index a3b0114..2be6bf3 100644
f744a9
--- a/numpy/core/tests/test_regression.py
f744a9
+++ b/numpy/core/tests/test_regression.py
f744a9
@@ -96,7 +96,7 @@ class TestRegression(object):
f744a9
         ca = np.char.array(np.arange(1000, 1010), itemsize=4)
f744a9
         ca.dump(f)
f744a9
         f.seek(0)
f744a9
-        ca = np.load(f)
f744a9
+        ca = np.load(f, allow_pickle=True)
f744a9
         f.close()
f744a9
 
f744a9
     def test_noncontiguous_fill(self):
f744a9
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
f744a9
index 363bb21..b91142c 100644
f744a9
--- a/numpy/lib/format.py
f744a9
+++ b/numpy/lib/format.py
f744a9
@@ -602,7 +602,7 @@ def write_array(fp, array, version=None, allow_pickle=True, pickle_kwargs=None):
f744a9
                 fp.write(chunk.tobytes('C'))
f744a9
 
f744a9
 
f744a9
-def read_array(fp, allow_pickle=True, pickle_kwargs=None):
f744a9
+def read_array(fp, allow_pickle=False, pickle_kwargs=None):
f744a9
     """
f744a9
     Read an array from an NPY file.
f744a9
 
f744a9
@@ -612,7 +612,11 @@ def read_array(fp, allow_pickle=True, pickle_kwargs=None):
f744a9
         If this is not a real file object, then this may take extra memory
f744a9
         and time.
f744a9
     allow_pickle : bool, optional
f744a9
-        Whether to allow reading pickled data. Default: True
f744a9
+        Whether to allow writing pickled data. Default: False
f744a9
+
f744a9
+        .. versionchanged:: 1.14.2
f744a9
+            Made default False in response to CVE-2019-6446.
f744a9
+
f744a9
     pickle_kwargs : dict
f744a9
         Additional keyword arguments to pass to pickle.load. These are only
f744a9
         useful when loading object arrays saved on Python 2 when using
f744a9
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
f744a9
index 76b135c..c6522f5 100644
f744a9
--- a/numpy/lib/npyio.py
f744a9
+++ b/numpy/lib/npyio.py
f744a9
@@ -130,7 +130,11 @@ class NpzFile(object):
f744a9
         An object on which attribute can be performed as an alternative
f744a9
         to getitem access on the `NpzFile` instance itself.
f744a9
     allow_pickle : bool, optional
f744a9
-        Allow loading pickled data. Default: True
f744a9
+        Allow loading pickled data. Default: False
f744a9
+
f744a9
+        .. versionchanged:: 1.14.2
f744a9
+            Made default False in response to CVE-2019-6446.
f744a9
+
f744a9
     pickle_kwargs : dict, optional
f744a9
         Additional keyword arguments to pass on to pickle.load.
f744a9
         These are only useful when loading object arrays saved on
f744a9
@@ -166,7 +170,7 @@ class NpzFile(object):
f744a9
 
f744a9
     """
f744a9
 
f744a9
-    def __init__(self, fid, own_fid=False, allow_pickle=True,
f744a9
+    def __init__(self, fid, own_fid=False, allow_pickle=False,
f744a9
                  pickle_kwargs=None):
f744a9
         # Import is postponed to here since zipfile depends on gzip, an
f744a9
         # optional component of the so-called standard library.
f744a9
@@ -265,7 +269,7 @@ class NpzFile(object):
f744a9
         return self.files.__contains__(key)
f744a9
 
f744a9
 
f744a9
-def load(file, mmap_mode=None, allow_pickle=True, fix_imports=True,
f744a9
+def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
f744a9
          encoding='ASCII'):
f744a9
     """
f744a9
     Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.
f744a9
@@ -287,8 +291,11 @@ def load(file, mmap_mode=None, allow_pickle=True, fix_imports=True,
f744a9
         Allow loading pickled object arrays stored in npy files. Reasons for
f744a9
         disallowing pickles include security, as loading pickled data can
f744a9
         execute arbitrary code. If pickles are disallowed, loading object
f744a9
-        arrays will fail.
f744a9
-        Default: True
f744a9
+        arrays will fail. Default: False
f744a9
+
f744a9
+        .. versionchanged:: 1.14.2
f744a9
+            Made default False in response to CVE-2019-6446.
f744a9
+
f744a9
     fix_imports : bool, optional
f744a9
         Only useful when loading Python 2 generated pickled files on Python 3,
f744a9
         which includes npy/npz files containing object arrays. If `fix_imports`
f744a9
diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py
f744a9
index 2d2b4ce..04e090c 100644
f744a9
--- a/numpy/lib/tests/test_format.py
f744a9
+++ b/numpy/lib/tests/test_format.py
f744a9
@@ -426,7 +426,7 @@ def roundtrip(arr):
f744a9
     f = BytesIO()
f744a9
     format.write_array(f, arr)
f744a9
     f2 = BytesIO(f.getvalue())
f744a9
-    arr2 = format.read_array(f2)
f744a9
+    arr2 = format.read_array(f2, allow_pickle=True)
f744a9
     return arr2
f744a9
 
f744a9
 
f744a9
@@ -553,7 +553,7 @@ def test_pickle_python2_python3():
f744a9
         path = os.path.join(data_dir, fname)
f744a9
 
f744a9
         for encoding in ['bytes', 'latin1']:
f744a9
-            data_f = np.load(path, encoding=encoding)
f744a9
+            data_f = np.load(path, allow_pickle=True, encoding=encoding)
f744a9
             if fname.endswith('.npz'):
f744a9
                 data = data_f['x']
f744a9
                 data_f.close()
f744a9
@@ -575,16 +575,19 @@ def test_pickle_python2_python3():
f744a9
         if sys.version_info[0] >= 3:
f744a9
             if fname.startswith('py2'):
f744a9
                 if fname.endswith('.npz'):
f744a9
-                    data = np.load(path)
f744a9
+                    data = np.load(path, allow_pickle=True)
f744a9
                     assert_raises(UnicodeError, data.__getitem__, 'x')
f744a9
                     data.close()
f744a9
-                    data = np.load(path, fix_imports=False, encoding='latin1')
f744a9
+                    data = np.load(path, allow_pickle=True, fix_imports=False,
f744a9
+                                   encoding='latin1')
f744a9
                     assert_raises(ImportError, data.__getitem__, 'x')
f744a9
                     data.close()
f744a9
                 else:
f744a9
-                    assert_raises(UnicodeError, np.load, path)
f744a9
+                    assert_raises(UnicodeError, np.load, path,
f744a9
+                                  allow_pickle=True)
f744a9
                     assert_raises(ImportError, np.load, path,
f744a9
-                                  encoding='latin1', fix_imports=False)
f744a9
+                                  allow_pickle=True, fix_imports=False,
f744a9
+                                  encoding='latin1')
f744a9
 
f744a9
 
f744a9
 def test_pickle_disallow():
f744a9
diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py
f744a9
index 2daa015..bde2567 100644
f744a9
--- a/numpy/lib/tests/test_io.py
f744a9
+++ b/numpy/lib/tests/test_io.py
f744a9
@@ -87,7 +87,7 @@ class RoundtripTest(object):
f744a9
 
f744a9
         """
f744a9
         save_kwds = kwargs.get('save_kwds', {})
f744a9
-        load_kwds = kwargs.get('load_kwds', {})
f744a9
+        load_kwds = kwargs.get('load_kwds', {"allow_pickle": True})
f744a9
         file_on_disk = kwargs.get('file_on_disk', False)
f744a9
 
f744a9
         if file_on_disk:
f744a9
-- 
f744a9
2.21.0
f744a9