aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp41
-rw-r--r--src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h9
-rw-r--r--src/bun.js/builtins/js/JSBufferPrototype.js32
-rw-r--r--test/bun.js/buffer.test.js78
4 files changed, 111 insertions, 49 deletions
diff --git a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp
index d1d9231e7..367041f65 100644
--- a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp
+++ b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp
@@ -717,40 +717,33 @@ const char* const s_jsBufferPrototypeToJSONCode =
"})\n" \
;
-const JSC::ConstructAbility s_jsBufferPrototypeSubarrayCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
-const JSC::ConstructorKind s_jsBufferPrototypeSubarrayCodeConstructorKind = JSC::ConstructorKind::None;
-const JSC::ImplementationVisibility s_jsBufferPrototypeSubarrayCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_jsBufferPrototypeSubarrayCodeLength = 196;
-static const JSC::Intrinsic s_jsBufferPrototypeSubarrayCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_jsBufferPrototypeSubarrayCode =
- "(function (start, end) {\n" \
- " \"use strict\";\n" \
- "\n" \
- " Buffer[Symbol.species] ??= Buffer;\n" \
- " return new Buffer(this.buffer, this.byteOffset + (start || 0), (end || this.byteLength) - (start || 0));\n" \
- "})\n" \
-;
-
const JSC::ConstructAbility s_jsBufferPrototypeSliceCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_jsBufferPrototypeSliceCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_jsBufferPrototypeSliceCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_jsBufferPrototypeSliceCodeLength = 308;
+const int s_jsBufferPrototypeSliceCodeLength = 612;
static const JSC::Intrinsic s_jsBufferPrototypeSliceCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_jsBufferPrototypeSliceCode =
"(function (start, end) {\n" \
" \"use strict\";\n" \
- " if (start === undefined && end === undefined) {\n" \
- " return this;\n" \
- " }\n" \
- "\n" \
- " Buffer[Symbol.species] ||= Buffer;\n" \
+ " var { buffer, byteOffset, byteLength } = this;\n" \
"\n" \
- " start = start || 0;\n" \
- " if (end !== 0) {\n" \
- " end = end || this.byteLength;\n" \
+ " function adjustOffset(offset, length) {\n" \
+ " //\n" \
+ " //\n" \
+ " offset = @trunc(offset);\n" \
+ " if (offset === 0 || @isNaN(offset)) {\n" \
+ " return 0;\n" \
+ " } else if (offset < 0) {\n" \
+ " offset += length;\n" \
+ " return offset > 0 ? offset : 0;\n" \
+ " } else {\n" \
+ " return offset < length ? offset : length;\n" \
+ " }\n" \
" }\n" \
"\n" \
- " return new Buffer(this.buffer, this.byteOffset + start, end - start);\n" \
+ " var start_ = adjustOffset(start, byteLength);\n" \
+ " var end_ = end !== undefined ? adjustOffset(end, byteLength) : byteLength;\n" \
+ " return new Buffer(buffer, byteOffset + start_, end_ > start_ ? (end_ - start_) : 0);\n" \
"})\n" \
;
diff --git a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h
index f17f22dbb..04fa9df0b 100644
--- a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h
+++ b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h
@@ -318,11 +318,6 @@ extern const int s_jsBufferPrototypeToJSONCodeLength;
extern const JSC::ConstructAbility s_jsBufferPrototypeToJSONCodeConstructAbility;
extern const JSC::ConstructorKind s_jsBufferPrototypeToJSONCodeConstructorKind;
extern const JSC::ImplementationVisibility s_jsBufferPrototypeToJSONCodeImplementationVisibility;
-extern const char* const s_jsBufferPrototypeSubarrayCode;
-extern const int s_jsBufferPrototypeSubarrayCodeLength;
-extern const JSC::ConstructAbility s_jsBufferPrototypeSubarrayCodeConstructAbility;
-extern const JSC::ConstructorKind s_jsBufferPrototypeSubarrayCodeConstructorKind;
-extern const JSC::ImplementationVisibility s_jsBufferPrototypeSubarrayCodeImplementationVisibility;
extern const char* const s_jsBufferPrototypeSliceCode;
extern const int s_jsBufferPrototypeSliceCodeLength;
extern const JSC::ConstructAbility s_jsBufferPrototypeSliceCodeConstructAbility;
@@ -389,7 +384,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe
macro(base64urlSlice, jsBufferPrototypeBase64urlSlice, 2) \
macro(hexSlice, jsBufferPrototypeHexSlice, 2) \
macro(toJSON, jsBufferPrototypeToJSON, 0) \
- macro(subarray, jsBufferPrototypeSubarray, 2) \
macro(slice, jsBufferPrototypeSlice, 2) \
macro(initializeBunBuffer, jsBufferPrototypeInitializeBunBuffer, 1) \
@@ -447,7 +441,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe
#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_BASE64URLSLICE 1
#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_HEXSLICE 1
#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_TOJSON 1
-#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_SUBARRAY 1
#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_SLICE 1
#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_INITIALIZEBUNBUFFER 1
@@ -506,7 +499,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe
macro(jsBufferPrototypeBase64urlSliceCode, base64urlSlice, ASCIILiteral(), s_jsBufferPrototypeBase64urlSliceCodeLength) \
macro(jsBufferPrototypeHexSliceCode, hexSlice, ASCIILiteral(), s_jsBufferPrototypeHexSliceCodeLength) \
macro(jsBufferPrototypeToJSONCode, toJSON, ASCIILiteral(), s_jsBufferPrototypeToJSONCodeLength) \
- macro(jsBufferPrototypeSubarrayCode, subarray, ASCIILiteral(), s_jsBufferPrototypeSubarrayCodeLength) \
macro(jsBufferPrototypeSliceCode, slice, ASCIILiteral(), s_jsBufferPrototypeSliceCodeLength) \
macro(jsBufferPrototypeInitializeBunBufferCode, initializeBunBuffer, ASCIILiteral(), s_jsBufferPrototypeInitializeBunBufferCodeLength) \
@@ -542,7 +534,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe
macro(readUInt8) \
macro(setBigUint64) \
macro(slice) \
- macro(subarray) \
macro(toJSON) \
macro(ucs2Slice) \
macro(ucs2Write) \
diff --git a/src/bun.js/builtins/js/JSBufferPrototype.js b/src/bun.js/builtins/js/JSBufferPrototype.js
index a81634f69..689dc2dde 100644
--- a/src/bun.js/builtins/js/JSBufferPrototype.js
+++ b/src/bun.js/builtins/js/JSBufferPrototype.js
@@ -277,27 +277,27 @@ function toJSON() {
return { type, data };
}
-function subarray(start, end) {
- "use strict";
-
- Buffer[Symbol.species] ??= Buffer;
- return new Buffer(this.buffer, this.byteOffset + (start || 0), (end || this.byteLength) - (start || 0));
-}
-
function slice(start, end) {
"use strict";
- if (start === undefined && end === undefined) {
- return this;
- }
-
- Buffer[Symbol.species] ||= Buffer;
+ var { buffer, byteOffset, byteLength } = this;
- start = start || 0;
- if (end !== 0) {
- end = end || this.byteLength;
+ function adjustOffset(offset, length) {
+ // Use Math.trunc() to convert offset to an integer value that can be larger
+ // than an Int32. Hence, don't use offset | 0 or similar techniques.
+ offset = @trunc(offset);
+ if (offset === 0 || @isNaN(offset)) {
+ return 0;
+ } else if (offset < 0) {
+ offset += length;
+ return offset > 0 ? offset : 0;
+ } else {
+ return offset < length ? offset : length;
+ }
}
- return new Buffer(this.buffer, this.byteOffset + start, end - start);
+ var start_ = adjustOffset(start, byteLength);
+ var end_ = end !== undefined ? adjustOffset(end, byteLength) : byteLength;
+ return new Buffer(buffer, byteOffset + start_, end_ > start_ ? (end_ - start_) : 0);
}
diff --git a/test/bun.js/buffer.test.js b/test/bun.js/buffer.test.js
index 02ee1e75e..23d94abd5 100644
--- a/test/bun.js/buffer.test.js
+++ b/test/bun.js/buffer.test.js
@@ -213,6 +213,71 @@ it("Buffer.compare", () => {
b[2] = 0;
expect(a.compare(b)).toBe(1);
expect(b.compare(a)).toBe(-1);
+
+ const buf = Buffer.from("0123456789", "utf8");
+ const expectedSameBufs = [
+ [buf.slice(-10, 10), Buffer.from("0123456789", "utf8")],
+ [buf.slice(-20, 10), Buffer.from("0123456789", "utf8")],
+ [buf.slice(-20, -10), Buffer.from("", "utf8")],
+ [buf.slice(), Buffer.from("0123456789", "utf8")],
+ [buf.slice(0), Buffer.from("0123456789", "utf8")],
+ [buf.slice(0, 0), Buffer.from("", "utf8")],
+ [buf.slice(undefined), Buffer.from("0123456789", "utf8")],
+ [buf.slice("foobar"), Buffer.from("0123456789", "utf8")],
+ [buf.slice(undefined, undefined), Buffer.from("0123456789", "utf8")],
+ [buf.slice(2), Buffer.from("23456789", "utf8")],
+ [buf.slice(5), Buffer.from("56789", "utf8")],
+ [buf.slice(10), Buffer.from("", "utf8")],
+ [buf.slice(5, 8), Buffer.from("567", "utf8")],
+ [buf.slice(8, -1), Buffer.from("8", "utf8")],
+ [buf.slice(-10), Buffer.from("0123456789", "utf8")],
+ [buf.slice(0, -9), Buffer.from("0", "utf8")],
+ [buf.slice(0, -10), Buffer.from("", "utf8")],
+ [buf.slice(0, -1), Buffer.from("012345678", "utf8")],
+ [buf.slice(2, -2), Buffer.from("234567", "utf8")],
+ [buf.slice(0, 65536), Buffer.from("0123456789", "utf8")],
+ [buf.slice(65536, 0), Buffer.from("", "utf8")],
+ [buf.slice(-5, -8), Buffer.from("", "utf8")],
+ [buf.slice(-5, -3), Buffer.from("56", "utf8")],
+ [buf.slice(-10, 10), Buffer.from("0123456789", "utf8")],
+ [buf.slice("0", "1"), Buffer.from("0", "utf8")],
+ [buf.slice("-5", "10"), Buffer.from("56789", "utf8")],
+ [buf.slice("-10", "10"), Buffer.from("0123456789", "utf8")],
+ [buf.slice("-10", "-5"), Buffer.from("01234", "utf8")],
+ [buf.slice("-10", "-0"), Buffer.from("", "utf8")],
+ [buf.slice("111"), Buffer.from("", "utf8")],
+ [buf.slice("0", "-111"), Buffer.from("", "utf8")],
+ ];
+
+ for (let i = 0, s = buf.toString(); i < buf.length; ++i) {
+ expectedSameBufs.push(
+ [buf.slice(i), Buffer.from(s.slice(i))],
+ [buf.slice(0, i), Buffer.from(s.slice(0, i))],
+ [buf.slice(-i), Buffer.from(s.slice(-i))],
+ [buf.slice(0, -i), Buffer.from(s.slice(0, -i))]
+ );
+ }
+
+ expectedSameBufs.forEach(([buf1, buf2]) => {
+ expect(Buffer.compare(buf1, buf2)).toBe(0);
+ });
+
+ {
+ const buf = Buffer.from([
+ 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0, 0, 0, 18, 184, 6, 0,
+ 175, 29, 0, 8, 11, 1, 0, 0,
+ ]);
+ const chunk1 = Buffer.from([
+ 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0,
+ ]);
+ const chunk2 = Buffer.from([
+ 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0,
+ ]);
+ const middle = buf.length / 2;
+
+ expect(JSON.stringify(buf.slice(0, middle))).toBe(JSON.stringify(chunk1));
+ expect(JSON.stringify(buf.slice(middle))).toBe(JSON.stringify(chunk2));
+ }
});
it("Buffer.copy", () => {
@@ -512,3 +577,16 @@ it("lastIndexOf", () => {
expect(b.lastIndexOf("b", null)).toBe(-1);
expect(b.lastIndexOf("b", [])).toBe(-1);
});
+
+for (let fn of [Buffer.prototype.slice, Buffer.prototype.subarray]) {
+ it(`Buffer.${fn.name}`, () => {
+ const buf = new Buffer("buffer");
+ const slice = fn.call(buf, 1, 3);
+ expect(slice.toString()).toBe("uf");
+ const slice2 = fn.call(slice, 100);
+ expect(slice2.toString()).toBe("");
+
+ const slice3 = fn.call(slice, -1);
+ expect(slice3.toString()).toBe("f");
+ });
+}