Dmitry Volyntsev
March 03, 2023 09:52PM
details: https://hg.nginx.org/njs/rev/7ad9dd5da3fb
branches:
changeset: 2063:7ad9dd5da3fb
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Fri Mar 03 17:49:11 2023 -0800
description:
Fixed Array.prototype.sort() when array is changed while sorting.

Previously, the fast-path check did not take into account the fact that
the flat array may be resized as a side effect of the array's values
evaluation.

In addition, the slow_path fix ensures that "this" array is repopulated
again even if the array was resized.

This fixes #594 issue on Github.

diffstat:

src/njs_array.c | 13 +++++++------
src/test/njs_unit_test.c | 28 ++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 6 deletions(-)

diffs (68 lines):

diff -r 163229f0c552 -r 7ad9dd5da3fb src/njs_array.c
--- a/src/njs_array.c Fri Mar 03 17:49:10 2023 -0800
+++ b/src/njs_array.c Fri Mar 03 17:49:11 2023 -0800
@@ -2663,7 +2663,10 @@ slow_path:
goto exception;
}

- if (njs_fast_path(fast_path && njs_is_fast_array(this))) {
+ if (njs_fast_path(fast_path
+ && njs_is_fast_array(this)
+ && (njs_array(this)->length == length)))
+ {
array = njs_array(this);
start = array->start;

@@ -2677,11 +2680,9 @@ slow_path:

} else {
for (i = 0; i < len; i++) {
- if (slots[i].pos != i) {
- ret = njs_value_property_i64_set(vm, this, i, &slots[i].value);
- if (njs_slow_path(ret == NJS_ERROR)) {
- goto exception;
- }
+ ret = njs_value_property_i64_set(vm, this, i, &slots[i].value);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ goto exception;
}
}

diff -r 163229f0c552 -r 7ad9dd5da3fb src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Fri Mar 03 17:49:10 2023 -0800
+++ b/src/test/njs_unit_test.c Fri Mar 03 17:49:11 2023 -0800
@@ -7276,6 +7276,34 @@ static njs_unit_test_t njs_test[] =
{ njs_str("var a = [1,2]; a.sort(() => {a.length = 65535}); a.length"),
njs_str("65535") },

+ { njs_str("var a = [];"
+ "var shift = true;"
+ "for (let i = 0; i < 64; i++) {"
+ " a[i] = { toString() {"
+ " if (shift) { a.shift() };"
+ " return (63 - i).toString().padStart(2, '0');"
+ " }"
+ " };"
+ "}"
+ "a.sort();"
+ "shift = false;"
+ "[a.length, a[0].toString(), a[63].toString()]"),
+ njs_str("64,00,63") },
+
+ { njs_str("var a = [];"
+ "var shift = true;"
+ "for (let i = 0; i < 64; i++) {"
+ " a[i] = { toString() {"
+ " if (shift) { a.shift() };"
+ " return (i).toString().padStart(2, '0');"
+ " }"
+ " };"
+ "}"
+ "a.sort();"
+ "shift = false;"
+ "[a.length, a[0].toString(), a[63].toString()]"),
+ njs_str("64,00,63") },
+
/*
Array.prototype.keys()
Array.prototype.values()
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Fixed Array.prototype.sort() when array is changed while sorting.

Dmitry Volyntsev 346 March 03, 2023 09:52PM



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

Online Users

Guests: 198
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready