@@ -31,6 +31,7 @@ def _scan(src: str):
3131
3232
3333class TestParseSleep :
34+
3435 def test_plain_seconds (self ):
3536 assert _parse_sleep ("5" ) == 5.0
3637
@@ -54,6 +55,7 @@ def test_invalid(self):
5455
5556
5657class TestHostHelpers :
58+
5759 def test_looks_like_host_simple (self ):
5860 assert _looks_like_host ("api.example.com" ) is True
5961
@@ -72,6 +74,7 @@ def test_looks_like_host_path(self):
7274
7375
7476class TestSecretRef :
77+
7578 def test_token_var (self ):
7679 assert _looks_like_secret_ref ("${API_TOKEN}" ) is True
7780
@@ -84,6 +87,7 @@ def test_plain_var(self):
8487
8588
8689class TestEnvAssignment :
90+
8791 def test_simple (self ):
8892 assert _looks_like_env_assignment ("FOO=bar" ) is True
8993
@@ -101,6 +105,7 @@ def test_no_equals(self):
101105
102106
103107class TestDdHelpers :
108+
104109 def test_size_bs_count (self ):
105110 assert _extract_dd_size (["bs=1M" , "count=2" ]) == 2 * 1024 * 1024
106111
@@ -130,9 +135,9 @@ def test_parse_size_value_invalid(self):
130135
131136
132137class TestPythonPipInstall :
138+
133139 def test_python_m_pip_install (self ):
134- assert _is_python_pip_install ("python" ,
135- ["-m" , "pip" , "install" , "x" ]) is True
140+ assert _is_python_pip_install ("python" , ["-m" , "pip" , "install" , "x" ]) is True
136141
137142 def test_python_no_pip (self ):
138143 assert _is_python_pip_install ("python" , ["script.py" ]) is False
@@ -142,6 +147,7 @@ def test_non_python(self):
142147
143148
144149class TestInterpreterPayload :
150+
145151 def test_dash_c (self ):
146152 assert _interpreter_runs_payload (["-c" , "code" ]) is True
147153
@@ -156,6 +162,7 @@ def test_only_flags(self):
156162
157163
158164class TestOffsets :
165+
159166 def test_line_of_first_line (self ):
160167 assert _line_of ("hello\n world" , 1 ) == 1
161168
@@ -172,6 +179,7 @@ def test_col_of_second_line(self):
172179
173180
174181class TestRm :
182+
175183 def test_recursive_rm (self ):
176184 facts = _scan ("rm -rf /tmp/x" )
177185 assert facts .file_deletes
@@ -190,6 +198,7 @@ def test_rm_no_target(self):
190198
191199
192200class TestNetwork :
201+
193202 def test_curl_static_url (self ):
194203 facts = _scan ("curl https://api.example.com/x" )
195204 assert facts .network_calls
@@ -217,11 +226,11 @@ def test_url_in_arg_catchall(self):
217226 # command follows. Use a plain command that survives to the URL
218227 # catch-all in the generic handler.
219228 facts = _scan ("true https://evil.example.com" )
220- assert any (n .target == "evil.example.com"
221- for n in facts .network_calls )
229+ assert any (n .target == "evil.example.com" for n in facts .network_calls )
222230
223231
224232class TestFileRead :
233+
225234 def test_cat_dotenv (self ):
226235 facts = _scan ("cat .env" )
227236 assert facts .file_reads
@@ -234,6 +243,7 @@ def test_cat_ssh_key(self):
234243
235244
236245class TestFileWrite :
246+
237247 def test_tee (self ):
238248 facts = _scan ("echo hi | tee /tmp/x" )
239249 assert any (w .target == "/tmp/x" for w in facts .file_writes )
@@ -245,13 +255,15 @@ def test_redirection(self):
245255
246256
247257class TestPrivilege :
258+
248259 def test_sudo (self ):
249260 facts = _scan ("sudo rm /tmp/x" )
250261 assert facts .privilege_commands
251262 assert facts .privilege_commands [0 ].command == "sudo"
252263
253264
254265class TestPackageManager :
266+
255267 def test_pip_install (self ):
256268 facts = _scan ("pip install requests" )
257269 assert facts .dependency_installs
@@ -273,6 +285,7 @@ def test_apt_install(self):
273285
274286
275287class TestDynamicExec :
288+
276289 def test_eval (self ):
277290 facts = _scan ("eval 'rm -rf /'" )
278291 assert facts .dynamic_execs
@@ -308,6 +321,7 @@ def test_interpreter_payload(self):
308321
309322
310323class TestShellOperators :
324+
311325 def test_pipe (self ):
312326 facts = _scan ("a | b" )
313327 assert any (o .operator == "|" for o in facts .shell_operators )
@@ -329,6 +343,7 @@ def test_semicolon(self):
329343
330344
331345class TestSleep :
346+
332347 def test_static_sleep (self ):
333348 facts = _scan ("sleep 5" )
334349 assert facts .long_sleeps
@@ -341,6 +356,7 @@ def test_invalid_sleep(self):
341356
342357
343358class TestLargeWrites :
359+
344360 def test_dd_size_extracted (self ):
345361 facts = _scan ("dd if=/dev/zero of=/tmp/x bs=1M count=10" )
346362 assert facts .large_writes
@@ -349,12 +365,14 @@ def test_dd_size_extracted(self):
349365
350366
351367class TestForkBomb :
368+
352369 def test_classic_bomb (self ):
353370 facts = _scan (":(){ :|:& };:" )
354371 assert facts .fork_bombs
355372
356373
357374class TestLoops :
375+
358376 def test_while_true (self ):
359377 facts = _scan ("while true; do echo hi; done" )
360378 assert facts .unbounded_loops
@@ -365,6 +383,7 @@ def test_for_infinite(self):
365383
366384
367385class TestConcurrency :
386+
368387 def test_many_background_jobs (self ):
369388 # 8+ single-amp background jobs trigger concurrency fact
370389 facts = _scan ("a & b & c & d & e & f & g & h &" )
@@ -373,6 +392,7 @@ def test_many_background_jobs(self):
373392
374393
375394class TestSecretFlowBash :
395+
376396 def test_echo_token (self ):
377397 facts = _scan ('echo "$API_TOKEN"' )
378398 assert facts .secret_flows
@@ -384,6 +404,7 @@ def test_echo_password(self):
384404
385405
386406class TestLexer :
407+
387408 def test_unbalanced_quote (self ):
388409 lexer = _BashLexer ("'unterminated" )
389410 _ , errors = lexer .tokenize ()
@@ -416,6 +437,7 @@ def test_newline_separator(self):
416437
417438
418439class TestEnvAssignmentHandling :
440+
419441 def test_leading_env_stripped (self ):
420442 facts = _scan ("FOO=bar ls -l" )
421443 assert facts .process_calls
@@ -428,17 +450,16 @@ def test_env_only_no_command(self):
428450
429451
430452class TestBashScannerRule :
453+
431454 def test_skips_when_language_mismatch (self , scan_request_factory ):
432455 rule = BashScannerRule ()
433- req = scan_request_factory (
434- language = ScriptLanguage .PYTHON , script = "print(1)" )
456+ req = scan_request_factory (language = ScriptLanguage .PYTHON , script = "print(1)" )
435457 out = list (rule .scan (req , _make_min_policy ()))
436458 assert out == []
437459
438460 def test_emits_finding_for_dangerous (self , scan_request_factory ):
439461 rule = BashScannerRule ()
440- req = scan_request_factory (
441- language = ScriptLanguage .BASH , script = "rm -rf /tmp" )
462+ req = scan_request_factory (language = ScriptLanguage .BASH , script = "rm -rf /tmp" )
442463 out = list (rule .scan (req , _make_min_policy ()))
443464 assert any (f .rule_id == "FILE001_RECURSIVE_DELETE" for f in out )
444465
0 commit comments