From b7cf9288524cd9ec717f6c88d2b26226d8d04bf0 Mon Sep 17 00:00:00 2001 From: Peter Eckersley Date: Wed, 13 Jul 2016 17:17:45 -0700 Subject: [PATCH] Parse charset_map correctly (though we still don't emit it correctly...) --- .../chive/chive-nginx-master/win-utf | 1 + certbot-nginx/certbot_nginx/nginxparser.py | 27 ++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/certbot-compatibility-test/nginx/nginx-roundtrip-testdata/chive/chive-nginx-master/win-utf b/certbot-compatibility-test/nginx/nginx-roundtrip-testdata/chive/chive-nginx-master/win-utf index ed8bc007a..e4b1e8360 100644 --- a/certbot-compatibility-test/nginx/nginx-roundtrip-testdata/chive/chive-nginx-master/win-utf +++ b/certbot-compatibility-test/nginx/nginx-roundtrip-testdata/chive/chive-nginx-master/win-utf @@ -2,6 +2,7 @@ # This map is not a full windows-1251 <> utf8 map: it does not # contain Serbian and Macedonian letters. If you need a full map, # use contrib/unicode2nginx/win-utf map instead. +# charset_map windows-1251 utf-8 { diff --git a/certbot-nginx/certbot_nginx/nginxparser.py b/certbot-nginx/certbot_nginx/nginxparser.py index 1859777d8..10a26ecb2 100644 --- a/certbot-nginx/certbot_nginx/nginxparser.py +++ b/certbot-nginx/certbot_nginx/nginxparser.py @@ -40,6 +40,7 @@ class RawNginxParser(object): assignment = space + key + Optional(space + value, default=None) + semicolon location_statement = space + Optional(modifier) + Optional(space + location + space) if_statement = space + Literal("if") + space + condition + space + charset_map_statement = space + Literal("charset_map") + space + value + space + value map_statement = space + Literal("map") + space + nonspace + space + dollar_var + space # This is NOT an accurate way to parse nginx map entries; it's almost @@ -52,28 +53,36 @@ class RawNginxParser(object): map_pattern = Regex(r'".*"') | Regex(r"'.*'") | nonspace map_entry = space + map_pattern + space + value + space + semicolon map_block = Group( - # key could for instance be "server" or "http", or "location" (in which case - # location_statement needs to have a non-empty location) Group(map_statement).leaveWhitespace() + left_bracket + Group(ZeroOrMore(Group(comment | map_entry)) + space).leaveWhitespace() + right_bracket) block = Forward() - block << Group( - # key could for instance be "server" or "http", or "location" (in which case - # location_statement needs to have a non-empty location) - (Group(space + key + location_statement) ^ Group(if_statement)).leaveWhitespace() + - left_bracket + - Group(ZeroOrMore(Group(comment | assignment) | block | map_block) + space).leaveWhitespace() - + right_bracket) + + # key could for instance be "server" or "http", or "location" (in which case + # location_statement needs to have a non-empty location) + + block_begin = (Group(space + key + location_statement) ^ + Group(if_statement) ^ + Group(charset_map_statement)).leaveWhitespace() + + block_innards = Group(ZeroOrMore(Group(comment | assignment) | block | map_block) + + space).leaveWhitespace() + + block << Group(block_begin + left_bracket + block_innards + right_bracket) script = OneOrMore(Group(comment | assignment) ^ block ^ map_block) + space + stringEnd script.parseWithTabs() + testLine = OneOrMore(Group(space + key + location_statement)).leaveWhitespace() + testTwo = OneOrMore(block) def __init__(self, source): self.source = source + def test(self): + return self.testLine.parseString(self.source) + def parse(self): """Returns the parsed tree.""" return self.script.parseString(self.source)