quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit 088d5beeacb1a4274e520e285f14737e7a6a634a
parent 98d91318c7ea8ef9b7e7f78749485a50f52a3bfb
Author: Florian Dold <florian@dold.me>
Date:   Mon,  7 Aug 2023 19:20:56 +0200

make TextDecoder work with typed array views

Diffstat:
Mprelude.js | 5+++--
Mtart_module.c | 30++++++++++++++++++++++++++++--
Atest_prelude.js | 23+++++++++++++++++++++++
3 files changed, 54 insertions(+), 4 deletions(-)

diff --git 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 @@ -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 @@ -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"); +}