aboutsummaryrefslogtreecommitdiff
path: root/src/string_immutable.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/string_immutable.zig')
-rw-r--r--src/string_immutable.zig44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index e85fc4ef8..7bdd7cfe5 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -2550,7 +2550,7 @@ pub fn latin1ToCodepointBytesAssumeNotASCII16(char: u32) u16 {
return latin1_to_utf16_conversion_table[@truncate(u8, char)];
}
-pub fn copyUTF16IntoUTF8(buf: []u8, comptime Type: type, utf16: Type) EncodeIntoResult {
+pub fn copyUTF16IntoUTF8(buf: []u8, comptime Type: type, utf16: Type, comptime allow_partial_write: bool) EncodeIntoResult {
if (comptime Type == []const u16) {
if (bun.FeatureFlags.use_simdutf) {
if (utf16.len == 0)
@@ -2564,14 +2564,14 @@ pub fn copyUTF16IntoUTF8(buf: []u8, comptime Type: type, utf16: Type) EncodeInto
else
buf.len;
- return copyUTF16IntoUTF8WithBuffer(buf, Type, utf16, trimmed, out_len);
+ return copyUTF16IntoUTF8WithBuffer(buf, Type, utf16, trimmed, out_len, allow_partial_write);
}
}
- return copyUTF16IntoUTF8WithBuffer(buf, Type, utf16, utf16, utf16.len);
+ return copyUTF16IntoUTF8WithBuffer(buf, Type, utf16, utf16, utf16.len, allow_partial_write);
}
-pub fn copyUTF16IntoUTF8WithBuffer(buf: []u8, comptime Type: type, utf16: Type, trimmed: Type, out_len: usize) EncodeIntoResult {
+pub fn copyUTF16IntoUTF8WithBuffer(buf: []u8, comptime Type: type, utf16: Type, trimmed: Type, out_len: usize, comptime allow_partial_write: bool) EncodeIntoResult {
var remaining = buf;
var utf16_remaining = utf16;
var ended_on_non_ascii = false;
@@ -2604,7 +2604,7 @@ pub fn copyUTF16IntoUTF8WithBuffer(buf: []u8, comptime Type: type, utf16: Type,
const width: usize = replacement.utf8Width();
if (width > remaining.len) {
ended_on_non_ascii = width > 1;
- switch (width) {
+ if (comptime allow_partial_write) switch (width) {
2 => {
if (remaining.len > 0) {
//only first will be written
@@ -2650,7 +2650,7 @@ pub fn copyUTF16IntoUTF8WithBuffer(buf: []u8, comptime Type: type, utf16: Type,
},
else => {},
- }
+ };
break;
}
@@ -3257,8 +3257,9 @@ pub fn indexOfNotChar(slice: []const u8, char: u8) ?u32 {
return null;
}
+const invalid_char: u8 = 0xff;
const hex_table: [255]u8 = brk: {
- var values: [255]u8 = [_]u8{0} ** 255;
+ var values: [255]u8 = [_]u8{invalid_char} ** 255;
values['0'] = 0;
values['1'] = 1;
values['2'] = 2;
@@ -3285,22 +3286,41 @@ const hex_table: [255]u8 = brk: {
break :brk values;
};
-pub fn decodeHexToBytes(destination: []u8, comptime Char: type, source: []const Char) usize {
+pub fn decodeHexToBytes(destination: []u8, comptime Char: type, source: []const Char) !usize {
+ return _decodeHexToBytes(destination, Char, source, false);
+}
+
+pub fn decodeHexToBytesTruncate(destination: []u8, comptime Char: type, source: []const Char) usize {
+ return _decodeHexToBytes(destination, Char, source, true) catch 0;
+}
+
+inline fn _decodeHexToBytes(destination: []u8, comptime Char: type, source: []const Char, comptime truncate: bool) !usize {
var remain = destination;
var input = source;
- while (input.len > 1 and remain.len > 0) {
+ while (remain.len > 0 and input.len > 1) {
const int = input[0..2].*;
+ if (comptime @sizeOf(Char) > 1) {
+ if (int[0] > std.math.maxInt(u8) or int[1] > std.math.maxInt(u8)) {
+ if (comptime truncate) break;
+ return error.InvalidByteSequence;
+ }
+ }
const a = hex_table[@truncate(u8, int[0])];
const b = hex_table[@truncate(u8, int[1])];
- if (a == 255 or b == 255) {
- break;
+ if (a == invalid_char or b == invalid_char) {
+ if (comptime truncate) break;
+ return error.InvalidByteSequence;
}
remain[0] = a << 4 | b;
remain = remain[1..];
input = input[2..];
}
+ if (comptime !truncate) {
+ if (remain.len > 0 and input.len > 0) return error.InvalidByteSequence;
+ }
+
return destination.len - remain.len;
}
@@ -3615,7 +3635,7 @@ pub fn formatUTF16Type(comptime Slice: type, slice_: Slice, writer: anytype) !vo
var slice = slice_;
while (slice.len > 0) {
- const result = strings.copyUTF16IntoUTF8(chunk, Slice, slice);
+ const result = strings.copyUTF16IntoUTF8(chunk, Slice, slice, true);
if (result.read == 0 or result.written == 0)
break;
try writer.writeAll(chunk[0..result.written]);