summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZackery Spytz <zspytz@gmail.com>2023-12-01 13:36:37 (GMT)
committerGitHub <noreply@github.com>2023-12-01 13:36:37 (GMT)
commit058444308abee79bb1b3358883adfa8c97bd043a (patch)
tree051cc0e5addc7b1557e6df9902ce1ee18041c937
parenta73aa48e6bec900be7edd3431deaa5fc1d809e6f (diff)
downloadcpython-058444308abee79bb1b3358883adfa8c97bd043a.zip
cpython-058444308abee79bb1b3358883adfa8c97bd043a.tar.gz
cpython-058444308abee79bb1b3358883adfa8c97bd043a.tar.bz2
gh-82565: Add tests for pickle and unpickle with bad files (GH-16606)
-rw-r--r--Lib/test/pickletester.py78
1 files changed, 78 insertions, 0 deletions
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
index ddb180e..fd446c8 100644
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -3514,6 +3514,84 @@ class AbstractPickleModuleTests:
self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
+ def test_unpickler_bad_file(self):
+ # bpo-38384: Crash in _pickle if the read attribute raises an error.
+ def raises_oserror(self, *args, **kwargs):
+ raise OSError
+ @property
+ def bad_property(self):
+ 1/0
+
+ # File without read and readline
+ class F:
+ pass
+ self.assertRaises((AttributeError, TypeError), self.Unpickler, F())
+
+ # File without read
+ class F:
+ readline = raises_oserror
+ self.assertRaises((AttributeError, TypeError), self.Unpickler, F())
+
+ # File without readline
+ class F:
+ read = raises_oserror
+ self.assertRaises((AttributeError, TypeError), self.Unpickler, F())
+
+ # File with bad read
+ class F:
+ read = bad_property
+ readline = raises_oserror
+ self.assertRaises(ZeroDivisionError, self.Unpickler, F())
+
+ # File with bad readline
+ class F:
+ readline = bad_property
+ read = raises_oserror
+ self.assertRaises(ZeroDivisionError, self.Unpickler, F())
+
+ # File with bad readline, no read
+ class F:
+ readline = bad_property
+ self.assertRaises(ZeroDivisionError, self.Unpickler, F())
+
+ # File with bad read, no readline
+ class F:
+ read = bad_property
+ self.assertRaises((AttributeError, ZeroDivisionError), self.Unpickler, F())
+
+ # File with bad peek
+ class F:
+ peek = bad_property
+ read = raises_oserror
+ readline = raises_oserror
+ try:
+ self.Unpickler(F())
+ except ZeroDivisionError:
+ pass
+
+ # File with bad readinto
+ class F:
+ readinto = bad_property
+ read = raises_oserror
+ readline = raises_oserror
+ try:
+ self.Unpickler(F())
+ except ZeroDivisionError:
+ pass
+
+ def test_pickler_bad_file(self):
+ # File without write
+ class F:
+ pass
+ self.assertRaises(TypeError, self.Pickler, F())
+
+ # File with bad write
+ class F:
+ @property
+ def write(self):
+ 1/0
+ self.assertRaises(ZeroDivisionError, self.Pickler, F())
+
def check_dumps_loads_oob_buffers(self, dumps, loads):
# No need to do the full gamut of tests here, just enough to
# check that dumps() and loads() redirect their arguments