diff --git a/CHANGELOG b/CHANGELOG index 67782fa5..d2c15c74 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ jc changelog -20260227 v1.25.7 +20260306 v1.25.7 +- Fix `proc-pid-smaps` proc parser when unknown VmFlags are output +- Fix `iptables` command parser when Target is blank and verbose output is used 20251012 v1.25.6 - Add `net-localgroup` Windows command parser diff --git a/jc/parsers/iptables.py b/jc/parsers/iptables.py index 9dd8b7b5..f5d21adb 100644 --- a/jc/parsers/iptables.py +++ b/jc/parsers/iptables.py @@ -173,7 +173,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.12' + version = '1.13' description = '`iptables` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -294,9 +294,16 @@ def parse(data, raw=False, quiet=False): else: # sometimes the "target" column is blank. Stuff in a dummy character - if headers[0] == 'target' and line.startswith(' '): + opt_values = {'--', '-f', '!f'} + line_split = line.split() + if headers[0] == 'target' and line.startswith(' '): # standard output line = '\u2063' + line + elif headers[0] == 'pkts' and line_split[3] in opt_values: # verbose output + first_section = line_split[:2] + second_section = line_split[2:] + line = ' '.join(first_section) + ' \u2063 ' + ' '.join(second_section) + rule = line.split(maxsplit=len(headers) - 1) temp_rule = dict(zip(headers, rule)) if temp_rule: diff --git a/tests/fixtures/generic/iptables-no-jump2.json b/tests/fixtures/generic/iptables-no-jump2.json new file mode 100644 index 00000000..ea217a0e --- /dev/null +++ b/tests/fixtures/generic/iptables-no-jump2.json @@ -0,0 +1 @@ +[{"chain":"INPUT","default_policy":"ACCEPT","default_packets":0,"default_bytes":0,"rules":[{"pkts":17,"bytes":1172,"target":null,"prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"}]}] diff --git a/tests/fixtures/generic/iptables-no-jump2.out b/tests/fixtures/generic/iptables-no-jump2.out new file mode 100644 index 00000000..0422051e --- /dev/null +++ b/tests/fixtures/generic/iptables-no-jump2.out @@ -0,0 +1,3 @@ +Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + 17 1172 all -- * * 0.0.0.0/0 0.0.0.0/0 diff --git a/tests/test_iptables.py b/tests/test_iptables.py index e94ea806..157dff63 100644 --- a/tests/test_iptables.py +++ b/tests/test_iptables.py @@ -48,6 +48,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/iptables-no-jump.out'), 'r', encoding='utf-8') as f: generic_iptables_no_jump = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/iptables-no-jump2.out'), 'r', encoding='utf-8') as f: + generic_iptables_no_jump2 = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iptables-filter.json'), 'r', encoding='utf-8') as f: centos_7_7_iptables_filter_json = json.loads(f.read()) @@ -88,6 +91,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/iptables-no-jump.json'), 'r', encoding='utf-8') as f: generic_iptables_no_jump_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/iptables-no-jump2.json'), 'r', encoding='utf-8') as f: + generic_iptables_no_jump2_json = json.loads(f.read()) + def test_iptables_nodata(self): """ @@ -173,6 +179,12 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.iptables.parse(self.generic_iptables_no_jump, quiet=True), self.generic_iptables_no_jump_json) + def test_iptables_no_jump2_generic(self): + """ + Test 'sudo iptables' with no jump target and verbose output + """ + self.assertEqual(jc.parsers.iptables.parse(self.generic_iptables_no_jump2, quiet=True), self.generic_iptables_no_jump2_json) + def test_iptables_x_option_format(self): """ Test iptables -x