authorgravatar for michael.larouche@gmail.comMichaël Larouche <michael.larouche@gmail.com> 2020-02-25 15:07:35-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-05 17:08:12-05:00
logf5954dad8356c05c294630f19609c343d65ea544
tree068322245e42dbad86815b4776f3ab6e78656102
parent1091fee2425f9142c726233f89e0f8d49165d829

Fix crash when freeing empty string as null-terminated sentinel


1 files changed, 13 insertions(+), 1 deletions(-)

lib/std/mem.zig+13-1
......@@ -1780,10 +1780,11 @@ fn SliceAsBytesReturnType(comptime sliceType: type) type {
17801780
17811781pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
17821782 const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice;
1783 const actualSliceTypeInfo = @typeInfo(@TypeOf(actualSlice)).Pointer;
17831784
17841785 // let's not give an undefined pointer to @ptrCast
17851786 // it may be equal to zero and fail a null check
1786 if (actualSlice.len == 0) {
1787 if (actualSlice.len == 0 and actualSliceTypeInfo.sentinel == null) {
17871788 return &[0]u8{};
17881789 }
17891790
......@@ -1805,6 +1806,12 @@ test "sliceAsBytes" {
18051806 }));
18061807}
18071808
1809test "sliceAsBytes with sentinel slice" {
1810 const empty_string:[:0]const u8 = "";
1811 const bytes = sliceAsBytes(empty_string);
1812 testing.expect(bytes.len == 0);
1813}
1814
18081815test "sliceAsBytes packed struct at runtime and comptime" {
18091816 const Foo = packed struct {
18101817 a: u4,
......@@ -1941,3 +1948,8 @@ test "isAligned" {
19411948 testing.expect(!isAligned(4, 8));
19421949 testing.expect(!isAligned(4, 16));
19431950}
1951
1952test "freeing empty string with null-terminated sentinel" {
1953 const empty_string = try dupeZ(testing.allocator, u8, "");
1954 testing.allocator.free(empty_string);
1955}