fix off-by-one error in std.unicode.utf8ToUtf16LeWithNull
and fix larger-than-one-byte sentinels when being freed Thank you to João Pedro for identifying both problems and providing example code to solve them. closes #4413master
parent
c4d0f97b4c
commit
3b622f4494
|
@ -233,7 +233,7 @@ pub const Allocator = struct {
|
||||||
pub fn free(self: *Allocator, memory: var) void {
|
pub fn free(self: *Allocator, memory: var) void {
|
||||||
const Slice = @typeInfo(@TypeOf(memory)).Pointer;
|
const Slice = @typeInfo(@TypeOf(memory)).Pointer;
|
||||||
const bytes = @sliceToBytes(memory);
|
const bytes = @sliceToBytes(memory);
|
||||||
const bytes_len = bytes.len + @boolToInt(Slice.sentinel != null);
|
const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;
|
||||||
if (bytes_len == 0) return;
|
if (bytes_len == 0) return;
|
||||||
const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
|
const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
|
||||||
@memset(non_const_ptr, undefined, bytes_len);
|
@memset(non_const_ptr, undefined, bytes_len);
|
||||||
|
|
|
@ -571,8 +571,9 @@ pub fn utf8ToUtf16LeWithNull(allocator: *mem.Allocator, utf8: []const u8) ![:0]u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const len = result.len;
|
||||||
try result.append(0);
|
try result.append(0);
|
||||||
return result.toOwnedSlice()[0..:0];
|
return result.toOwnedSlice()[0..len :0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns index of next character. If exact fit, returned index equals output slice length.
|
/// Returns index of next character. If exact fit, returned index equals output slice length.
|
||||||
|
@ -619,12 +620,14 @@ test "utf8ToUtf16LeWithNull" {
|
||||||
var bytes: [128]u8 = undefined;
|
var bytes: [128]u8 = undefined;
|
||||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||||
const utf16 = try utf8ToUtf16LeWithNull(allocator, "𐐷");
|
const utf16 = try utf8ToUtf16LeWithNull(allocator, "𐐷");
|
||||||
testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc\x00\x00", @sliceToBytes(utf16[0..]));
|
testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16[0..]));
|
||||||
|
testing.expect(utf16[2] == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var bytes: [128]u8 = undefined;
|
var bytes: [128]u8 = undefined;
|
||||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||||
const utf16 = try utf8ToUtf16LeWithNull(allocator, "\u{10FFFF}");
|
const utf16 = try utf8ToUtf16LeWithNull(allocator, "\u{10FFFF}");
|
||||||
testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf\x00\x00", @sliceToBytes(utf16[0..]));
|
testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16[0..]));
|
||||||
|
testing.expect(utf16[2] == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue