[njs] RegExp: fixed a case when lastIndex is greater than string size.

Valentin Bartenev vbart at nginx.com
Mon Nov 12 14:23:04 UTC 2018


details:   http://hg.nginx.org/njs/rev/f1da98bdd82f
branches:  
changeset: 647:f1da98bdd82f
user:      Valentin Bartenev <vbart at nginx.com>
date:      Mon Nov 12 17:22:14 2018 +0300
description:
RegExp: fixed a case when lastIndex is greater than string size.

Previously, it resulted in: "InternalError: pcre_exec() failed: -32" due to
negative string size caused by subtraction of last_index.

diffstat:

 njs/njs_regexp.c         |  62 ++++++++++++++++++++++++-----------------------
 njs/test/njs_unit_test.c |   3 ++
 2 files changed, 35 insertions(+), 30 deletions(-)

diffs (91 lines):

diff -r 7d06ada396d7 -r f1da98bdd82f njs/njs_regexp.c
--- a/njs/njs_regexp.c	Fri Nov 09 18:22:01 2018 +0300
+++ b/njs/njs_regexp.c	Mon Nov 12 17:22:14 2018 +0300
@@ -644,42 +644,44 @@ njs_regexp_prototype_exec(njs_vm_t *vm, 
 
     (void) njs_string_prop(&string, value);
 
-    utf8 = NJS_STRING_BYTE;
-    type = NJS_REGEXP_BYTE;
-
-    if (string.length != 0) {
-        utf8 = NJS_STRING_ASCII;
-        type = NJS_REGEXP_UTF8;
-
-        if (string.length != string.size) {
-            utf8 = NJS_STRING_UTF8;
-        }
-    }
+    if (string.size >= regexp->last_index) {
+        utf8 = NJS_STRING_BYTE;
+        type = NJS_REGEXP_BYTE;
 
-    pattern = regexp->pattern;
-
-    if (nxt_regex_is_valid(&pattern->regex[type])) {
-        string.start += regexp->last_index;
-        string.size -= regexp->last_index;
+        if (string.length != 0) {
+            utf8 = NJS_STRING_ASCII;
+            type = NJS_REGEXP_UTF8;
 
-        match_data = nxt_regex_match_data(&pattern->regex[type],
-                                          vm->regex_context);
-        if (nxt_slow_path(match_data == NULL)) {
-            njs_memory_error(vm);
-            return NXT_ERROR;
+            if (string.length != string.size) {
+                utf8 = NJS_STRING_UTF8;
+            }
         }
 
-        ret = njs_regexp_match(vm, &pattern->regex[type], string.start,
-                               string.size, match_data);
-        if (ret >= 0) {
-            return njs_regexp_exec_result(vm, regexp, utf8, string.start,
-                                          match_data);
-        }
+        pattern = regexp->pattern;
+
+        if (nxt_regex_is_valid(&pattern->regex[type])) {
+            string.start += regexp->last_index;
+            string.size -= regexp->last_index;
+
+            match_data = nxt_regex_match_data(&pattern->regex[type],
+                                              vm->regex_context);
+            if (nxt_slow_path(match_data == NULL)) {
+                njs_memory_error(vm);
+                return NXT_ERROR;
+            }
 
-        if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) {
-            nxt_regex_match_data_free(match_data, vm->regex_context);
+            ret = njs_regexp_match(vm, &pattern->regex[type], string.start,
+                                   string.size, match_data);
+            if (ret >= 0) {
+                return njs_regexp_exec_result(vm, regexp, utf8, string.start,
+                                              match_data);
+            }
 
-            return NXT_ERROR;
+            if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) {
+                nxt_regex_match_data_free(match_data, vm->regex_context);
+
+                return NXT_ERROR;
+            }
         }
     }
 
diff -r 7d06ada396d7 -r f1da98bdd82f njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Nov 09 18:22:01 2018 +0300
+++ b/njs/test/njs_unit_test.c	Mon Nov 12 17:22:14 2018 +0300
@@ -5973,6 +5973,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = /^$/.exec(''); a.length +' '+ a"),
       nxt_string("1 ") },
 
+    { nxt_string("var r = /3/g; r.exec('123') +' '+ r.exec('3')"),
+      nxt_string("3 null") },
+
     { nxt_string("var r = /бв/ig;"
                  "var a = r.exec('АБВ');"
                  "r.lastIndex +' '+ a +' '+ "


More information about the nginx-devel mailing list