Previously, when exactly 32 characters unicode string was provided and
the "lastIndex" value of "this" regexp was equal to 32 too, the
njs_string_utf8_offset() was called with invalid index argument (longer
than a size of the string). As a result njs_string_utf8_offset()
returned garbage values.
This was manifested in the following ways:
1) InternalError: pcre2_match() failed: bad offset value
2) Very slow replace calls with global regexps, for
example in expressions like: str.replace(/<re>/g).
This fixes #677 on Github.
offset = last_index;
} else {
- offset = njs_string_utf8_offset(string.start,
- string.start + string.size, last_index)
- - string.start;
+ if ((size_t) last_index < string.length) {
+ offset = njs_string_utf8_offset(string.start,
+ string.start + string.size,
+ last_index)
+ - string.start;
+ } else {
+ offset = string.size;
+ }
}
ret = njs_regexp_match(vm, &pattern->regex[type], string.start, offset,
{ njs_str("'abc'.replaceAll(/^/g, '|$&|')"),
njs_str("||abc") },
+ { njs_str("('α'.repeat(30) + 'aa').replace(/a/g, '#')"),
+ njs_str("αααααααααααααααααααααααααααααα##") },
+
+ { njs_str("('α'.repeat(30) + 'aa').replaceAll(/a/g, '#')"),
+ njs_str("αααααααααααααααααααααααααααααα##") },
+
{ njs_str("var uri ='/u/v1/Aa/bB?type=m3u8&mt=42';"
"uri.replace(/^\\/u\\/v1\\/[^/]*\\/([^\?]*)\\?.*(mt=[^&]*).*$/, '$1|$2')"),
njs_str("bB|mt=42") },