summaryrefslogtreecommitdiffstats
path: root/Lib/dis.py
diff options
context:
space:
mode:
authorSaul Shanabrook <s.shanabrook@gmail.com>2022-02-18 09:56:23 (GMT)
committerGitHub <noreply@github.com>2022-02-18 09:56:23 (GMT)
commitc3ce7781e3afe6f2dec5eef8e87fd5a664519ae9 (patch)
tree71debab0cde3a897b78dc05cec13beeca7ae82b4 /Lib/dis.py
parent2923d87ca258b9d421e8147b12f0d98295ee3f8e (diff)
downloadcpython-c3ce7781e3afe6f2dec5eef8e87fd5a664519ae9.zip
cpython-c3ce7781e3afe6f2dec5eef8e87fd5a664519ae9.tar.gz
cpython-c3ce7781e3afe6f2dec5eef8e87fd5a664519ae9.tar.bz2
bpo-46724: Fix dis support for overflow args (GH-31285)
Diffstat (limited to 'Lib/dis.py')
-rw-r--r--Lib/dis.py11
1 files changed, 11 insertions, 0 deletions
diff --git a/Lib/dis.py b/Lib/dis.py
index 2462a84..dc3ec16 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -515,6 +515,12 @@ 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):
@@ -522,6 +528,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
+ # to a negative integer
+ if extended_arg >= _INT_OVERFLOW:
+ extended_arg -= 2 * _INT_OVERFLOW
else:
arg = None
extended_arg = 0