Commit f5954dad83

Michaël Larouche <michael.larouche@gmail.com>
2020-02-25 21:07:35
Fix crash when freeing empty string as null-terminated sentinel
1 parent 1091fee
Changed files (1)
lib
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);
+}