diff options
author | Florian Dold <florian@dold.me> | 2023-08-07 19:20:56 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2023-08-07 19:20:56 +0200 |
commit | 088d5beeacb1a4274e520e285f14737e7a6a634a (patch) | |
tree | e541edc42d6c5b49834c123ede21bce27dcfae6c | |
parent | 98d91318c7ea8ef9b7e7f78749485a50f52a3bfb (diff) | |
download | quickjs-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.js | 5 | ||||
-rw-r--r-- | tart_module.c | 30 | ||||
-rw-r--r-- | test_prelude.js | 23 |
3 files changed, 54 insertions, 4 deletions
@@ -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"); +} |