[njs] Parser: fixed parsing of regexp flags.

Dmitry Volyntsev xeioex at nginx.com
Thu Jul 2 14:01:35 UTC 2020


details:   https://hg.nginx.org/njs/rev/6345c07f1c52
branches:  
changeset: 1444:6345c07f1c52
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu Jul 02 12:58:50 2020 +0000
description:
Parser: fixed parsing of regexp flags.

diffstat:

 src/njs_parser.c         |   2 +-
 src/njs_regexp.c         |  32 ++++++++++----------------------
 src/njs_regexp.h         |   4 ++--
 src/test/njs_unit_test.c |  21 ++++++++++++++++++---
 4 files changed, 31 insertions(+), 28 deletions(-)

diffs (143 lines):

diff -r e8a941b394a3 -r 6345c07f1c52 src/njs_parser.c
--- a/src/njs_parser.c	Tue Jun 30 15:36:31 2020 +0000
+++ b/src/njs_parser.c	Thu Jul 02 12:58:50 2020 +0000
@@ -1247,7 +1247,7 @@ njs_parser_regexp_literal(njs_parser_t *
             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 -r e8a941b394a3 -r 6345c07f1c52 src/njs_regexp.c
--- a/src/njs_regexp.c	Tue Jun 30 15:36:31 2020 +0000
+++ b/src/njs_regexp.c	Thu Jul 02 12:58:50 2020 +0000
@@ -143,8 +143,10 @@ njs_regexp_constructor(njs_vm_t *vm, njs
 
         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 
             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 -r e8a941b394a3 -r 6345c07f1c52 src/njs_regexp.h
--- a/src/njs_regexp.h	Tue Jun 30 15:36:31 2020 +0000
+++ b/src/njs_regexp.h	Thu Jul 02 12:58:50 2020 +0000
@@ -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 -r e8a941b394a3 -r 6345c07f1c52 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Tue Jun 30 15:36:31 2020 +0000
+++ b/src/test/njs_unit_test.c	Thu Jul 02 12:58:50 2020 +0000
@@ -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]/") },
 


More information about the nginx-devel mailing list