[njs] Fixed RegExpBuiltinExec() with global flag and byte-strings.
Dmitry Volyntsev
xeioex at nginx.com
Tue Sep 1 17:32:51 UTC 2020
details: https://hg.nginx.org/njs/rev/e03701b6e8aa
branches:
changeset: 1514:e03701b6e8aa
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Sep 01 17:25:33 2020 +0000
description:
Fixed RegExpBuiltinExec() with global flag and byte-strings.
The issue was introduced in f9082cd59ba6 (0.4.2). Since 1c729f765cfb
(0.4.2) RegExp.prototype[Symbol.replace] with a regexp with the global
flag may result in an endless loop for byte-strings with broken UTF8
encoding.
diffstat:
src/njs_regexp.c | 20 +++++++++++++++++---
src/test/njs_unit_test.c | 14 ++++++++++++--
2 files changed, 29 insertions(+), 5 deletions(-)
diffs (70 lines):
diff -r d00a6ec5a39a -r e03701b6e8aa src/njs_regexp.c
--- a/src/njs_regexp.c Tue Sep 01 16:37:33 2020 +0000
+++ b/src/njs_regexp.c Tue Sep 01 17:25:33 2020 +0000
@@ -929,6 +929,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs
int *captures;
u_char *start;
int32_t size, length;
+ uint32_t index;
njs_int_t ret;
njs_uint_t i, n;
njs_array_t *array;
@@ -982,11 +983,24 @@ njs_regexp_exec_result(njs_vm_t *vm, njs
goto fail;
}
- njs_set_number(&prop->value, njs_string_index(string, captures[0]));
+ if (type == NJS_REGEXP_UTF8) {
+ index = njs_string_index(string, captures[0]);
+
+ } else {
+ index = captures[0];
+ }
+
+ njs_set_number(&prop->value, index);
if (pattern->global) {
- njs_set_number(®exp->last_index,
- njs_string_index(string, captures[1]));
+ if (type == NJS_REGEXP_UTF8) {
+ index = njs_string_index(string, captures[1]);
+
+ } else {
+ index = captures[1];
+ }
+
+ njs_set_number(®exp->last_index, index);
}
lhq.key_hash = NJS_INDEX_HASH;
diff -r d00a6ec5a39a -r e03701b6e8aa src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Sep 01 16:37:33 2020 +0000
+++ b/src/test/njs_unit_test.c Tue Sep 01 17:25:33 2020 +0000
@@ -8307,6 +8307,12 @@ static njs_unit_test_t njs_test[] =
{ njs_str("RegExp.prototype[Symbol.replace].call(/b/, 'abc','B')"),
njs_str("aBc") },
+ { njs_str("String.bytesFrom([253,242,141,10]).replace(/\\s/g, 'X')[3]"),
+ njs_str("X") },
+
+ { njs_str("String.bytesFrom([255,149,15,97,95]).replace(/_/g, 'X')[4]"),
+ njs_str("X") },
+
{ njs_str("/]/"),
njs_str("/\\]/") },
@@ -10327,8 +10333,12 @@ static njs_unit_test_t njs_test[] =
#endif
{ njs_str("var r = /\\x80/g; r.exec('\\u0081\\u0080'.toBytes());"
- "r.lastIndex +' '+ r.source +' '+ r.source.length +' '+ r"),
- njs_str("1 \\x80 4 /\\x80/g") },
+ "r.lastIndex +' '+ r.source +' '+ r.source.length +' '+ r"),
+ njs_str("2 \\x80 4 /\\x80/g") },
+
+ { njs_str("var r = /_/g; var index = r.exec(String.bytesFrom([255,149,15,97,95])).index;"
+ "[index, r.lastIndex]"),
+ njs_str("4,5") },
{ njs_str("var descs = Object.getOwnPropertyDescriptors(RegExp('a'));"
"Object.keys(descs)"),
More information about the nginx-devel
mailing list