@@ -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+
98106class 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
117136if __name__ == "__main__" :
0 commit comments