aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base64/base64.zig24
-rw-r--r--src/bun.js/bindings/JSBuffer.cpp102
-rw-r--r--src/bun.js/webcore/encoding.zig35
m---------src/deps/uws0
4 files changed, 125 insertions, 36 deletions
diff --git a/src/base64/base64.zig b/src/base64/base64.zig
index be0086c46..a5a94200f 100644
--- a/src/base64/base64.zig
+++ b/src/base64/base64.zig
@@ -37,24 +37,28 @@ pub fn decodeURLSafe(destination: []u8, source: []const u8) DecodeResult {
pub fn encode(destination: []u8, source: []const u8) usize {
return zig_base64.standard.Encoder.encode(destination, source).len;
+
+}
+
+pub fn decodeLenUpperBound(len: usize) usize {
+ return zig_base64.standard.Decoder.calcSizeUpperBound(len) catch {
+ //fallback
+ return len / 4 * 3;
+ };
}
-/// Given a source string of length len, this returns the amount of
-/// memory the destination string should have.
-///
-/// remember, this is integer math
-/// 3 bytes turn into 4 chars
-/// ceiling[len / 3] * 4
-///
-///
pub fn decodeLen(source: anytype) usize {
- return (source.len / 4 * 3 + 2);
+ return zig_base64.standard.Decoder.calcSizeForSlice(source) catch {
+ //fallback
+ return source.len / 4 * 3;
+ };
}
pub fn encodeLen(source: anytype) usize {
- return (source.len + 2) / 3 * 4;
+ return zig_base64.standard.Encoder.calcSize(source.len);
}
+
pub const urlsafe = zig_base64.Base64DecoderWithIgnore.init(
zig_base64.url_safe_alphabet_chars,
null,
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp
index 5b038f3ae..0c393ce05 100644
--- a/src/bun.js/bindings/JSBuffer.cpp
+++ b/src/bun.js/bindings/JSBuffer.cpp
@@ -374,18 +374,65 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_allocBody(JSC::JSG
return JSValue::encode(jsUndefined());
}
- auto arrayBuffer = JSC::ArrayBuffer::tryCreate(length, 1);
- if (!arrayBuffer) {
- throwOutOfMemoryError(lexicalGlobalObject, throwScope);
- return JSValue::encode(jsUndefined());
- }
-
auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
auto* subclassStructure = globalObject->JSBufferSubclassStructure();
- auto uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, length);
- RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
+ // fill argument
+ if(callFrame->argumentCount() > 1){
+ auto uint8Array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, subclassStructure, length);
+
+ auto value = callFrame->argument(1);
+
+ if (!value.isString()) {
+ auto value_ = value.toInt32(lexicalGlobalObject) & 0xFF;
+
+ auto value_uint8 = static_cast<uint8_t>(value_);
+ RETURN_IF_EXCEPTION(throwScope, JSC::JSValue::encode(jsUndefined()));
+
+ auto length = uint8Array->byteLength();
+ auto start = 0;
+ auto end = length;
+
+ auto startPtr = uint8Array->typedVector() + start;
+ auto endPtr = uint8Array->typedVector() + end;
+ memset(startPtr, value_uint8, endPtr - startPtr);
+ RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
+ }
+
+ {
+ size_t length = uint8Array->byteLength();
+ size_t start = 0;
+ size_t end = length;
+ WebCore::BufferEncodingType encoding = WebCore::BufferEncodingType::utf8;
+ if (callFrame->argumentCount() > 2) {
+ auto encoding_ = callFrame->uncheckedArgument(2).toString(lexicalGlobalObject);
+
+ std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, encoding_);
+ if (!encoded) {
+ throwTypeError(lexicalGlobalObject, throwScope, "Invalid encoding"_s);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+ encoding = encoded.value();
+
+ }
+ auto startPtr = uint8Array->typedVector() + start;
+ auto str_ = value.toWTFString(lexicalGlobalObject);
+ ZigString str = Zig::toZigString(str_);
+
+ Bun__Buffer_fill(&str, startPtr, end - start, encoding);
+ RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
+ }
+ } else {
+ auto arrayBuffer = JSC::ArrayBuffer::tryCreate(length, 1);
+ if (!arrayBuffer) {
+ throwOutOfMemoryError(lexicalGlobalObject, throwScope);
+ return JSValue::encode(jsUndefined());
+ }
+ auto uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, length);
+ RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
+
+ }
}
static inline JSC::EncodedJSValue jsBufferConstructorFunction_allocUnsafeSlowBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
@@ -891,6 +938,8 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_fillBody(JSC::JSGlob
auto value_ = value.toInt32(lexicalGlobalObject) & 0xFF;
auto value_uint8 = static_cast<uint8_t>(value_);
+ RETURN_IF_EXCEPTION(throwScope, JSC::JSValue::encode(jsUndefined()));
+
auto length = castedThis->byteLength();
auto start = 0;
auto end = length;
@@ -1363,7 +1412,6 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlo
throwTypeError(lexicalGlobalObject, scope, "Invalid encoding"_s);
return JSC::JSValue::encode(jsUndefined());
}
-
encoding = encoded.value();
}
}
@@ -1371,20 +1419,38 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlo
if (UNLIKELY(length < offset)) {
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsNumber(0)));
}
-
+
if (callFrame->argumentCount() > 2) {
uint32_t arg_len = 0;
- arg_len = callFrame->argument(2).toUInt32(lexicalGlobalObject);
- length = std::min(arg_len, length - offset);
- }
+ EnsureStillAliveScope arg2 = callFrame->argument(2);
+ if (arg2.value().isAnyInt()) {
+ arg_len = arg2.value().toUInt32(lexicalGlobalObject);
+ length = std::min(arg_len, length);
- if (callFrame->argumentCount() > 2) {
- std::optional<BufferEncodingType> parsedEncoding = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, callFrame->argument(3));
- if (parsedEncoding.has_value()) {
- encoding = parsedEncoding.value();
+ if (callFrame->argumentCount() > 3) {
+ EnsureStillAliveScope arg3 = callFrame->argument(3);
+ if (arg3.value().isString()) {
+ std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg3.value());
+ if (!encoded) {
+ throwTypeError(lexicalGlobalObject, scope, "Invalid encoding"_s);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+ encoding = encoded.value();
+ }
+ }
+ } else if (arg2.value().isString()) {
+ std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg2.value());
+ if (!encoded) {
+ throwTypeError(lexicalGlobalObject, scope, "Invalid encoding"_s);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+
+ encoding = encoded.value();
}
}
+ length = length - offset;
+
auto view = str->tryGetValue(lexicalGlobalObject);
int64_t written = 0;
@@ -1397,6 +1463,8 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlo
case WebCore::BufferEncodingType::base64:
case WebCore::BufferEncodingType::base64url:
case WebCore::BufferEncodingType::hex: {
+
+
if (view.is8Bit()) {
written = Bun__encoding__writeLatin1(view.characters8(), view.length(), castedThis->typedVector() + offset, length, static_cast<uint8_t>(encoding));
} else {
diff --git a/src/bun.js/webcore/encoding.zig b/src/bun.js/webcore/encoding.zig
index 76541e111..4f30aadae 100644
--- a/src/bun.js/webcore/encoding.zig
+++ b/src/bun.js/webcore/encoding.zig
@@ -860,12 +860,14 @@ pub const Encoder = struct {
switch (comptime encoding) {
JSC.Node.Encoding.buffer => {
+
const written = @min(len, to_len);
@memcpy(to, input, written);
return @intCast(i64, written);
},
.latin1, .ascii => {
+
const written = @min(len, to_len);
@memcpy(to, input, written);
@@ -887,12 +889,17 @@ pub const Encoder = struct {
if (std.mem.isAligned(@ptrToInt(to), @alignOf([*]u16))) {
var buf = input[0..len];
+
var output = @ptrCast([*]u16, @alignCast(@alignOf(u16), to))[0 .. to_len / 2];
- return strings.copyLatin1IntoUTF16([]u16, output, []const u8, buf).written;
+ var written = strings.copyLatin1IntoUTF16([]u16, output, []const u8, buf).written;
+ return written * 2;
} else {
var buf = input[0..len];
var output = @ptrCast([*]align(1) u16, to)[0 .. to_len / 2];
- return strings.copyLatin1IntoUTF16([]align(1) u16, output, []const u8, buf).written;
+
+ var written = strings.copyLatin1IntoUTF16([]align(1) u16, output, []const u8, buf).written;
+ return written * 2;
+
}
},
@@ -901,6 +908,7 @@ pub const Encoder = struct {
},
JSC.Node.Encoding.base64url => {
+
var slice = strings.trim(input[0..len], "\r\n\t " ++ [_]u8{std.ascii.control_code.vt});
if (slice.len == 0)
return 0;
@@ -940,11 +948,11 @@ pub const Encoder = struct {
},
JSC.Node.Encoding.hex => {
- return len * 2;
+ return len / 2;
},
JSC.Node.Encoding.base64, JSC.Node.Encoding.base64url => {
- return bun.base64.encodeLen(input[0..len]);
+ return bun.base64.decodeLen(input[0..len]);
},
// else => return &[_]u8{};
}
@@ -958,12 +966,21 @@ pub const Encoder = struct {
.utf8 => {
return @intCast(i32, strings.copyUTF16IntoUTF8(to[0..to_len], []const u16, input[0..len]).written);
},
- // string is already encoded, just need to copy the data
- .latin1, JSC.Node.Encoding.ascii, JSC.Node.Encoding.ucs2, JSC.Node.Encoding.buffer, JSC.Node.Encoding.utf16le => {
+ .latin1, JSC.Node.Encoding.ascii, JSC.Node.Encoding.buffer => {
strings.copyU16IntoU8(to[0..to_len], []const u16, input[0..len]);
-
return @intCast(i64, @min(len, to_len));
},
+ // string is already encoded, just need to copy the data
+ JSC.Node.Encoding.ucs2, JSC.Node.Encoding.utf16le => {
+ var bytes_input_len = len * 2;
+ var written = @min(bytes_input_len, to_len);
+ if (written < 2) return 0;
+
+ var fixed_len = (written/2) * 2;
+ var input_u8 = @ptrCast([*] const u8, input);
+ strings.copyU16IntoU8(to[0..written], []const u8, input_u8[0..fixed_len]);
+ return @intCast(i64, written);
+ },
JSC.Node.Encoding.hex => {
return @intCast(i64, strings.decodeHexToBytes(to[0..to_len], u16, input[0..len]));
@@ -999,11 +1016,11 @@ pub const Encoder = struct {
},
JSC.Node.Encoding.hex => {
- return len;
+ return len / 2;
},
JSC.Node.Encoding.base64, JSC.Node.Encoding.base64url => {
- return bun.base64.encodeLen(input[0..len]);
+ return bun.base64.decodeLenUpperBound(len);
},
// else => return &[_]u8{};
}
diff --git a/src/deps/uws b/src/deps/uws
-Subproject a076c28a37ae2ffbcb4e2cec023056b13ba0518
+Subproject 665680ca11e09649b96e665a5eb97edc65cbb65