Welcome! Log In Create A New Profile

Advanced

[njs] Fixed RegExpBuiltinExec() with global flag and byte-strings.

Dmitry Volyntsev
September 01, 2020 01:34PM
details: https://hg.nginx.org/njs/rev/e03701b6e8aa
branches:
changeset: 1514:e03701b6e8aa
user: Dmitry Volyntsev <xeioex@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(&regexp->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(&regexp->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)"),
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Fixed RegExpBuiltinExec() with global flag and byte-strings.

Dmitry Volyntsev 108 September 01, 2020 01:34PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 75
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready