From: Dmitry Volyntsev Date: Sat, 4 Mar 2023 01:49:11 +0000 (-0800) Subject: Fixed Array.prototype.sort() when array is changed while sorting. X-Git-Tag: 0.7.11~6 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=5f4b5f2713b19ebf4524191309eb81eeb28205e3;p=njs.git 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. --- diff --git a/src/njs_array.c b/src/njs_array.c index 0eb3276f..7418a35c 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -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 --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index beb2cea6..dc12f8f8 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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()