details: https://hg.nginx.org/njs/rev/d62db2c99851 branches: changeset: 1170:d62db2c99851 user: Dmitry Volyntsev <xei...@nginx.com> date: Fri Oct 04 17:19:06 2019 +0300 description: Fixed Regexp.prototype.test() for regexps with backreferences.
This closes #225 issue on Github. diffstat: src/njs_pcre.c | 18 ++++++++++++++++++ src/njs_pcre.h | 1 + src/njs_regex.h | 1 + src/njs_regexp.c | 42 ++++++++++++++++++++++++++++++++---------- src/test/njs_unit_test.c | 4 ++++ 5 files changed, 56 insertions(+), 10 deletions(-) diffs (139 lines): diff -r 956b24477d59 -r d62db2c99851 src/njs_pcre.c --- a/src/njs_pcre.c Thu Oct 03 16:59:22 2019 +0300 +++ b/src/njs_pcre.c Fri Oct 04 17:19:06 2019 +0300 @@ -111,6 +111,17 @@ njs_regex_compile(njs_regex_t *regex, u_ goto done; } + err = pcre_fullinfo(regex->code, NULL, PCRE_INFO_BACKREFMAX, + ®ex->backrefmax); + + if (njs_slow_path(err < 0)) { + njs_alert(ctx->trace, NJS_LEVEL_ERROR, + "pcre_fullinfo(\"%s\", PCRE_INFO_BACKREFMAX) failed: %d", + pattern, err); + + goto done; + } + /* Reserve additional elements for the first "$0" capture. */ regex->ncaptures++; @@ -175,6 +186,13 @@ njs_regex_ncaptures(njs_regex_t *regex) } +njs_uint_t +njs_regex_backrefs(njs_regex_t *regex) +{ + return regex->backrefmax; +} + + njs_int_t njs_regex_named_captures(njs_regex_t *regex, njs_str_t *name, int n) { diff -r 956b24477d59 -r d62db2c99851 src/njs_pcre.h --- a/src/njs_pcre.h Thu Oct 03 16:59:22 2019 +0300 +++ b/src/njs_pcre.h Fri Oct 04 17:19:06 2019 +0300 @@ -18,6 +18,7 @@ struct njs_regex_s { pcre *code; pcre_extra *extra; int ncaptures; + int backrefmax; int nentries; int entry_size; char *entries; diff -r 956b24477d59 -r d62db2c99851 src/njs_regex.h --- a/src/njs_regex.h Thu Oct 03 16:59:22 2019 +0300 +++ b/src/njs_regex.h Fri Oct 04 17:19:06 2019 +0300 @@ -31,6 +31,7 @@ NJS_EXPORT njs_int_t njs_regex_compile(n size_t len, njs_uint_t options, njs_regex_context_t *ctx); NJS_EXPORT njs_bool_t njs_regex_is_valid(njs_regex_t *regex); NJS_EXPORT njs_uint_t njs_regex_ncaptures(njs_regex_t *regex); +NJS_EXPORT njs_uint_t njs_regex_backrefs(njs_regex_t *regex); NJS_EXPORT njs_int_t njs_regex_named_captures(njs_regex_t *regex, njs_str_t *name, int n); NJS_EXPORT njs_regex_match_data_t *njs_regex_match_data(njs_regex_t *regex, diff -r 956b24477d59 -r d62db2c99851 src/njs_regexp.c --- a/src/njs_regexp.c Thu Oct 03 16:59:22 2019 +0300 +++ b/src/njs_regexp.c Fri Oct 04 17:19:06 2019 +0300 @@ -842,11 +842,13 @@ static njs_int_t njs_regexp_prototype_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { - njs_int_t ret; - njs_uint_t n; - const njs_value_t *value, *retval; - njs_string_prop_t string; - njs_regexp_pattern_t *pattern; + njs_int_t ret; + njs_uint_t n; + njs_regex_t *regex; + const njs_value_t *value, *retval; + njs_string_prop_t string; + njs_regexp_pattern_t *pattern; + njs_regex_match_data_t *match_data; if (!njs_is_regexp(njs_arg(args, nargs, 0))) { njs_type_error(vm, "\"this\" argument is not a regexp"); @@ -866,20 +868,40 @@ njs_regexp_prototype_test(njs_vm_t *vm, pattern = njs_regexp_pattern(&args[0]); - if (njs_regex_is_valid(&pattern->regex[n])) { - ret = njs_regexp_match(vm, &pattern->regex[n], string.start, - string.size, vm->single_match_data); + regex = &pattern->regex[n]; + match_data = vm->single_match_data; + + if (njs_regex_is_valid(regex)) { + if (njs_regex_backrefs(regex) != 0) { + match_data = njs_regex_match_data(regex, vm->regex_context); + if (njs_slow_path(match_data == NULL)) { + njs_memory_error(vm); + return NJS_ERROR; + } + } + + ret = njs_regexp_match(vm, regex, string.start, string.size, + match_data); if (ret >= 0) { retval = &njs_value_true; } else if (ret != NJS_REGEX_NOMATCH) { - return NJS_ERROR; + ret = NJS_ERROR; + goto done; } } + ret = NJS_OK; + vm->retval = *retval; - return NJS_OK; +done: + + if (match_data != vm->single_match_data) { + njs_regex_match_data_free(match_data, vm->regex_context); + } + + return ret; } diff -r 956b24477d59 -r d62db2c99851 src/test/njs_unit_test.c --- a/src/test/njs_unit_test.c Thu Oct 03 16:59:22 2019 +0300 +++ b/src/test/njs_unit_test.c Fri Oct 04 17:19:06 2019 +0300 @@ -8178,6 +8178,10 @@ static njs_unit_test_t njs_test[] = njs_str("true") }, #endif + { njs_str("var re = /<(?<key>[\\w\\-\\.\\:]+)>(?<body>.*?)<\\/\\1>/g;" + "['<A>XXX</A>', '<A>XX</B>'].map(s=>re.test(s))"), + njs_str("true,false") }, + { njs_str("/\\x80/.test('\\u0080')"), njs_str("true") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel