summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2025-04-22 19:07:47 +0200
committerFabrice Bellard <fabrice@bellard.org>2025-04-22 19:07:47 +0200
commit3bffe67e6b0994553fce3f639b42de818f5967d5 (patch)
treeb20578e863c22e1636fa1c652c63bc75e14f58be
parent08a28c0cc3b2af966fd2ae900869c7ffe7b2b9f2 (diff)
downloadquickjs-3bffe67e6b0994553fce3f639b42de818f5967d5.tar.gz
quickjs-3bffe67e6b0994553fce3f639b42de818f5967d5.zip
fixed TypedArray.prototype.slice() when the buffers overlap
-rw-r--r--quickjs.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/quickjs.c b/quickjs.c
index d6d1478..11a6367 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -52747,6 +52747,18 @@ static JSValue js_typed_array_toReversed(JSContext *ctx, JSValueConst this_val,
return ret;
}
+static void slice_memcpy(uint8_t *dst, const uint8_t *src, size_t len)
+{
+ if (dst + len <= src || dst >= src + len) {
+ /* no overlap: can use memcpy */
+ memcpy(dst, src, len);
+ } else {
+ /* otherwise the spec mandates byte copy */
+ while (len-- != 0)
+ *dst++ = *src++;
+ }
+}
+
static JSValue js_typed_array_slice(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
@@ -52789,9 +52801,9 @@ static JSValue js_typed_array_slice(JSContext *ctx, JSValueConst this_val,
if (p1 != NULL && p->class_id == p1->class_id &&
typed_array_get_length(ctx, p1) >= count &&
typed_array_get_length(ctx, p) >= start + count) {
- memcpy(p1->u.array.u.uint8_ptr,
- p->u.array.u.uint8_ptr + (start << shift),
- count << shift);
+ slice_memcpy(p1->u.array.u.uint8_ptr,
+ p->u.array.u.uint8_ptr + (start << shift),
+ count << shift);
} else {
for (n = 0; n < count; n++) {
val = JS_GetPropertyValue(ctx, this_val, JS_NewInt32(ctx, start + n));