diff options
author | 2022-11-27 20:21:41 -0800 | |
---|---|---|
committer | 2022-11-27 20:21:41 -0800 | |
commit | ed152596231975d1d09598b8221f49a10c5aa0b6 (patch) | |
tree | 4acb4146bf8428914be3061a6a2efb9c3c2b1fe2 | |
parent | 427203874355abb4e1b1f97852a9fea2d4a5aa14 (diff) | |
download | bun-ed152596231975d1d09598b8221f49a10c5aa0b6.tar.gz bun-ed152596231975d1d09598b8221f49a10c5aa0b6.tar.zst bun-ed152596231975d1d09598b8221f49a10c5aa0b6.zip |
Fix Buffer.toString("latin1") and make Buffer.toString("utf16le") faster
Fixes #455
Fixes #1016
-rw-r--r-- | src/bun.js/bindings/JSBuffer.cpp | 20 | ||||
-rw-r--r-- | test/bun.js/buffer.test.js | 27 |
2 files changed, 44 insertions, 3 deletions
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index 8f9ce2dd2..b3e5f0b4e 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -1141,14 +1141,28 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JS switch (encoding) { case WebCore::BufferEncodingType::latin1: { - ret = JSC::JSValue::encode(JSC::jsString(vm, WTF::StringImpl::create(reinterpret_cast<const UChar*>(castedThis->typedVector() + offset), length))); + LChar* data = nullptr; + auto str = String::createUninitialized(length, data); + memcpy(data, reinterpret_cast<const char*>(castedThis->typedVector() + offset), length); + ret = JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str))); break; } + + case WebCore::BufferEncodingType::ucs2: + case WebCore::BufferEncodingType::utf16le: { + UChar* data = nullptr; + size_t u16length = length > 1 ? length / 2 : 1; + auto str = String::createUninitialized(u16length, data); + // always zero out the last byte of the string incase the buffer is not a multiple of 2 + data[u16length - 1] = 0; + memcpy(data, reinterpret_cast<const char*>(castedThis->typedVector() + offset), length); + ret = JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str))); + break; + } + case WebCore::BufferEncodingType::buffer: case WebCore::BufferEncodingType::utf8: case WebCore::BufferEncodingType::ascii: - case WebCore::BufferEncodingType::ucs2: - case WebCore::BufferEncodingType::utf16le: case WebCore::BufferEncodingType::base64: case WebCore::BufferEncodingType::base64url: case WebCore::BufferEncodingType::hex: { diff --git a/test/bun.js/buffer.test.js b/test/bun.js/buffer.test.js index 14394bd2a..b8771d5b4 100644 --- a/test/bun.js/buffer.test.js +++ b/test/bun.js/buffer.test.js @@ -600,6 +600,33 @@ it("Buffer.from(base64)", () => { ).toBe('console.log("hello world")\n'); }); +it("Buffer.toString regessions", () => { + expect( + Buffer.from([65, 0]) + .toString("utf16le") + .split("") + .map((x) => x.charCodeAt(0)), + ).toEqual([65]); + expect(Buffer.from([65, 0]).toString("base64")).toBe("QQA="); + expect( + Buffer.from('{"alg":"RS256","typ":"JWT"}', "latin1").toString("latin1"), + ).toBe('{"alg":"RS256","typ":"JWT"}'); + expect( + Buffer.from('{"alg":"RS256","typ":"JWT"}', "utf8").toString("utf8"), + ).toBe('{"alg":"RS256","typ":"JWT"}'); +}); + +it("Buffer.toString(utf16le)", () => { + const buf = Buffer.from("hello world", "utf16le"); + expect(buf.toString("utf16le")).toBe("hello world"); + expect(buf.toString("utf16le", 0, 5)).toBe("he"); +}); + +it("Buffer.toString(binary)", () => { + var x = Buffer.from("<?xm", "binary"); + expect(x.toString("binary")).toBe("<?xm"); +}); + it("Buffer.toString(base64)", () => { { const buf = Buffer.from("hello world"); |