diff options
author | 2022-08-29 13:09:46 -0700 | |
---|---|---|
committer | 2022-08-29 13:09:46 -0700 | |
commit | 8651799097e9fd69d36ca61b95d6dc274cab095d (patch) | |
tree | 48d22965f14e3b79b3f1dabe9defffa272291b2e | |
parent | 9d8fb814130a5af6206233eb5c08d974b75148ac (diff) | |
download | bun-8651799097e9fd69d36ca61b95d6dc274cab095d.tar.gz bun-8651799097e9fd69d36ca61b95d6dc274cab095d.tar.zst bun-8651799097e9fd69d36ca61b95d6dc274cab095d.zip |
Fixed JSBuffer write issues (#1175)
-rw-r--r-- | src/bun.js/bindings/JSBuffer.cpp | 27 | ||||
-rw-r--r-- | src/string_immutable.zig | 2 | ||||
-rw-r--r-- | test/bun.js/buffer.test.js | 31 |
3 files changed, 44 insertions, 16 deletions
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index 396e643d5..4b509f257 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -1192,12 +1192,12 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlo if (callFrame->argumentCount() > 1) { if (arg1.value().isAnyInt()) { - int32_t ioffset = arg1.value().toInt32(lexicalGlobalObject); + int32_t ioffset = arg1.value().toUInt32(lexicalGlobalObject); if (ioffset < 0) { throwTypeError(lexicalGlobalObject, scope, "Offset must be a positive integer"_s); return JSC::JSValue::encode(jsUndefined()); } - offset = static_cast<uint32_t>(ioffset); + offset = ioffset; } else if (arg1.value().isString()) { std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg1.value()); if (!encoded) { @@ -1209,24 +1209,21 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlo } } - if (callFrame->argumentCount() > 2) { - length = static_cast<uint32_t>(callFrame->argument(2).toInt32(lexicalGlobalObject)); - } - - length -= std::min(offset, length); - if (UNLIKELY(length < offset)) { RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsNumber(0))); } if (callFrame->argumentCount() > 2) { - std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, callFrame->argument(3)); - if (!encoded) { - throwTypeError(lexicalGlobalObject, scope, "Invalid encoding"_s); - return JSC::JSValue::encode(jsUndefined()); - } + uint32_t arg_len = 0; + arg_len = callFrame->argument(2).toUInt32(lexicalGlobalObject); + length = std::min(arg_len, length-offset); + } - encoding = encoded.value(); + if (callFrame->argumentCount() > 2) { + std::optional<BufferEncodingType> parsedEncoding = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, callFrame->argument(3)); + if (parsedEncoding.has_value()) { + encoding = parsedEncoding.value(); + } } auto view = str->tryGetValue(lexicalGlobalObject); @@ -1653,4 +1650,4 @@ void toBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSUint8Array* uint8 auto* dataView = JSC::JSDataView::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeDataView), uint8Array->possiblySharedBuffer(), uint8Array->byteOffset(), uint8Array->length()); // putDirectWithTransition doesn't work here object->putDirectWithoutTransition(vm, clientData->builtinNames().dataViewPublicName(), dataView, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); -}
\ No newline at end of file +} diff --git a/src/string_immutable.zig b/src/string_immutable.zig index 8503d3418..48d591eff 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -1402,7 +1402,7 @@ pub fn copyLatin1IntoUTF8StopOnNonASCII(buf_: []u8, comptime Type: type, latin1_ } { - const end = latin1.ptr + latin1.len; + const end = latin1.ptr + @minimum(buf.len, latin1.len); assert(@ptrToInt(latin1.ptr + 8) > @ptrToInt(end)); const start_ptr = @ptrToInt(buf.ptr); const start_ptr_latin1 = @ptrToInt(latin1.ptr); diff --git a/test/bun.js/buffer.test.js b/test/bun.js/buffer.test.js index 0b3abd270..3c25450f7 100644 --- a/test/bun.js/buffer.test.js +++ b/test/bun.js/buffer.test.js @@ -387,6 +387,37 @@ it("read", () => { reset(); }); +it("write", () => { + let buf = Buffer.alloc(16); + function reset() { + new Uint8Array(buf.buffer).fill(0); + } + + expect(buf.write("hello", 8, 8)).toBe(5); + reset(); + + expect(buf.write("hello!", 3, 8)).toBe(6); + reset(); + + expect(buf.write("Foo Bar!", 4, 4)).toBe(4); + reset(); + + expect(buf.write("foo", 0, 1)).toBe(1); + reset(); + + expect(buf.write("foo", 0, 2)).toBe(2); + reset(); + + expect(buf.write("foo", 0)).toBe(3); + reset(); + + expect(buf.write("Foo Bar!", 4, 6)).toBe(6); + reset(); + + expect(buf.write("Foo Bar!", 4, 7)).toBe(7); + reset(); +}); + it("includes", () => { const buf = Buffer.from('this is a buffer'); |