From 85de221305ac5c87409133b116b20138b873fbd7 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Fri, 11 Feb 2022 15:30:11 -0500 Subject: [PATCH 01/15] bpo-46724: Fix dis support for overflow args --- Lib/dis.py | 14 ++++++++++++++ Lib/test/test_dis.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/Lib/dis.py b/Lib/dis.py index 2462a8434e8950..febfdd2dbdc2cc 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -4,6 +4,7 @@ import types import collections import io +import ctypes from opcode import * from opcode import __all__ as _opcodes_all @@ -515,6 +516,14 @@ def _disassemble_str(source, **kwargs): disco = disassemble # XXX For backwards compatibility + +# The number of bits in a signed int +_c_int_bit_size = ctypes.sizeof(ctypes.c_int()) * 8 +# The maximum value that can be stored in a signed int +_c_int_upper_limit = (2 ** (_c_int_bit_size - 1)) - 1 +# The number of values that can be stored in a signed int +_c_int_length = 2 ** _c_int_bit_size + def _unpack_opargs(code): extended_arg = 0 for i in range(0, len(code), 2): @@ -522,6 +531,11 @@ def _unpack_opargs(code): if op >= HAVE_ARGUMENT: arg = code[i+1] | extended_arg extended_arg = (arg << 8) if op == EXTENDED_ARG else 0 + # The oparg is stored as a signed integer + # If the value exceeds its upper limit, it will overflow and wrap + # This makes the dis output match the current behavior of the interpreter + if extended_arg > _c_int_upper_limit: + extended_arg -= _c_int_length else: arg = None extended_arg = 0 diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 4feeb8c5be8a25..7d447ba957da12 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -219,6 +219,45 @@ def bug42562(): RETURN_VALUE """ +bug46724 = compile("while not (a < b < c):\n pass", "", "exec") + +dis_bug46724 = """\ + 0 RESUME 0 + + 1 2 LOAD_NAME 0 (a) + 4 LOAD_NAME 1 (b) + 6 SWAP 2 + 8 COPY 2 + 10 COMPARE_OP 0 (<) + 12 POP_JUMP_IF_FALSE 11 (to 22) + 14 LOAD_NAME 2 (c) + 16 COMPARE_OP 0 (<) + 18 POP_JUMP_IF_TRUE 29 (to 58) + 20 JUMP_FORWARD 1 (to 24) + >> 22 POP_TOP + + 2 >> 24 NOP + + 1 26 LOAD_NAME 0 (a) + 28 LOAD_NAME 1 (b) + 30 SWAP 2 + 32 COPY 2 + 34 COMPARE_OP 0 (<) + 36 POP_JUMP_IF_FALSE 24 (to 48) + 38 LOAD_NAME 2 (c) + 40 COMPARE_OP 0 (<) + 42 POP_JUMP_IF_FALSE 12 (to 24) + 44 LOAD_CONST 0 (None) + 46 RETURN_VALUE + >> 48 POP_TOP + 50 EXTENDED_ARG 255 + 52 EXTENDED_ARG 65535 + 54 EXTENDED_ARG 16777215 + 56 JUMP_FORWARD -17 (to 24) + >> 58 LOAD_CONST 0 (None) + 60 RETURN_VALUE +""" + _BIG_LINENO_FORMAT = """\ 1 RESUME 0 @@ -688,6 +727,10 @@ def test_bug_45757(self): # Extended arg followed by NOP self.do_disassembly_test(code_bug_45757, dis_bug_45757) + def test_bug_46724(self): + # Test that overflow operargs wrap + self.do_disassembly_test(bug46724, dis_bug46724) + def test_big_linenos(self): def func(count): namespace = {} From 5f6222ccaabd999bd46abda5a46e00daac1e4358 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 11 Feb 2022 20:41:18 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst diff --git a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst new file mode 100644 index 00000000000000..342e63a2d1f1aa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst @@ -0,0 +1 @@ +Fixes dis behavior on bytecode arguments which overflow to match Python interpreter From 813f42af43abde64f19ea1907faa96971eebe44b Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Fri, 11 Feb 2022 15:47:02 -0500 Subject: [PATCH 03/15] Move ctypes import inside --- Lib/dis.py | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index febfdd2dbdc2cc..ea6fd91e6b1b60 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -4,7 +4,6 @@ import types import collections import io -import ctypes from opcode import * from opcode import __all__ as _opcodes_all @@ -517,14 +516,47 @@ def _disassemble_str(source, **kwargs): disco = disassemble # XXX For backwards compatibility -# The number of bits in a signed int -_c_int_bit_size = ctypes.sizeof(ctypes.c_int()) * 8 -# The maximum value that can be stored in a signed int -_c_int_upper_limit = (2 ** (_c_int_bit_size - 1)) - 1 -# The number of values that can be stored in a signed int -_c_int_length = 2 ** _c_int_bit_size def _unpack_opargs(code): + + # When the ctypes import is at the top level, the tests raise an error, so it is imported inline: + # Traceback (most recent call last): + # File "", line 198, in _run_module_as_main + # File "", line 88, in _run_code + # File "/home/runner/work/cpython/cpython/Lib/sysconfig.py", line 810, in + # _main() + # ^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/sysconfig.py", line 798, in _main + # _generate_posix_vars() + # ^^^^^^^^^^^^^^^^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/sysconfig.py", line 418, in _generate_posix_vars + # import pprint + # ^^^^^^^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/pprint.py", line 38, in + # import dataclasses as _dataclasses + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/dataclasses.py", line 5, in + # import inspect + # ^^^^^^^^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/inspect.py", line 137, in + # import dis + # ^^^^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/dis.py", line 7, in + # import ctypes + # ^^^^^^^^^^^^^ + # File "/home/runner/work/cpython/cpython/Lib/ctypes/__init__.py", line 8, in + # from _ctypes import Union, Structure, Array + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # ModuleNotFoundError: No module named '_ctypes' + import ctypes + # The number of bits in a signed int + c_int_bit_size = ctypes.sizeof(ctypes.c_int()) * 8 + # The maximum value that can be stored in a signed int + c_int_upper_limit = (2 ** (c_int_bit_size - 1)) - 1 + # The number of values that can be stored in a signed int + c_int_length = 2 ** c_int_bit_size + + extended_arg = 0 for i in range(0, len(code), 2): op = code[i] @@ -534,8 +566,8 @@ def _unpack_opargs(code): # The oparg is stored as a signed integer # If the value exceeds its upper limit, it will overflow and wrap # This makes the dis output match the current behavior of the interpreter - if extended_arg > _c_int_upper_limit: - extended_arg -= _c_int_length + if extended_arg > c_int_upper_limit: + extended_arg -= c_int_length else: arg = None extended_arg = 0 From 31c7714fb697c7d773ea22cdc8499b602eb9a840 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Sat, 12 Feb 2022 09:26:16 -0500 Subject: [PATCH 04/15] Change news to document that it supports negative values --- .../next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst index 342e63a2d1f1aa..d3d0c78ebf7f5b 100644 --- a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst +++ b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst @@ -1 +1 @@ -Fixes dis behavior on bytecode arguments which overflow to match Python interpreter +Fixes dis behavior on bytecode arguments which overflow to support negative args From 30782434fffa2009b9ced892cbe64364fa6fac59 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Sun, 13 Feb 2022 13:09:10 -0500 Subject: [PATCH 05/15] Update Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst Co-authored-by: Jelle Zijlstra --- .../next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst index d3d0c78ebf7f5b..9ac8c17deb7a2d 100644 --- a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst +++ b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst @@ -1 +1 @@ -Fixes dis behavior on bytecode arguments which overflow to support negative args +Fix :mod:`dis` behavior on negative jump offsets. From e87c2c4fb5fea2b538f2f1eb2fb0a9032a4e6bb6 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Sun, 13 Feb 2022 13:11:48 -0500 Subject: [PATCH 06/15] Remove long comment stack trace --- Lib/dis.py | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index ea6fd91e6b1b60..82c3396e04e648 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -518,36 +518,7 @@ def _disassemble_str(source, **kwargs): def _unpack_opargs(code): - - # When the ctypes import is at the top level, the tests raise an error, so it is imported inline: - # Traceback (most recent call last): - # File "", line 198, in _run_module_as_main - # File "", line 88, in _run_code - # File "/home/runner/work/cpython/cpython/Lib/sysconfig.py", line 810, in - # _main() - # ^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/sysconfig.py", line 798, in _main - # _generate_posix_vars() - # ^^^^^^^^^^^^^^^^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/sysconfig.py", line 418, in _generate_posix_vars - # import pprint - # ^^^^^^^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/pprint.py", line 38, in - # import dataclasses as _dataclasses - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/dataclasses.py", line 5, in - # import inspect - # ^^^^^^^^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/inspect.py", line 137, in - # import dis - # ^^^^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/dis.py", line 7, in - # import ctypes - # ^^^^^^^^^^^^^ - # File "/home/runner/work/cpython/cpython/Lib/ctypes/__init__.py", line 8, in - # from _ctypes import Union, Structure, Array - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # ModuleNotFoundError: No module named '_ctypes' + # Can't import ctypes at the top level because it's unavailable in some tests that need dis import ctypes # The number of bits in a signed int c_int_bit_size = ctypes.sizeof(ctypes.c_int()) * 8 From 75365050304b89ece097f25dbae2c4b8d4d82fa5 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 15 Feb 2022 09:44:30 -0500 Subject: [PATCH 07/15] Rely on int being 4 bytes --- Lib/dis.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 82c3396e04e648..4a01ed7b1b1207 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -516,18 +516,12 @@ def _disassemble_str(source, **kwargs): disco = disassemble # XXX For backwards compatibility +# Rely on C `int` being 32 bits for oparg +INT_BITS = 32 +# Maximum value for a c int +INT_MAX = 2 ** (INT_BITS - 1) def _unpack_opargs(code): - # Can't import ctypes at the top level because it's unavailable in some tests that need dis - import ctypes - # The number of bits in a signed int - c_int_bit_size = ctypes.sizeof(ctypes.c_int()) * 8 - # The maximum value that can be stored in a signed int - c_int_upper_limit = (2 ** (c_int_bit_size - 1)) - 1 - # The number of values that can be stored in a signed int - c_int_length = 2 ** c_int_bit_size - - extended_arg = 0 for i in range(0, len(code), 2): op = code[i] @@ -536,9 +530,9 @@ def _unpack_opargs(code): extended_arg = (arg << 8) if op == EXTENDED_ARG else 0 # The oparg is stored as a signed integer # If the value exceeds its upper limit, it will overflow and wrap - # This makes the dis output match the current behavior of the interpreter - if extended_arg > c_int_upper_limit: - extended_arg -= c_int_length + # to a negative integer + if extended_arg >= INT_MAX: + extended_arg -= 2 * INT_MAX else: arg = None extended_arg = 0 From 59b767b1506058e0e72775ed838ebe6545bbd0f9 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 15 Feb 2022 09:56:05 -0500 Subject: [PATCH 08/15] Add bytecode as constant in test --- Lib/test/test_dis.py | 70 ++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 7d447ba957da12..0f252036d5b4e1 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -219,43 +219,43 @@ def bug42562(): RETURN_VALUE """ -bug46724 = compile("while not (a < b < c):\n pass", "", "exec") +# Result of compile("while not (a < b < c):\n pass", "", "exec").co_code +# but added as constant to make agnostic to compile behavior +bug46724 = b'\x97\x00e\x00e\x01c\x02x\x02k\x00r\x0be\x02k\x00s\x1dn\x01\x01\x00\t\x00e\x00e\x01c\x02x\x02k\x00r\x18e\x02k\x00r\x0cd\x00S\x00\x01\x00\x90\xff\x90\xff\x90\xffn\xefd\x00S\x00' + dis_bug46724 = """\ - 0 RESUME 0 - - 1 2 LOAD_NAME 0 (a) - 4 LOAD_NAME 1 (b) - 6 SWAP 2 - 8 COPY 2 - 10 COMPARE_OP 0 (<) - 12 POP_JUMP_IF_FALSE 11 (to 22) - 14 LOAD_NAME 2 (c) - 16 COMPARE_OP 0 (<) - 18 POP_JUMP_IF_TRUE 29 (to 58) - 20 JUMP_FORWARD 1 (to 24) - >> 22 POP_TOP - - 2 >> 24 NOP - - 1 26 LOAD_NAME 0 (a) - 28 LOAD_NAME 1 (b) - 30 SWAP 2 - 32 COPY 2 - 34 COMPARE_OP 0 (<) - 36 POP_JUMP_IF_FALSE 24 (to 48) - 38 LOAD_NAME 2 (c) - 40 COMPARE_OP 0 (<) - 42 POP_JUMP_IF_FALSE 12 (to 24) - 44 LOAD_CONST 0 (None) - 46 RETURN_VALUE - >> 48 POP_TOP - 50 EXTENDED_ARG 255 - 52 EXTENDED_ARG 65535 - 54 EXTENDED_ARG 16777215 - 56 JUMP_FORWARD -17 (to 24) - >> 58 LOAD_CONST 0 (None) - 60 RETURN_VALUE + 0 RESUME 0 + 2 LOAD_NAME 0 + 4 LOAD_NAME 1 + 6 SWAP 2 + 8 COPY 2 + 10 COMPARE_OP 0 (<) + 12 POP_JUMP_IF_FALSE 11 (to 22) + 14 LOAD_NAME 2 + 16 COMPARE_OP 0 (<) + 18 POP_JUMP_IF_TRUE 29 (to 58) + 20 JUMP_FORWARD 1 (to 24) + >> 22 POP_TOP + >> 24 NOP + 26 LOAD_NAME 0 + 28 LOAD_NAME 1 + 30 SWAP 2 + 32 COPY 2 + 34 COMPARE_OP 0 (<) + 36 POP_JUMP_IF_FALSE 24 (to 48) + 38 LOAD_NAME 2 + 40 COMPARE_OP 0 (<) + 42 POP_JUMP_IF_FALSE 12 (to 24) + 44 LOAD_CONST 0 + 46 RETURN_VALUE + >> 48 POP_TOP + 50 EXTENDED_ARG 255 + 52 EXTENDED_ARG 65535 + 54 EXTENDED_ARG 16777215 + 56 JUMP_FORWARD -17 (to 24) + >> 58 LOAD_CONST 0 + 60 RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ From 5b582d1f23b49ff2b5a7976f27c6fcea6bc7db58 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 15 Feb 2022 09:57:15 -0500 Subject: [PATCH 09/15] Make constants private Co-authored-by: Jelle Zijlstra --- Lib/dis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 4a01ed7b1b1207..c4a85e27af1ac4 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -517,9 +517,9 @@ def _disassemble_str(source, **kwargs): # Rely on C `int` being 32 bits for oparg -INT_BITS = 32 +_INT_BITS = 32 # Maximum value for a c int -INT_MAX = 2 ** (INT_BITS - 1) +_INT_MAX = 2 ** (_INT_BITS - 1) def _unpack_opargs(code): extended_arg = 0 From ab07e3a6bbf0761497d446565ffd19af8abffa4a Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 15 Feb 2022 09:57:54 -0500 Subject: [PATCH 10/15] Update constant references to match private names --- Lib/dis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index c4a85e27af1ac4..5101cf1ff8d1e2 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -531,8 +531,8 @@ def _unpack_opargs(code): # The oparg is stored as a signed integer # If the value exceeds its upper limit, it will overflow and wrap # to a negative integer - if extended_arg >= INT_MAX: - extended_arg -= 2 * INT_MAX + if extended_arg >= _INT_MAX: + extended_arg -= 2 * _INT_MAX else: arg = None extended_arg = 0 From cf92b0bc962e40e9604be00fe59e1d35a1c1ad18 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 15 Feb 2022 11:29:50 -0500 Subject: [PATCH 11/15] Simplify test case --- Lib/test/test_dis.py | 45 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 0f252036d5b4e1..4421045b712fdd 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -219,43 +219,20 @@ def bug42562(): RETURN_VALUE """ -# Result of compile("while not (a < b < c):\n pass", "", "exec").co_code -# but added as constant to make agnostic to compile behavior -bug46724 = b'\x97\x00e\x00e\x01c\x02x\x02k\x00r\x0be\x02k\x00s\x1dn\x01\x01\x00\t\x00e\x00e\x01c\x02x\x02k\x00r\x18e\x02k\x00r\x0cd\x00S\x00\x01\x00\x90\xff\x90\xff\x90\xffn\xefd\x00S\x00' +# [255, 255, 255, 252] is -4 in a 4 byte signed integer +bug46724 = bytes([ + 144, 255, # EXTENDED_ARG + 144, 255, + 144, 255, + 110, 252, # JUMP_FORWARD +]) dis_bug46724 = """\ - 0 RESUME 0 - 2 LOAD_NAME 0 - 4 LOAD_NAME 1 - 6 SWAP 2 - 8 COPY 2 - 10 COMPARE_OP 0 (<) - 12 POP_JUMP_IF_FALSE 11 (to 22) - 14 LOAD_NAME 2 - 16 COMPARE_OP 0 (<) - 18 POP_JUMP_IF_TRUE 29 (to 58) - 20 JUMP_FORWARD 1 (to 24) - >> 22 POP_TOP - >> 24 NOP - 26 LOAD_NAME 0 - 28 LOAD_NAME 1 - 30 SWAP 2 - 32 COPY 2 - 34 COMPARE_OP 0 (<) - 36 POP_JUMP_IF_FALSE 24 (to 48) - 38 LOAD_NAME 2 - 40 COMPARE_OP 0 (<) - 42 POP_JUMP_IF_FALSE 12 (to 24) - 44 LOAD_CONST 0 - 46 RETURN_VALUE - >> 48 POP_TOP - 50 EXTENDED_ARG 255 - 52 EXTENDED_ARG 65535 - 54 EXTENDED_ARG 16777215 - 56 JUMP_FORWARD -17 (to 24) - >> 58 LOAD_CONST 0 - 60 RETURN_VALUE + >> 0 EXTENDED_ARG 255 + 2 EXTENDED_ARG 65535 + 4 EXTENDED_ARG 16777215 + 6 JUMP_FORWARD -4 (to 0) """ _BIG_LINENO_FORMAT = """\ From 26fea404234866d6f2e6f2704e98a9c8988ccc29 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 15 Feb 2022 11:32:16 -0500 Subject: [PATCH 12/15] Update comment to reflect we are testing negative opargs --- Lib/test/test_dis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 4421045b712fdd..e66b25f941f6b2 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -705,7 +705,7 @@ def test_bug_45757(self): self.do_disassembly_test(code_bug_45757, dis_bug_45757) def test_bug_46724(self): - # Test that overflow operargs wrap + # Test that negative operargs are handled properly self.do_disassembly_test(bug46724, dis_bug46724) def test_big_linenos(self): From 2dfe57d03fb4a4fb725e6919fae0057d30844349 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 16 Feb 2022 10:14:16 -0500 Subject: [PATCH 13/15] _INT_MAX -> _INT_OVERFLOW --- Lib/dis.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 5101cf1ff8d1e2..dc3ec169abecf0 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -518,8 +518,8 @@ def _disassemble_str(source, **kwargs): # Rely on C `int` being 32 bits for oparg _INT_BITS = 32 -# Maximum value for a c int -_INT_MAX = 2 ** (_INT_BITS - 1) +# Value for c int when it overflows +_INT_OVERFLOW = 2 ** (_INT_BITS - 1) def _unpack_opargs(code): extended_arg = 0 @@ -531,8 +531,8 @@ def _unpack_opargs(code): # The oparg is stored as a signed integer # If the value exceeds its upper limit, it will overflow and wrap # to a negative integer - if extended_arg >= _INT_MAX: - extended_arg -= 2 * _INT_MAX + if extended_arg >= _INT_OVERFLOW: + extended_arg -= 2 * _INT_OVERFLOW else: arg = None extended_arg = 0 From fb8dde4d3347690bf27152defbfc5cf393656729 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Thu, 17 Feb 2022 14:16:17 -0500 Subject: [PATCH 14/15] Update test output to new form --- Lib/test/test_dis.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index e66b25f941f6b2..ba2d3bcc65e39a 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1,14 +1,15 @@ # Minimal tests for dis module -from test.support import captured_stdout, requires_debug_ranges -from test.support.bytecode_helper import BytecodeTestCase -import unittest -import sys +import contextlib import dis import io import re +import sys import types -import contextlib +import unittest +from test.support import captured_stdout, requires_debug_ranges +from test.support.bytecode_helper import BytecodeTestCase + def get_tb(): def _error(): @@ -229,10 +230,10 @@ def bug42562(): dis_bug46724 = """\ - >> 0 EXTENDED_ARG 255 - 2 EXTENDED_ARG 65535 - 4 EXTENDED_ARG 16777215 - 6 JUMP_FORWARD -4 (to 0) + >> EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to 0) """ _BIG_LINENO_FORMAT = """\ From 2859a220f7c913e55511a101610d6f011b112bdc Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Thu, 17 Feb 2022 15:13:32 -0500 Subject: [PATCH 15/15] Replace op integers with opcode references --- Lib/test/test_dis.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index ba2d3bcc65e39a..488b8dffdedbf2 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -10,6 +10,8 @@ from test.support import captured_stdout, requires_debug_ranges from test.support.bytecode_helper import BytecodeTestCase +import opcode + def get_tb(): def _error(): @@ -222,10 +224,10 @@ def bug42562(): # [255, 255, 255, 252] is -4 in a 4 byte signed integer bug46724 = bytes([ - 144, 255, # EXTENDED_ARG - 144, 255, - 144, 255, - 110, 252, # JUMP_FORWARD + opcode.EXTENDED_ARG, 255, + opcode.EXTENDED_ARG, 255, + opcode.EXTENDED_ARG, 255, + opcode.opmap['JUMP_FORWARD'], 252, ])