From: Alexander Borisov Date: Wed, 15 May 2019 09:51:31 +0000 (+0300) Subject: Fixed regexp literals parsing. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=7cbff0c652b6bcc630318c2d9316a407a5f91e4b;p=njs.git Fixed regexp literals parsing. Problems were observed: 1. Escaping symbols: /\\\\/ 2. Solidus symbol ('/') in square bracket: /[/]/ This closes #149 issue on GitHub. --- diff --git a/njs/njs_regexp.c b/njs/njs_regexp.c index bc1544ce..19c7ae75 100644 --- a/njs/njs_regexp.c +++ b/njs/njs_regexp.c @@ -209,7 +209,7 @@ njs_regexp_create(njs_vm_t *vm, njs_value_t *value, u_char *start, njs_token_t njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value) { - u_char *p, c; + u_char *p; nxt_str_t text; njs_lexer_t *lexer; njs_regexp_flags_t flags; @@ -219,13 +219,37 @@ njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value) for (p = lexer->start; p < lexer->end; p++) { - c = *p; + switch (*p) { + case '\n': + case '\r': + goto failed; + + case '[': + while (++p < lexer->end && *p != ']') { + switch (*p) { + case '\n': + case '\r': + goto failed; + + case '\\': + if (++p < lexer->end && (*p == '\n' || *p == '\r')) { + goto failed; + } + + break; + } + } - if (c == '\n' || c == '\r') { break; - } - if (c == '/' && !(p > lexer->start && p[-1] == '\\')) { + case '\\': + if (++p < lexer->end && (*p == '\n' || *p == '\r')) { + goto failed; + } + + break; + + case '/': text.start = lexer->start; text.length = p - text.start; p++; @@ -255,6 +279,8 @@ njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value) } } +failed: + njs_parser_syntax_error(vm, parser, "Unterminated RegExp \"%*s\"", p - (lexer->start - 1), lexer->start - 1); diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 8730f8a7..02bc3c16 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -7073,6 +7073,37 @@ static njs_unit_test_t njs_test[] = { nxt_string("/a\\q/"), nxt_string("/a\\q/") }, + { nxt_string("/\\\\/"), + nxt_string("/\\\\/") }, + + { nxt_string("/\\\\\\/"), + nxt_string("SyntaxError: Unterminated RegExp \"/\\\\\\/\" in 1") }, + + { nxt_string("/\\\\\\\\/"), + nxt_string("/\\\\\\\\/") }, + + { nxt_string("/\\\\\\//"), + nxt_string("/\\\\\\//") }, + + { nxt_string("/[A-Z/]/"), + nxt_string("/[A-Z/]/") }, + + { nxt_string("/[A-Z\n]/"), + nxt_string("SyntaxError: Unterminated RegExp \"/[A-Z\" in 1") }, + + { nxt_string("/[A-Z\\\n]/"), + nxt_string("SyntaxError: Unterminated RegExp \"/[A-Z\\\" in 1") }, + + { nxt_string("/\\\n/"), + nxt_string("SyntaxError: Unterminated RegExp \"/\\\" in 1") }, + + { nxt_string("/^[A-Za-z0-9+/]{4}$/.test('////')"), + nxt_string("true") }, + + { nxt_string("'[]!\"#$%&\\'()*+,.\\/:;<=>?@\\^_`{|}-'.split('')" + ".every(ch=>/[\\]\\[!\"#$%&'()*+,.\\/:;<=>?@\\^_`{|}-]/.test(ch))"), + nxt_string("true") }, + { nxt_string("/a\\q/.test('a\\q')"), nxt_string("true") },