Check the arguments of FRAME opcodes in a protocol 4+ pickle. Note that binary objects that are larger than FRAME_SIZE_TARGET are not framed by default and are therefore considered a frame by themselves in the following consistency check.
(self, pickled)
| 3856 | FRAME_SIZE_TARGET = 64 * 1024 |
| 3857 | |
| 3858 | def check_frame_opcodes(self, pickled): |
| 3859 | """ |
| 3860 | Check the arguments of FRAME opcodes in a protocol 4+ pickle. |
| 3861 | |
| 3862 | Note that binary objects that are larger than FRAME_SIZE_TARGET are not |
| 3863 | framed by default and are therefore considered a frame by themselves in |
| 3864 | the following consistency check. |
| 3865 | """ |
| 3866 | frame_end = frameless_start = None |
| 3867 | frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8', |
| 3868 | 'BINUNICODE8', 'BYTEARRAY8'} |
| 3869 | for op, arg, pos in pickletools.genops(pickled): |
| 3870 | if frame_end is not None: |
| 3871 | self.assertLessEqual(pos, frame_end) |
| 3872 | if pos == frame_end: |
| 3873 | frame_end = None |
| 3874 | |
| 3875 | if frame_end is not None: # framed |
| 3876 | self.assertNotEqual(op.name, 'FRAME') |
| 3877 | if op.name in frameless_opcodes: |
| 3878 | # Only short bytes and str objects should be written |
| 3879 | # in a frame |
| 3880 | self.assertLessEqual(len(arg), self.FRAME_SIZE_TARGET) |
| 3881 | |
| 3882 | else: # not framed |
| 3883 | if (op.name == 'FRAME' or |
| 3884 | (op.name in frameless_opcodes and |
| 3885 | len(arg) > self.FRAME_SIZE_TARGET)): |
| 3886 | # Frame or large bytes or str object |
| 3887 | if frameless_start is not None: |
| 3888 | # Only short data should be written outside of a frame |
| 3889 | self.assertLess(pos - frameless_start, |
| 3890 | self.FRAME_SIZE_MIN) |
| 3891 | frameless_start = None |
| 3892 | elif frameless_start is None and op.name != 'PROTO': |
| 3893 | frameless_start = pos |
| 3894 | |
| 3895 | if op.name == 'FRAME': |
| 3896 | self.assertGreaterEqual(arg, self.FRAME_SIZE_MIN) |
| 3897 | frame_end = pos + 9 + arg |
| 3898 | |
| 3899 | pos = len(pickled) |
| 3900 | if frame_end is not None: |
| 3901 | self.assertEqual(frame_end, pos) |
| 3902 | elif frameless_start is not None: |
| 3903 | self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN) |
| 3904 | |
| 3905 | @support.skip_if_pgo_task |
| 3906 | @support.requires_resource('cpu') |
no test coverage detected