@@ -3483,6 +3483,84 @@ def __init__(self): pass
3483
3483
self .assertRaises (pickle .PicklingError , BadPickler ().dump , 0 )
3484
3484
self .assertRaises (pickle .UnpicklingError , BadUnpickler ().load )
3485
3485
3486
+ def test_unpickler_bad_file (self ):
3487
+ # bpo-38384: Crash in _pickle if the read attribute raises an error.
3488
+ def raises_oserror (self , * args , ** kwargs ):
3489
+ raise OSError
3490
+ @property
3491
+ def bad_property (self ):
3492
+ 1 / 0
3493
+
3494
+ # File without read and readline
3495
+ class F :
3496
+ pass
3497
+ self .assertRaises ((AttributeError , TypeError ), self .Unpickler , F ())
3498
+
3499
+ # File without read
3500
+ class F :
3501
+ readline = raises_oserror
3502
+ self .assertRaises ((AttributeError , TypeError ), self .Unpickler , F ())
3503
+
3504
+ # File without readline
3505
+ class F :
3506
+ read = raises_oserror
3507
+ self .assertRaises ((AttributeError , TypeError ), self .Unpickler , F ())
3508
+
3509
+ # File with bad read
3510
+ class F :
3511
+ read = bad_property
3512
+ readline = raises_oserror
3513
+ self .assertRaises (ZeroDivisionError , self .Unpickler , F ())
3514
+
3515
+ # File with bad readline
3516
+ class F :
3517
+ readline = bad_property
3518
+ read = raises_oserror
3519
+ self .assertRaises (ZeroDivisionError , self .Unpickler , F ())
3520
+
3521
+ # File with bad readline, no read
3522
+ class F :
3523
+ readline = bad_property
3524
+ self .assertRaises (ZeroDivisionError , self .Unpickler , F ())
3525
+
3526
+ # File with bad read, no readline
3527
+ class F :
3528
+ read = bad_property
3529
+ self .assertRaises ((AttributeError , ZeroDivisionError ), self .Unpickler , F ())
3530
+
3531
+ # File with bad peek
3532
+ class F :
3533
+ peek = bad_property
3534
+ read = raises_oserror
3535
+ readline = raises_oserror
3536
+ try :
3537
+ self .Unpickler (F ())
3538
+ except ZeroDivisionError :
3539
+ pass
3540
+
3541
+ # File with bad readinto
3542
+ class F :
3543
+ readinto = bad_property
3544
+ read = raises_oserror
3545
+ readline = raises_oserror
3546
+ try :
3547
+ self .Unpickler (F ())
3548
+ except ZeroDivisionError :
3549
+ pass
3550
+
3551
+ def test_pickler_bad_file (self ):
3552
+ # File without write
3553
+ class F :
3554
+ pass
3555
+ self .assertRaises (TypeError , self .Pickler , F ())
3556
+
3557
+ # File with bad write
3558
+ class F :
3559
+ @property
3560
+ def write (self ):
3561
+ 1 / 0
3562
+ self .assertRaises (ZeroDivisionError , self .Pickler , F ())
3563
+
3486
3564
def check_dumps_loads_oob_buffers (self , dumps , loads ):
3487
3565
# No need to do the full gamut of tests here, just enough to
3488
3566
# check that dumps() and loads() redirect their arguments
0 commit comments