diff options
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 9 | ||||
-rw-r--r-- | test/bun.js/text-decoder.test.js | 21 |
2 files changed, 30 insertions, 0 deletions
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 6dcd01bd5..e971a74a9 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -1868,6 +1868,10 @@ JSC__JSValue ZigString__to16BitValue(const ZigString* arg0, JSC__JSGlobalObject* JSC__JSValue ZigString__toExternalU16(const uint16_t* arg0, size_t len, JSC__JSGlobalObject* global) { + if (len == 0) { + return JSC::JSValue::encode(JSC::jsEmptyString(global->vm())); + } + auto ref = String(ExternalStringImpl::create(reinterpret_cast<const UChar*>(arg0), len, reinterpret_cast<void*>(const_cast<uint16_t*>(arg0)), free_global_string)); return JSC::JSValue::encode(JSC::JSValue(JSC::jsString( @@ -1876,7 +1880,12 @@ JSC__JSValue ZigString__toExternalU16(const uint16_t* arg0, size_t len, JSC__JSG // This must be a globally allocated string JSC__JSValue ZigString__toExternalValue(const ZigString* arg0, JSC__JSGlobalObject* arg1) { + ZigString str = *arg0; + if (str.len == 0) { + return JSC::JSValue::encode(JSC::jsEmptyString(arg1->vm())); + } + if (Zig::isTaggedUTF16Ptr(str.ptr)) { auto ref = String(ExternalStringImpl::create(reinterpret_cast<const UChar*>(Zig::untag(str.ptr)), str.len, Zig::untagVoid(str.ptr), free_global_string)); diff --git a/test/bun.js/text-decoder.test.js b/test/bun.js/text-decoder.test.js index c2a00222f..561aec6fc 100644 --- a/test/bun.js/text-decoder.test.js +++ b/test/bun.js/text-decoder.test.js @@ -14,6 +14,27 @@ const getByteLength = (str) => { }; describe("TextDecoder", () => { + it("should not crash on empty text", () => { + const decoder = new TextDecoder(); + gcTrace(true); + const fixtures = [ + new Uint8Array(), + new Uint8Array([]), + new Buffer(0), + new ArrayBuffer(0), + ]; + + for (let input of fixtures) { + expect(decoder.decode(input)).toBe(""); + } + + // DOMJIT test + for (let i = 0; i < 90000; i++) { + decoder.decode(fixtures[0]); + } + + gcTrace(true); + }); it("should decode ascii text", () => { const decoder = new TextDecoder("latin1"); gcTrace(true); |