summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-08-07 19:20:56 +0200
committerFlorian Dold <florian@dold.me>2023-08-07 19:20:56 +0200
commit088d5beeacb1a4274e520e285f14737e7a6a634a (patch)
treee541edc42d6c5b49834c123ede21bce27dcfae6c
parent98d91318c7ea8ef9b7e7f78749485a50f52a3bfb (diff)
downloadquickjs-tart-dev/ivan-avalos/anastasis-qtart.tar.gz
quickjs-tart-dev/ivan-avalos/anastasis-qtart.tar.bz2
quickjs-tart-dev/ivan-avalos/anastasis-qtart.zip
make TextDecoder work with typed array viewsdev/ivan-avalos/anastasis-qtart
-rw-r--r--prelude.js5
-rw-r--r--tart_module.c30
-rw-r--r--test_prelude.js23
3 files changed, 54 insertions, 4 deletions
diff --git a/prelude.js b/prelude.js
index 87c5b70..11ad084 100644
--- a/prelude.js
+++ b/prelude.js
@@ -14,9 +14,10 @@ class TextEncoder {
class TextDecoder {
decode(bytes) {
if (ArrayBuffer.isView(bytes)) {
- return tart.decodeUtf8(bytes.buffer);
+ return tart.decodeUtf8(bytes.buffer, bytes.byteOffset, bytes.byteLength);
}
- return tart.decodeUtf8(bytes);
+ // Assume it is an ArrayBuffer
+ return tart.decodeUtf8(bytes, 0, bytes.byteLength);
}
}
diff --git a/tart_module.c b/tart_module.c
index 01cd990..87228d0 100644
--- a/tart_module.c
+++ b/tart_module.c
@@ -1250,16 +1250,42 @@ cleanup:
}
+// (ArrayBuffer, offset, len) => string
+// FIXME: Eventually, this should handle typed arrays properly as input as well.
static JSValue js_decode_utf8(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
size_t psize;
uint8_t *utf8_buf;
+ uint32_t offset;
+ uint32_t len;
+ JSValue ret_val;
+
utf8_buf = JS_GetArrayBuffer(ctx, &psize, argv[0]);
if (NULL == utf8_buf) {
- return JS_EXCEPTION;
+ goto exception;
+ }
+
+ if (0 != JS_ToUint32(ctx, &offset, argv[1])) {
+ goto exception;
+ }
+
+ if (0 != JS_ToUint32(ctx, &len, argv[2])) {
+ goto exception;
}
+
+ if (offset + len > psize) {
+ JS_ThrowRangeError(ctx, "offset %llu len %llu out of range (%llu)",
+ offset, len, psize);
+ goto exception;
+ }
+
return JS_NewStringLen(ctx, (char *) utf8_buf, psize);
+done:
+ return ret_val;
+exception:
+ ret_val = JS_EXCEPTION;
+ goto done;
}
static JSValue js_structured_clone(JSContext *ctx, JSValueConst this_val,
@@ -1383,7 +1409,7 @@ static JSValue js_talercrypto_hash_state_finish(JSContext *ctx, JSValue this_val
static const JSCFunctionListEntry tart_talercrypto_funcs[] = {
JS_CFUNC_DEF("structuredClone", 1, js_structured_clone),
JS_CFUNC_DEF("encodeUtf8", 1, js_encode_utf8),
- JS_CFUNC_DEF("decodeUtf8", 1, js_decode_utf8),
+ JS_CFUNC_DEF("decodeUtf8", 3, js_decode_utf8),
JS_CFUNC_DEF("randomBytes", 1, js_random_bytes),
JS_CFUNC_DEF("encodeCrock", 1, js_talercrypto_encode_crock),
JS_CFUNC_DEF("decodeCrock", 1, js_talercrypto_decode_crock),
diff --git a/test_prelude.js b/test_prelude.js
new file mode 100644
index 0000000..29c4af0
--- /dev/null
+++ b/test_prelude.js
@@ -0,0 +1,23 @@
+const enc = new TextEncoder();
+const dec = new TextDecoder();
+
+const buf = enc.encode("Hello, World");
+
+console.log("byteOffset", buf.byteOffset);
+console.log("byteLength", buf.byteLength);
+
+const str = dec.decode(buf);
+
+if (str != "Hello, World") {
+ throw Error("test 1 failed");
+}
+
+// Put 4 bytes before and after!
+const buf2 = new Uint8Array(buf.byteLength + 8);
+
+buf2.set(buf, 4);
+
+const str2 = dec.decode(buf2.slice(4, buf2.byteLength - 4))
+if (str2 != "Hello, World") {
+ throw Error("test 2 failed");
+}