mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
bpo-46724: Fix dis support for overflow args (GH-31285)
This commit is contained in:
parent
2923d87ca2
commit
c3ce7781e3
3 changed files with 40 additions and 5 deletions
11
Lib/dis.py
11
Lib/dis.py
|
@ -515,6 +515,12 @@ def _disassemble_str(source, **kwargs):
|
||||||
|
|
||||||
disco = disassemble # XXX For backwards compatibility
|
disco = disassemble # XXX For backwards compatibility
|
||||||
|
|
||||||
|
|
||||||
|
# Rely on C `int` being 32 bits for oparg
|
||||||
|
_INT_BITS = 32
|
||||||
|
# Value for c int when it overflows
|
||||||
|
_INT_OVERFLOW = 2 ** (_INT_BITS - 1)
|
||||||
|
|
||||||
def _unpack_opargs(code):
|
def _unpack_opargs(code):
|
||||||
extended_arg = 0
|
extended_arg = 0
|
||||||
for i in range(0, len(code), 2):
|
for i in range(0, len(code), 2):
|
||||||
|
@ -522,6 +528,11 @@ def _unpack_opargs(code):
|
||||||
if op >= HAVE_ARGUMENT:
|
if op >= HAVE_ARGUMENT:
|
||||||
arg = code[i+1] | extended_arg
|
arg = code[i+1] | extended_arg
|
||||||
extended_arg = (arg << 8) if op == EXTENDED_ARG else 0
|
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
|
||||||
|
# to a negative integer
|
||||||
|
if extended_arg >= _INT_OVERFLOW:
|
||||||
|
extended_arg -= 2 * _INT_OVERFLOW
|
||||||
else:
|
else:
|
||||||
arg = None
|
arg = None
|
||||||
extended_arg = 0
|
extended_arg = 0
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
# Minimal tests for dis module
|
# Minimal tests for dis module
|
||||||
|
|
||||||
from test.support import captured_stdout, requires_debug_ranges
|
import contextlib
|
||||||
from test.support.bytecode_helper import BytecodeTestCase
|
|
||||||
import unittest
|
|
||||||
import sys
|
|
||||||
import dis
|
import dis
|
||||||
import io
|
import io
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import types
|
import types
|
||||||
import contextlib
|
import unittest
|
||||||
|
from test.support import captured_stdout, requires_debug_ranges
|
||||||
|
from test.support.bytecode_helper import BytecodeTestCase
|
||||||
|
|
||||||
|
import opcode
|
||||||
|
|
||||||
|
|
||||||
def get_tb():
|
def get_tb():
|
||||||
def _error():
|
def _error():
|
||||||
|
@ -219,6 +222,22 @@ dis_bug_45757 = """\
|
||||||
RETURN_VALUE
|
RETURN_VALUE
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# [255, 255, 255, 252] is -4 in a 4 byte signed integer
|
||||||
|
bug46724 = bytes([
|
||||||
|
opcode.EXTENDED_ARG, 255,
|
||||||
|
opcode.EXTENDED_ARG, 255,
|
||||||
|
opcode.EXTENDED_ARG, 255,
|
||||||
|
opcode.opmap['JUMP_FORWARD'], 252,
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dis_bug46724 = """\
|
||||||
|
>> EXTENDED_ARG 255
|
||||||
|
EXTENDED_ARG 65535
|
||||||
|
EXTENDED_ARG 16777215
|
||||||
|
JUMP_FORWARD -4 (to 0)
|
||||||
|
"""
|
||||||
|
|
||||||
_BIG_LINENO_FORMAT = """\
|
_BIG_LINENO_FORMAT = """\
|
||||||
1 RESUME 0
|
1 RESUME 0
|
||||||
|
|
||||||
|
@ -688,6 +707,10 @@ class DisTests(DisTestBase):
|
||||||
# Extended arg followed by NOP
|
# Extended arg followed by NOP
|
||||||
self.do_disassembly_test(code_bug_45757, dis_bug_45757)
|
self.do_disassembly_test(code_bug_45757, dis_bug_45757)
|
||||||
|
|
||||||
|
def test_bug_46724(self):
|
||||||
|
# Test that negative operargs are handled properly
|
||||||
|
self.do_disassembly_test(bug46724, dis_bug46724)
|
||||||
|
|
||||||
def test_big_linenos(self):
|
def test_big_linenos(self):
|
||||||
def func(count):
|
def func(count):
|
||||||
namespace = {}
|
namespace = {}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix :mod:`dis` behavior on negative jump offsets.
|
Loading…
Add table
Add a link
Reference in a new issue