mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 19:08:50 +00:00
Remove ZigString.Slice.clone(...) (#21410)
### What does this PR do?
Removes `ZigString.Slice.clone(...)` and replaces all of its usages with
`.cloneIfNeeded(...)` which is what it did anyway (why did this alias
exist in the first place?)
Anyone reading code that sees `.clone(...)` would expect it to clone the
underlying string. This makes it _extremely_ easy to write code which
looks okay but actually results in a use-after-free:
```zig
const out: []const u8 = out: {
const string = bun.String.cloneUTF8("hello friends!");
defer string.deref();
const utf8_slice = string.toUTF8(bun.default_allocator);
defer utf8_slice.deinit();
// doesn't actually clone
const cloned = utf8_slice.clone(bun.default_allocator) catch bun.outOfMemory();
break :out cloned.slice();
};
std.debug.print("Use after free: {s}!\n", .{out});
```
(This is a simplification of an actual example from the codebase)
This commit is contained in:
@@ -89,7 +89,7 @@ pub const String = extern struct {
|
||||
}
|
||||
}
|
||||
|
||||
return .{ @constCast((try utf8_slice.clone(allocator)).slice()), true };
|
||||
return .{ @constCast((try utf8_slice.cloneIfNeeded(allocator)).slice()), true };
|
||||
},
|
||||
.StaticZigString => return .{ try this.value.StaticZigString.toOwnedSlice(allocator), false },
|
||||
else => return .{ &[_]u8{}, false },
|
||||
|
||||
Reference in New Issue
Block a user