From 86c8fb141049fe704b99f1904fc3620c6b5ed4e4 Mon Sep 17 00:00:00 2001 From: Ceesjan Luiten Date: Fri, 10 Jul 2015 22:54:54 +0200 Subject: [PATCH] Do not silently truncate nginx config files --- .../letsencrypt_nginx/nginxparser.py | 4 ++-- .../letsencrypt_nginx/tests/nginxparser_test.py | 6 ++++++ .../tests/testdata/etc_nginx/broken.conf | 12 ++++++++++++ letsencrypt-nginx/letsencrypt_nginx/tests/util.py | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 letsencrypt-nginx/letsencrypt_nginx/tests/testdata/etc_nginx/broken.conf diff --git a/letsencrypt-nginx/letsencrypt_nginx/nginxparser.py b/letsencrypt-nginx/letsencrypt_nginx/nginxparser.py index f24455d59..6cce8d03a 100644 --- a/letsencrypt-nginx/letsencrypt_nginx/nginxparser.py +++ b/letsencrypt-nginx/letsencrypt_nginx/nginxparser.py @@ -4,7 +4,7 @@ import string from pyparsing import ( Literal, White, Word, alphanums, CharsNotIn, Forward, Group, Optional, OneOrMore, Regex, ZeroOrMore, pythonStyleComment) - +from pyparsing import stringEnd class RawNginxParser(object): # pylint: disable=expression-not-assigned @@ -35,7 +35,7 @@ class RawNginxParser(object): + Group(ZeroOrMore(Group(assignment) | block)) + right_bracket) - script = OneOrMore(Group(assignment) | block).ignore(pythonStyleComment) + script = (OneOrMore(Group(assignment) | block) + stringEnd).ignore(pythonStyleComment) def __init__(self, source): self.source = source diff --git a/letsencrypt-nginx/letsencrypt_nginx/tests/nginxparser_test.py b/letsencrypt-nginx/letsencrypt_nginx/tests/nginxparser_test.py index 73a89534b..59bb070b2 100644 --- a/letsencrypt-nginx/letsencrypt_nginx/tests/nginxparser_test.py +++ b/letsencrypt-nginx/letsencrypt_nginx/tests/nginxparser_test.py @@ -2,6 +2,8 @@ import operator import unittest +from pyparsing import ParseException + from letsencrypt_nginx.nginxparser import ( RawNginxParser, load, dumps, dump) from letsencrypt_nginx.tests import util @@ -104,6 +106,10 @@ class TestRawNginxParser(unittest.TestCase): ['blah', '"hello;world"'], ['try_files', '$uri @rewrites']]]]]]) + def test_abort_on_parse_failure(self): + with open(util.get_data_filename('broken.conf')) as handle: + self.assertRaises(ParseException, load, handle) + def test_dump_as_file(self): parsed = load(open(util.get_data_filename('nginx.conf'))) parsed[-1][-1].append([['server'], diff --git a/letsencrypt-nginx/letsencrypt_nginx/tests/testdata/etc_nginx/broken.conf b/letsencrypt-nginx/letsencrypt_nginx/tests/testdata/etc_nginx/broken.conf new file mode 100644 index 000000000..98aef55d6 --- /dev/null +++ b/letsencrypt-nginx/letsencrypt_nginx/tests/testdata/etc_nginx/broken.conf @@ -0,0 +1,12 @@ +# A faulty configuration file + +pid logs/nginx.pid; + + +events { + worker_connections 1024; +} + +include foo.conf; + +@@@ diff --git a/letsencrypt-nginx/letsencrypt_nginx/tests/util.py b/letsencrypt-nginx/letsencrypt_nginx/tests/util.py index a7db398c6..e7675f34d 100644 --- a/letsencrypt-nginx/letsencrypt_nginx/tests/util.py +++ b/letsencrypt-nginx/letsencrypt_nginx/tests/util.py @@ -59,3 +59,18 @@ def get_nginx_configurator( version=version) config.prepare() return config + + +def filter_comments(tree): + """Filter comment nodes from parsed configurations.""" + + def traverse(tree): + """Generator dropping comment nodes""" + for key, values in tree: + if isinstance(key, list): + yield [key, filter_comments(values)] + else: + if key != '#': + yield [key, values] + + return list(traverse(tree))