rules = []
buf = ""
for line in fileobj:
- try:
- if type(line) == type(b""):
- line = line.decode()
- except:
- pass
+ if type(line) == type(b""):
+ try:
+ line = line.decode("utf-8", "strict")
+ except UnicodeDecodeError:
+ logger.warning("Skipping rule due to encoding issue: %s", repr(line))
+ # Skip this line and reset buffer if we were accumulating a multi-line rule
+ if buf:
+ logger.warning("Discarding incomplete multi-line rule due to encoding issue")
+ buf = ""
+ continue
if line.rstrip().endswith("\\"):
buf = "%s%s " % (buf, line.rstrip()[0:-1])
continue
--- /dev/null
+alert tcp any any -> any any (msg:"Valid rule 1"; sid:1001; rev:1;)
+alert tcp any any -> any any (msg:"Bad encoding ÿþ"; sid:1002; rev:1;)
+alert tcp any any -> any any (msg:"Latin1 éè"; sid:1003; rev:1;)
+alert tcp any any -> any any (msg:"Valid rule 2"; sid:1004; rev:1;)
+alert tcp any any -> any any (msg:"Valid multiline"; \
+ content:"test"; \
+ sid:2001; rev:1;)
+alert tcp any any -> any any (msg:"Bad multiline"; \
+ content:"badÿþ"; \
+ sid:2002; rev:1;)
+alert tcp any any -> any any (msg:"Valid after bad"; sid:2003; rev:1;)
self.assertEqual(rule["source_port"], "any")
self.assertEqual(rule["dest_addr"], "[any,![$EXTERNAL_IP,$REVERSE_PROXY_HOSTS,$ODD_HTTP_HOSTS]]")
self.assertEqual(rule["dest_port"], "80")
+
+ def test_rule_with_encoding_issues(self):
+ """Test that rules with encoding issues are skipped (Issue #7812)"""
+ # Parse the file with encoding issues
+ with open('tests/rules-with-encoding-issues.rules', 'rb') as fileobj:
+ rules = suricata.update.rule.parse_fileobj(fileobj)
+
+ # Should have parsed:
+ # - Valid single-line rules (1001 and 1004)
+ # - Valid multiline rule (2001)
+ # - Valid rule after bad multiline (2003)
+ # Should have skipped:
+ # - Rules with bad encoding (1002, 1003)
+ # - Bad multiline rule (2002)
+ self.assertEqual(len(rules), 4)
+
+ # Check single-line rules
+ self.assertEqual(rules[0].sid, 1001)
+ self.assertEqual(rules[0].msg, "Valid rule 1")
+ self.assertEqual(rules[1].sid, 1004)
+ self.assertEqual(rules[1].msg, "Valid rule 2")
+
+ # Check multiline rules
+ self.assertEqual(rules[2].sid, 2001)
+ self.assertEqual(rules[2].msg, "Valid multiline")
+ self.assertEqual(rules[3].sid, 2003)
+ self.assertEqual(rules[3].msg, "Valid after bad")