Valentin Bartenev
2018-11-12 14:23:04 UTC
details: http://hg.nginx.org/njs/rev/f1da98bdd82f
branches:
changeset: 647:f1da98bdd82f
user: Valentin Bartenev <***@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 +' '+ "
branches:
changeset: 647:f1da98bdd82f
user: Valentin Bartenev <***@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 +' '+ "