A runaway string should still be returned by the code that splits on
commas, so add a '?' to the regex so that the last '"?' in a string
still produces a valid block for the split code.
Tested:
ACTION=="remove\"GOTO=""
Which then produced:
$ test/rule-syntax-check.py src/login/70-uaccess.rules
# looking at src/login/70-uaccess.rules
Invalid line src/login/70-uaccess.rules:10: ACTION=="remove\"GOTO=""
clause: ACTION=="remove\"GOTO=""
no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
# Find comma-separated groups, but allow commas that are inside quoted strings.
-comma_separated_group_re = re.compile(r'(?:[^,"]|' + quoted_string_re + ')+')
+# Using quoted_string_re + '?' so that strings missing the last double quote
+# will still match for this part that splits on commas.
+comma_separated_group_re = re.compile(r'(?:[^,"]|' + quoted_string_re + '?)+')
result = 0
buffer = ''