From c5df3f073ee69e297c2c3942d460a75284559a0b Mon Sep 17 00:00:00 2001 From: Andrew Krasichkov Date: Sun, 14 May 2017 14:33:38 +0300 Subject: [PATCH] Improved regex for "if" directive condition capturing --- gixy/parser/raw_parser.py | 10 +++++----- tests/parser/test_raw_parser.py | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/gixy/parser/raw_parser.py b/gixy/parser/raw_parser.py index 349f3a1..96cd992 100644 --- a/gixy/parser/raw_parser.py +++ b/gixy/parser/raw_parser.py @@ -57,15 +57,15 @@ class RawParser(object): Keyword("=") | Keyword("~*") | Keyword("~") | (Literal("-") + (Literal("f") | Literal("d") | Literal("e") | Literal("x"))))) + # This ugly workaround needed to parse unquoted regex with nested parentheses + # so we capture all content between parentheses and then parse it :( + # TODO(buglloc): may be use something better? condition_body = ( (if_modifier + Optional(space) + value) | (variable + Optional(space + if_modifier + Optional(space) + value)) ) - # This ugly workaround needed to parse unquoted regex with nested parentheses - # pyparsing.nestedExpr doesn't work in some rare cases like: ($http_user_agent ~* \( ) - # so we capture all content between parentheses and then parse it:) - # TODO(buglloc): may be use something better? - condition = Regex(r'\(.*\)').setParseAction(lambda s, l, t: condition_body.parseString(t[0][1:-1])) + condition = Regex(r'\((?:[^();\n\r\\]|(?:\(.*\))|(?:\\.))+?\)')\ + .setParseAction(lambda s, l, t: condition_body.parseString(t[0][1:-1])) # rules include = ( diff --git a/tests/parser/test_raw_parser.py b/tests/parser/test_raw_parser.py index c29b7cf..4a328c6 100644 --- a/tests/parser/test_raw_parser.py +++ b/tests/parser/test_raw_parser.py @@ -234,6 +234,8 @@ if ($host ~* (lori|rage2)\.yandex\.(ru|ua|com|com\.tr)) { if ($request_filename ~* ^.*?/(\d+_)([^/]+)$) { } + +if ($foo = "BAR") { rewrite ^(.*)$ /bar; } ''' expected = [ @@ -262,6 +264,9 @@ if ($request_filename ~* ^.*?/(\d+_)([^/]+)$) { ['set', '$x_frame_options', 'ALLOW'] ]], ['if', ['$request_filename', '~*', '^.*?/(\d+_)([^/]+)$'], [ + ]], + ['if', ['$foo', '=', 'BAR'], [ + ['rewrite', '^(.*)$', '/bar'] ]] ]