diff --git a/src/local_coding_slm/safety.py b/src/local_coding_slm/safety.py index e7de07a..c79fa2c 100644 --- a/src/local_coding_slm/safety.py +++ b/src/local_coding_slm/safety.py @@ -208,7 +208,7 @@ def parse_proc_net_listen_ports(text: str) -> list[tuple[str, int]]: parts = line.split() if len(parts) < 4: continue - if parts[3] != _LISTEN_STATE: + if parts[3].upper() != _LISTEN_STATE: continue local = parts[1] if ":" not in local: diff --git a/tests/test_safety.py b/tests/test_safety.py index 4538105..7292c09 100644 --- a/tests/test_safety.py +++ b/tests/test_safety.py @@ -168,6 +168,15 @@ def test_unparsed_listen_address_fails(self) -> None: result = classify_local_listeners(parse_proc_net_listen_ports(text)) self.assertEqual(result.status, "fail", result.message) + def test_lowercase_listen_state_fails_when_not_loopback(self) -> None: + """State 0a is LISTEN. A wildcard row must not be dropped as 'not listening'.""" + text = ( + " sl local_address rem_address st\n" + " 0: 00000000:2CAA 00000000:0000 0a 00000000:00000000\n" + ) + result = classify_local_listeners(parse_proc_net_listen_ports(text)) + self.assertEqual(result.status, "fail", result.message) + class TestHygiene(unittest.TestCase): def test_placeholder_ips_pass(self) -> None: