Skip to content

Commit

Permalink
Merge pull request #102 from tonioo/fix/control_args
Browse files Browse the repository at this point in the history
Fixed issues with test and control arguments.
  • Loading branch information
tonioo authored Dec 7, 2020
2 parents 264e97a + 6d30a86 commit cc76519
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 18 deletions.
50 changes: 32 additions & 18 deletions sievelib/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,30 @@ def __up(self, onlyrecord=False):
self.hash_comments = []
self.result += [self.__curcommand]

if not onlyrecord:
while self.__curcommand:
self.__curcommand = self.__curcommand.parent
# Make sure to detect all done tests (including 'not' ones).
condition = (
self.__curcommand and
self.__curcommand.get_type() == "test" and
self.__curcommand.iscomplete()
)
if condition:
continue
if onlyrecord:
# We are done
return

while self.__curcommand:
self.__curcommand = self.__curcommand.parent
if not self.__curcommand:
break
# Make sure to detect all done tests (including 'not' ones).
condition = (
self.__curcommand.get_type() == "test" and
self.__curcommand.iscomplete()
)
if condition:
continue
# If we are on a control accepting a test list, next token
# must be a comma or a right parenthesis.
condition = (
self.__curcommand.get_type() == "test" and
self.__curcommand.variable_args_nb
)
if condition:
self.__set_expected("comma", "right_parenthesis")
break

def __check_command_completion(self, testsemicolon=True):
"""Check for command(s) completion
Expand All @@ -224,9 +236,11 @@ def __check_command_completion(self, testsemicolon=True):
return True

ctype = self.__curcommand.get_type()
if ctype == "action" or \
(ctype == "control" and
not self.__curcommand.accept_children):
condition = (
ctype == "action" or
(ctype == "control" and not self.__curcommand.accept_children)
)
if condition:
if testsemicolon:
self.__set_expected("semicolon")
return True
Expand All @@ -237,6 +251,7 @@ def __check_command_completion(self, testsemicolon=True):
if self.__curcommand.get_type() in ["control", "test"]:
if self.__curcommand.iscomplete():
if self.__curcommand.get_type() == "control":
self.__set_expected("left_cbracket")
break
continue
if not self.__curcommand.check_next_arg("test", cmd, add=False):
Expand All @@ -245,7 +260,6 @@ def __check_command_completion(self, testsemicolon=True):
if self.__curcommand.variable_args_nb:
self.__set_expected("comma", "right_parenthesis")
break

return True

def __stringlist(self, ttype, tvalue):
Expand Down Expand Up @@ -442,9 +456,9 @@ def parse(self, text):
if ttype not in self.__expected:
if self.lexer.pos < len(text) + len(tvalue):
msg = (
"%s found while %s expected near '%s'"
% (ttype, "|".join(self.__expected),
text[self.lexer.pos])
"{} found while {} expected near '{}'"
.format(ttype, "|".join(self.__expected),
text.decode()[self.lexer.pos])
)
else:
msg = (
Expand Down
15 changes: 15 additions & 0 deletions sievelib/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,11 @@ def test_singletest_testlist(self):
discard (type: action)
""")

def test_multitest_testlist(self):
self.compilation_ok(b"""
if anyof(allof(address :contains "From" ""), allof(header :contains "Subject" "")) {}
""")

def test_truefalse_testlist(self):
self.compilation_ok(b"""
if anyof(true, false) {
Expand Down Expand Up @@ -696,6 +701,16 @@ def test_control_command_in_test(self):
if stop;
""")

def test_extra_test_in_simple_control(self):
self.compilation_ko(b"""
if address "From" "example.com" header "Subject" "Example" { stop; }
""")

def test_missing_comma_in_test_list(self):
self.compilation_ko(b"""
if allof(anyof(address "From" "example.com") header "Subject" "Example") { stop; }
""")


class LanguageRestrictions(SieveTest):
def test_unknown_control(self):
Expand Down

0 comments on commit cc76519

Please sign in to comment.