commit 7bae89a42b206c5aa5d29e7c1d262ebd8ec95e7e
parent a994dc86014ea032a7fa8b28dac301d66e98d100
Author: Fabrice Bellard <fabrice@bellard.org>
Date: Wed, 27 Dec 2023 17:13:44 +0100
fixed detached TypedArray in sort()
Diffstat:
3 files changed, 48 insertions(+), 46 deletions(-)
diff --git a/quickjs/TODO b/quickjs/TODO
@@ -1,6 +1,3 @@
-Bugs:
-- modules: better error handling with cyclic module references
-
Misc ideas:
- use custom printf to avoid compatibility issues with floating point numbers
- consistent naming for preprocessor defines
@@ -66,5 +63,5 @@ Optimization ideas:
Test262o: 0/11262 errors, 463 excluded
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
-Result: 35/75280 errors, 909 excluded, 585 skipped
+Result: 16/76387 errors, 1497 excluded, 8397 skipped
Test262 commit: 31126581e7290f9233c29cefd93f66c6ac78f1c9
diff --git a/quickjs/quickjs.c b/quickjs/quickjs.c
@@ -53436,7 +53436,7 @@ static JSValue js_TA_get_float64(JSContext *ctx, const void *a) {
struct TA_sort_context {
JSContext *ctx;
- int exception;
+ int exception; /* 1 = exception, 2 = detached typed array */
JSValueConst arr;
JSValueConst cmp;
JSValue (*getfun)(JSContext *ctx, const void *a);
@@ -53454,6 +53454,8 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) {
cmp = 0;
if (!psc->exception) {
+ /* Note: the typed array can be detached without causing an
+ error */
a_idx = *(uint32_t *)a;
b_idx = *(uint32_t *)b;
argv[0] = psc->getfun(ctx, psc->array_ptr +
@@ -53481,8 +53483,9 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) {
/* make sort stable: compare array offsets */
cmp = (a_idx > b_idx) - (a_idx < b_idx);
}
- if (validate_typed_array(ctx, psc->arr) < 0) {
- psc->exception = 1;
+ if (unlikely(typed_array_is_detached(ctx,
+ JS_VALUE_GET_PTR(psc->arr)))) {
+ psc->exception = 2;
}
done:
JS_FreeValue(ctx, (JSValue)argv[0]);
@@ -53506,11 +53509,11 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val,
tsc.arr = this_val;
tsc.cmp = argv[0];
+ if (!JS_IsUndefined(tsc.cmp) && check_function(ctx, tsc.cmp))
+ return JS_EXCEPTION;
len = js_typed_array_get_length_internal(ctx, this_val);
if (len < 0)
return JS_EXCEPTION;
- if (!JS_IsUndefined(tsc.cmp) && check_function(ctx, tsc.cmp))
- return JS_EXCEPTION;
if (len > 1) {
p = JS_VALUE_GET_OBJ(this_val);
@@ -53576,44 +53579,48 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val,
tsc.elt_size = elt_size;
rqsort(array_idx, len, sizeof(array_idx[0]),
js_TA_cmp_generic, &tsc);
- if (tsc.exception)
- goto fail;
- array_tmp = js_malloc(ctx, len * elt_size);
- if (!array_tmp) {
- fail:
- js_free(ctx, array_idx);
- return JS_EXCEPTION;
- }
- memcpy(array_tmp, array_ptr, len * elt_size);
- switch(elt_size) {
- case 1:
- for(i = 0; i < len; i++) {
- j = array_idx[i];
- ((uint8_t *)array_ptr)[i] = ((uint8_t *)array_tmp)[j];
- }
- break;
- case 2:
- for(i = 0; i < len; i++) {
- j = array_idx[i];
- ((uint16_t *)array_ptr)[i] = ((uint16_t *)array_tmp)[j];
- }
- break;
- case 4:
- for(i = 0; i < len; i++) {
- j = array_idx[i];
- ((uint32_t *)array_ptr)[i] = ((uint32_t *)array_tmp)[j];
+ if (tsc.exception) {
+ if (tsc.exception == 1)
+ goto fail;
+ /* detached typed array during the sort: no error */
+ } else {
+ array_tmp = js_malloc(ctx, len * elt_size);
+ if (!array_tmp) {
+ fail:
+ js_free(ctx, array_idx);
+ return JS_EXCEPTION;
}
- break;
- case 8:
- for(i = 0; i < len; i++) {
- j = array_idx[i];
- ((uint64_t *)array_ptr)[i] = ((uint64_t *)array_tmp)[j];
+ memcpy(array_tmp, array_ptr, len * elt_size);
+ switch(elt_size) {
+ case 1:
+ for(i = 0; i < len; i++) {
+ j = array_idx[i];
+ ((uint8_t *)array_ptr)[i] = ((uint8_t *)array_tmp)[j];
+ }
+ break;
+ case 2:
+ for(i = 0; i < len; i++) {
+ j = array_idx[i];
+ ((uint16_t *)array_ptr)[i] = ((uint16_t *)array_tmp)[j];
+ }
+ break;
+ case 4:
+ for(i = 0; i < len; i++) {
+ j = array_idx[i];
+ ((uint32_t *)array_ptr)[i] = ((uint32_t *)array_tmp)[j];
+ }
+ break;
+ case 8:
+ for(i = 0; i < len; i++) {
+ j = array_idx[i];
+ ((uint64_t *)array_ptr)[i] = ((uint64_t *)array_tmp)[j];
+ }
+ break;
+ default:
+ abort();
}
- break;
- default:
- abort();
+ js_free(ctx, array_tmp);
}
- js_free(ctx, array_tmp);
js_free(ctx, array_idx);
} else {
rqsort(array_ptr, len, elt_size, cmpfun, &tsc);
diff --git a/quickjs/test262_errors.txt b/quickjs/test262_errors.txt
@@ -5,8 +5,6 @@ test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: Test262Er
test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: strict mode: Test262Error: Expected [a, abc] and [a, undefined] to have the same contents. ? quantifier
test262/test/built-ins/RegExp/unicode_full_case_folding.js:20: Test262Error: \u0390 does not match \u1fd3
test262/test/built-ins/RegExp/unicode_full_case_folding.js:20: strict mode: Test262Error: \u0390 does not match \u1fd3
-test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:30: TypeError: ArrayBuffer is detached (Testing with Float64Array.)
-test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:30: strict mode: TypeError: ArrayBuffer is detached (Testing with Float64Array.)
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: Test262Error: Expected a DummyError but got a TypeError