Skip to content

Commit 5365c7e

Browse files
committed
Fixing broken CI/CD
1 parent ce01e65 commit 5365c7e

3 files changed

Lines changed: 34 additions & 14 deletions

File tree

‎lib/core/settings.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from thirdparty import six
2121

2222
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
23-
VERSION = "1.10.9.15"
23+
VERSION = "1.10.9.16"
2424
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2525
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2626
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

‎sqlmap.py‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@
88
from __future__ import print_function
99

1010
try:
11+
import os
1112
import sys
1213

1314
sys.dont_write_bytecode = True
1415

1516
# Reference: https://github.com/python/cpython/issues/156319 - CPython's tier-2 optimizer can
16-
# corrupt frame locals (raising exceptions the executed code cannot produce) whenever an active
17-
# sys.monitoring tool (an attached debugger/profiler/coverage run) coincides with enough hot
18-
# code. sqlmap never needs one attached during a scan, so silence any already-registered tool
19-
# up front, before any hot code runs (name stays registered so the owning tool can still free it)
20-
if hasattr(sys, "monitoring"):
17+
# corrupt frame locals (raising exceptions the executed code cannot produce), but only when the
18+
# experimental JIT is on AND a sys.monitoring tool (debugger/profiler/coverage run) is active at
19+
# the same time - neither alone triggers it. So only silence monitoring when the JIT is also on;
20+
# otherwise leave it alone (e.g. a legitimate `coverage run sqlmap.py ...` must keep working).
21+
if hasattr(sys, "monitoring") and (sys._jit.is_enabled() if hasattr(sys, "_jit") else (sys.version_info >= (3, 13) and os.environ.get("PYTHON_JIT") == '1')):
2122
for _ in range(6): # valid tool id range (Reference: https://docs.python.org/3/library/sys.monitoring.html)
2223
try:
2324
if sys.monitoring.get_tool(_) is not None:

‎tests/test_jit_guard.py‎

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,23 +95,42 @@ def test_normal_path_is_untouched_without_jit(self):
9595
""" % (ROOT, _TEST_TOOL_ID, _TEST_TOOL_ID, _TEST_TOOL_ID, _TEST_TOOL_ID)
9696

9797

98+
def _monitoringStateAfterImport(jit):
99+
env = dict(os.environ)
100+
env["PYTHON_JIT"] = jit
101+
out = subprocess.check_output([sys.executable, "-c", _MONITORING_DRIVER], cwd=ROOT, env=env)
102+
tool, events = out.decode("utf-8").strip().splitlines()
103+
return tool, int(events)
104+
105+
98106
class TestMonitoringGuard(unittest.TestCase):
99107
"""
100108
The other half of the cpython#156319 mitigation: the tier-2 corruption needs BOTH the JIT and
101-
an active sys.monitoring tool (debugger/profiler/coverage) at once. sqlmap has no legitimate
102-
reason to run a scan with one attached, so it silences any already-registered tool's events as
103-
the very first thing at import time (Reference: 'https://github.com/python/cpython/issues/156319').
109+
an active sys.monitoring tool (debugger/profiler/coverage) at once - neither alone triggers it.
110+
So sqlmap only silences an already-registered tool's events when the JIT is also on, and leaves
111+
it alone otherwise. A plain `coverage run sqlmap.py ...` (JIT off) must keep working - which is
112+
exactly what broke CI the first time this guard shipped unconditionally.
104113
"""
105114

106-
def test_active_tool_is_silenced_but_not_unregistered(self):
115+
def test_active_tool_is_silenced_when_jit_is_on(self):
107116
if not hasattr(sys, "monitoring"):
108117
self.skipTest("interpreter has no sys.monitoring (needs 3.12+)")
118+
if not _jitEnabled('1'):
119+
self.skipTest("interpreter does not report the JIT as enabled")
109120

110-
out = subprocess.check_output([sys.executable, "-c", _MONITORING_DRIVER], cwd=ROOT)
111-
tool, events = out.decode("utf-8").strip().splitlines()
112-
121+
tool, events = _monitoringStateAfterImport('1')
113122
self.assertEqual(tool, "test-tool") # still registered - its own owner can still free it
114-
self.assertEqual(events, "0") # events cleared to NO_EVENTS, so nothing fires
123+
self.assertEqual(events, 0) # but events cleared to NO_EVENTS
124+
125+
def test_active_tool_is_left_alone_without_jit(self):
126+
if not hasattr(sys, "monitoring"):
127+
self.skipTest("interpreter has no sys.monitoring (needs 3.12+)")
128+
if _jitEnabled('0'):
129+
self.skipTest("JIT stays enabled with PYTHON_JIT=0 on this build")
130+
131+
tool, events = _monitoringStateAfterImport('0')
132+
self.assertEqual(tool, "test-tool")
133+
self.assertNotEqual(events, 0) # untouched - e.g. a real `coverage run` must keep working
115134

116135

117136
if __name__ == "__main__":

0 commit comments

Comments
 (0)