From: Dmitry Volyntsev Date: Thu, 2 Jul 2020 12:58:50 +0000 (+0000) Subject: Parser: fixed parsing of regexp flags. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=f90f1530824176be41e6c1892c2c3bd1674e2f81;p=njs.git Parser: fixed parsing of regexp flags. --- diff --git a/src/njs_parser.c b/src/njs_parser.c index d022fcf1..89ab9bf9 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -1247,7 +1247,7 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token, p++; lexer->start = p; - flags = njs_regexp_flags(&p, lexer->end, 0); + flags = njs_regexp_flags(&p, lexer->end); if (njs_slow_path(flags < 0)) { njs_parser_syntax_error(parser, "Invalid RegExp flags \"%*s\"", diff --git a/src/njs_regexp.c b/src/njs_regexp.c index 09603227..05a02031 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -143,8 +143,10 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, start = string.start; - re_flags = njs_regexp_flags(&start, start + string.length, 1); - if (njs_slow_path(re_flags < 0)) { + re_flags = njs_regexp_flags(&start, start + string.length); + if (njs_slow_path(re_flags < 0 + || (size_t) (start - string.start) != string.length)) + { njs_syntax_error(vm, "Invalid RegExp flags \"%V\"", &string); return NJS_ERROR; } @@ -305,17 +307,15 @@ done: njs_regexp_flags_t -njs_regexp_flags(u_char **start, u_char *end, njs_bool_t bound) +njs_regexp_flags(u_char **start, u_char *end) { u_char *p; njs_regexp_flags_t flags, flag; - flags = 0; + flags = NJS_REGEXP_NO_FLAGS; for (p = *start; p < end; p++) { - switch (*p) { - case 'g': flag = NJS_REGEXP_GLOBAL; break; @@ -328,24 +328,12 @@ njs_regexp_flags(u_char **start, u_char *end, njs_bool_t bound) flag = NJS_REGEXP_MULTILINE; break; - case ';': - case ' ': - case '\t': - case '\r': - case '\n': - case ',': - case ')': - case ']': - case '}': - case '.': - if (!bound) { - goto done; + default: + if (*p >= 'a' && *p <= 'z') { + goto invalid; } - /* Fall through. */ - - default: - goto invalid; + goto done; } if (njs_slow_path((flags & flag) != 0)) { diff --git a/src/njs_regexp.h b/src/njs_regexp.h index d284e299..500c6fa7 100644 --- a/src/njs_regexp.h +++ b/src/njs_regexp.h @@ -10,6 +10,7 @@ typedef enum { NJS_REGEXP_INVALID_FLAG = -1, + NJS_REGEXP_NO_FLAGS = 0, NJS_REGEXP_GLOBAL = 1, NJS_REGEXP_IGNORE_CASE = 2, NJS_REGEXP_MULTILINE = 4, @@ -19,8 +20,7 @@ typedef enum { njs_int_t njs_regexp_init(njs_vm_t *vm); njs_int_t njs_regexp_create(njs_vm_t *vm, njs_value_t *value, u_char *start, size_t length, njs_regexp_flags_t flags); -njs_regexp_flags_t njs_regexp_flags(u_char **start, u_char *end, - njs_bool_t bound); +njs_regexp_flags_t njs_regexp_flags(u_char **start, u_char *end); njs_regexp_pattern_t *njs_regexp_pattern_create(njs_vm_t *vm, u_char *string, size_t length, njs_regexp_flags_t flags); njs_int_t njs_regexp_match(njs_vm_t *vm, njs_regex_t *regex, diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 3604d76e..56c7c5f3 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -9487,9 +9487,6 @@ static njs_unit_test_t njs_test[] = /* RegExp. */ - { njs_str("/./x"), - njs_str("SyntaxError: Invalid RegExp flags \"x\" in 1") }, - { njs_str("/"), njs_str("SyntaxError: Unterminated RegExp \"/\" in 1") }, @@ -9526,6 +9523,15 @@ static njs_unit_test_t njs_test[] = { njs_str("/\\\n/"), njs_str("SyntaxError: Unterminated RegExp \"/\\\" in 1") }, + { njs_str("/./x"), + njs_str("SyntaxError: Invalid RegExp flags \"x\" in 1") }, + + { njs_str("/./.exec === RegExp.prototype.exec"), + njs_str("true") }, + + { njs_str("/./['exec'] === RegExp.prototype.exec"), + njs_str("true") }, + { njs_str("/^[A-Za-z0-9+/]{4}$/.test('////')"), njs_str("true") }, @@ -9736,6 +9742,15 @@ static njs_unit_test_t njs_test[] = { njs_str("new RegExp('', 'x')"), njs_str("SyntaxError: Invalid RegExp flags \"x\"") }, + { njs_str("new RegExp('', 'g ')"), + njs_str("SyntaxError: Invalid RegExp flags \"g \"") }, + + { njs_str("new RegExp('', '')"), + njs_str("/(?:)/") }, + + { njs_str("new RegExp('', {toString:()=>'g'})"), + njs_str("/(?:)/g") }, + { njs_str("RegExp({})"), njs_str("/[object Object]/") },