From f5954dad8356c05c294630f19609c343d65ea544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Larouche?= Date: Tue, 25 Feb 2020 15:07:35 -0500 Subject: [PATCH] Fix crash when freeing empty string as null-terminated sentinel --- lib/std/mem.zig | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 391d587dbc..4da7829570 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -1780,10 +1780,11 @@ fn SliceAsBytesReturnType(comptime sliceType: type) type { pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) { const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice; + const actualSliceTypeInfo = @typeInfo(@TypeOf(actualSlice)).Pointer; // let's not give an undefined pointer to @ptrCast // it may be equal to zero and fail a null check - if (actualSlice.len == 0) { + if (actualSlice.len == 0 and actualSliceTypeInfo.sentinel == null) { return &[0]u8{}; } @@ -1805,6 +1806,12 @@ test "sliceAsBytes" { })); } +test "sliceAsBytes with sentinel slice" { + const empty_string:[:0]const u8 = ""; + const bytes = sliceAsBytes(empty_string); + testing.expect(bytes.len == 0); +} + test "sliceAsBytes packed struct at runtime and comptime" { const Foo = packed struct { a: u4, @@ -1941,3 +1948,8 @@ test "isAligned" { testing.expect(!isAligned(4, 8)); testing.expect(!isAligned(4, 16)); } + +test "freeing empty string with null-terminated sentinel" { + const empty_string = try dupeZ(testing.allocator, u8, ""); + testing.allocator.free(empty_string); +}