aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Taher <8665427+nullhook@users.noreply.github.com> 2022-08-29 13:09:46 -0700
committerGravatar GitHub <noreply@github.com> 2022-08-29 13:09:46 -0700
commit8651799097e9fd69d36ca61b95d6dc274cab095d (patch)
tree48d22965f14e3b79b3f1dabe9defffa272291b2e
parent9d8fb814130a5af6206233eb5c08d974b75148ac (diff)
downloadbun-8651799097e9fd69d36ca61b95d6dc274cab095d.tar.gz
bun-8651799097e9fd69d36ca61b95d6dc274cab095d.tar.zst
bun-8651799097e9fd69d36ca61b95d6dc274cab095d.zip
Fixed JSBuffer write issues (#1175)
-rw-r--r--src/bun.js/bindings/JSBuffer.cpp27
-rw-r--r--src/string_immutable.zig2
-rw-r--r--test/bun.js/buffer.test.js31
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');