details: https://hg.nginx.org/njs/rev/7ad9dd5da3fb branches: changeset: 2063:7ad9dd5da3fb user: Dmitry Volyntsev <xei...@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