details: http://hg.nginx.org/njs/rev/f1da98bdd82f branches: changeset: 647:f1da98bdd82f user: Valentin Bartenev <vb...@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 +' '+ " _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel