From be706fecb4c74a6c234c2a8b6b29d6afbd74ecfa Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Fri, 30 Dec 2022 21:30:23 -0800 Subject: [PATCH] Make `NamesIterator` safer --- src/install/bin.zig | 24 +++++++++++++++--------- src/string_immutable.zig | 9 +++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/install/bin.zig b/src/install/bin.zig index c7c3b37990..c7dd50367b 100644 --- a/src/install/bin.zig +++ b/src/install/bin.zig @@ -191,16 +191,19 @@ pub const Bin = extern struct { this.i += 1; this.done = true; const base = std.fs.path.basename(this.package_name.slice(this.string_buffer)); - if (strings.hasPrefix(base, "./")) return base[2..]; - return base; + if (strings.hasPrefix(base, "./")) + return strings.copy(&this.buf, base[2..]); + + return strings.copy(&this.buf, base); }, .named_file => { if (this.i > 0) return null; this.i += 1; this.done = true; const base = std.fs.path.basename(this.bin.value.named_file[0].slice(this.string_buffer)); - if (strings.hasPrefix(base, "./")) return base[2..]; - return base; + if (strings.hasPrefix(base, "./")) + return strings.copy(&this.buf, base[2..]); + return strings.copy(&this.buf, base); }, .dir => return try this.nextInDir(), @@ -209,15 +212,18 @@ pub const Bin = extern struct { const index = this.i; this.i += 2; this.done = this.i >= this.bin.value.map.len; + const current_string = this.bin.value.map.get( + this.extern_string_buf, + )[index]; + const base = std.fs.path.basename( - this.bin.value.map.get( - this.extern_string_buf, - )[index].slice( + current_string.slice( this.string_buffer, ), ); - if (strings.hasPrefix(base, "./")) return base[2..]; - return base; + if (strings.hasPrefix(base, "./")) + return strings.copy(&this.buf, base[2..]); + return strings.copy(&this.buf, base); }, else => return null, } diff --git a/src/string_immutable.zig b/src/string_immutable.zig index e3e72726f5..db1d459af5 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -498,6 +498,15 @@ test "StringOrTinyString Lowercase" { try std.testing.expectEqualStrings("hello!!!!!", str.slice()); } +/// Copy a string into a buffer +/// Return the copied version +pub fn copy(buf: []u8, src: []const u8) []const u8 { + const len = @min(buf.len, src.len); + if (len > 0) + @memcpy(buf.ptr, src.ptr, len); + return buf[0..len]; +} + /// startsWith except it checks for non-empty strings pub fn hasPrefix(self: string, str: string) bool { return str.len > 0 and startsWith(self, str);