]> git.kaiwu.me - njs.git/commitdiff
RegExp: fixed a case when lastIndex is greater than string size.
authorValentin Bartenev <vbart@nginx.com>
Mon, 12 Nov 2018 14:22:14 +0000 (17:22 +0300)
committerValentin Bartenev <vbart@nginx.com>
Mon, 12 Nov 2018 14:22:14 +0000 (17:22 +0300)
Previously, it resulted in: "InternalError: pcre_exec() failed: -32" due to
negative string size caused by subtraction of last_index.

njs/njs_regexp.c
njs/test/njs_unit_test.c

index 8ac7c42e156de8274b0f0e0324b1036431ed6284..461cc49f19009a2818dcd83ad2c8a7e0c1b2b61e 100644 (file)
@@ -644,42 +644,44 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
 
     (void) njs_string_prop(&string, value);
 
-    utf8 = NJS_STRING_BYTE;
-    type = NJS_REGEXP_BYTE;
+    if (string.size >= regexp->last_index) {
+        utf8 = NJS_STRING_BYTE;
+        type = NJS_REGEXP_BYTE;
 
-    if (string.length != 0) {
-        utf8 = NJS_STRING_ASCII;
-        type = NJS_REGEXP_UTF8;
+        if (string.length != 0) {
+            utf8 = NJS_STRING_ASCII;
+            type = NJS_REGEXP_UTF8;
 
-        if (string.length != string.size) {
-            utf8 = NJS_STRING_UTF8;
+            if (string.length != string.size) {
+                utf8 = NJS_STRING_UTF8;
+            }
         }
-    }
 
-    pattern = regexp->pattern;
+        pattern = regexp->pattern;
 
-    if (nxt_regex_is_valid(&pattern->regex[type])) {
-        string.start += regexp->last_index;
-        string.size -= regexp->last_index;
+        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;
-        }
+            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;
+            }
 
-        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);
-        }
+            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);
+            }
 
-        if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) {
-            nxt_regex_match_data_free(match_data, vm->regex_context);
+            if (nxt_slow_path(ret != NXT_REGEX_NOMATCH)) {
+                nxt_regex_match_data_free(match_data, vm->regex_context);
 
-            return NXT_ERROR;
+                return NXT_ERROR;
+            }
         }
     }
 
index 4033e2af6be557de31a0926487c92ece54ee47d6..73c8dbca7d6d9c8a66abd458e1212fce45e9a366 100644 (file)
@@ -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 +' '+ "