Skip to content

Commit

Permalink
bpo-46724: Fix dis support for overflow args (GH-31285)
Browse files Browse the repository at this point in the history
  • Loading branch information
saulshanabrook authored Feb 18, 2022
1 parent 2923d87 commit c3ce778
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
11 changes: 11 additions & 0 deletions Lib/dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,13 +515,24 @@ def _disassemble_str(source, **kwargs):

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):
extended_arg = 0
for i in range(0, len(code), 2):
op = code[i]
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
# to a negative integer
if extended_arg >= _INT_OVERFLOW:
extended_arg -= 2 * _INT_OVERFLOW
else:
arg = None
extended_arg = 0
Expand Down
33 changes: 28 additions & 5 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# 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

import opcode


def get_tb():
def _error():
Expand Down Expand Up @@ -219,6 +222,22 @@ def bug42562():
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 = """\
1 RESUME 0
Expand Down Expand Up @@ -688,6 +707,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 negative operargs are handled properly
self.do_disassembly_test(bug46724, dis_bug46724)

def test_big_linenos(self):
def func(count):
namespace = {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix :mod:`dis` behavior on negative jump offsets.

0 comments on commit c3ce778

Please sign in to comment.