@@ -3514,6 +3514,84 @@ def __init__(self): pass
3514
3514
self .assertRaises (pickle .PicklingError , BadPickler ().dump , 0 )
3515
3515
self .assertRaises (pickle .UnpicklingError , BadUnpickler ().load )
3516
3516
3517
+ def test_unpickler_bad_file (self ):
3518
+ # bpo-38384: Crash in _pickle if the read attribute raises an error.
3519
+ def raises_oserror (self , * args , ** kwargs ):
3520
+ raise OSError
3521
+ @property
3522
+ def bad_property (self ):
3523
+ 1 / 0
3524
+
3525
+ # File without read and readline
3526
+ class F :
3527
+ pass
3528
+ self .assertRaises ((AttributeError , TypeError ), self .Unpickler , F ())
3529
+
3530
+ # File without read
3531
+ class F :
3532
+ readline = raises_oserror
3533
+ self .assertRaises ((AttributeError , TypeError ), self .Unpickler , F ())
3534
+
3535
+ # File without readline
3536
+ class F :
3537
+ read = raises_oserror
3538
+ self .assertRaises ((AttributeError , TypeError ), self .Unpickler , F ())
3539
+
3540
+ # File with bad read
3541
+ class F :
3542
+ read = bad_property
3543
+ readline = raises_oserror
3544
+ self .assertRaises (ZeroDivisionError , self .Unpickler , F ())
3545
+
3546
+ # File with bad readline
3547
+ class F :
3548
+ readline = bad_property
3549
+ read = raises_oserror
3550
+ self .assertRaises (ZeroDivisionError , self .Unpickler , F ())
3551
+
3552
+ # File with bad readline, no read
3553
+ class F :
3554
+ readline = bad_property
3555
+ self .assertRaises (ZeroDivisionError , self .Unpickler , F ())
3556
+
3557
+ # File with bad read, no readline
3558
+ class F :
3559
+ read = bad_property
3560
+ self .assertRaises ((AttributeError , ZeroDivisionError ), self .Unpickler , F ())
3561
+
3562
+ # File with bad peek
3563
+ class F :
3564
+ peek = bad_property
3565
+ read = raises_oserror
3566
+ readline = raises_oserror
3567
+ try :
3568
+ self .Unpickler (F ())
3569
+ except ZeroDivisionError :
3570
+ pass
3571
+
3572
+ # File with bad readinto
3573
+ class F :
3574
+ readinto = bad_property
3575
+ read = raises_oserror
3576
+ readline = raises_oserror
3577
+ try :
3578
+ self .Unpickler (F ())
3579
+ except ZeroDivisionError :
3580
+ pass
3581
+
3582
+ def test_pickler_bad_file (self ):
3583
+ # File without write
3584
+ class F :
3585
+ pass
3586
+ self .assertRaises (TypeError , self .Pickler , F ())
3587
+
3588
+ # File with bad write
3589
+ class F :
3590
+ @property
3591
+ def write (self ):
3592
+ 1 / 0
3593
+ self .assertRaises (ZeroDivisionError , self .Pickler , F ())
3594
+
3517
3595
def check_dumps_loads_oob_buffers (self , dumps , loads ):
3518
3596
# No need to do the full gamut of tests here, just enough to
3519
3597
# check that dumps() and loads() redirect their arguments
0 commit comments