Commit 9e52febeeb
Changed files (1)
lib
std
lib/std/io/Writer.zig
@@ -211,16 +211,37 @@ pub fn writeSplatHeader(
var vecs: [8][]const u8 = undefined; // Arbitrarily chosen size.
var i: usize = 1;
vecs[0] = header;
- for (data) |buf| {
+ for (data[0 .. data.len - 1]) |buf| {
if (buf.len == 0) continue;
vecs[i] = buf;
i += 1;
if (vecs.len - i == 0) break;
}
- const new_splat = if (vecs[i - 1].ptr == data[data.len - 1].ptr) splat else 1;
+ const pattern = data[data.len - 1];
+ const new_splat = s: {
+ if (pattern.len == 0 or vecs.len - i == 0) break :s 1;
+ vecs[i] = pattern;
+ i += 1;
+ break :s splat;
+ };
return w.vtable.drain(w, vecs[0..i], new_splat);
}
+test "writeSplatHeader splatting avoids buffer aliasing temptation" {
+ const initial_buf = try testing.allocator.alloc(u8, 8);
+ var aw: std.io.Writer.Allocating = .initOwnedSlice(testing.allocator, initial_buf);
+ defer aw.deinit();
+ // This test assumes 8 vector buffer in this function.
+ const n = try aw.writer.writeSplatHeader("header which is longer than buf ", &.{
+ "1", "2", "3", "4", "5", "6", "foo", "bar", "foo",
+ }, 3);
+ try testing.expectEqual(41, n);
+ try testing.expectEqualStrings(
+ "header which is longer than buf 123456foo",
+ aw.writer.buffered(),
+ );
+}
+
/// Equivalent to `writeSplatHeader` but writes at most `limit` bytes.
pub fn writeSplatHeaderLimit(
w: *Writer,
@@ -2037,8 +2058,8 @@ test "printFloat with comptime_float" {
var buf: [20]u8 = undefined;
var w: Writer = .fixed(&buf);
try w.printFloat(@as(comptime_float, 1.0), std.fmt.Options.toNumber(.{}, .scientific, .lower));
- try std.testing.expectEqualStrings(w.buffered(), "1e0");
- try std.testing.expectFmt("1", "{}", .{1.0});
+ try testing.expectEqualStrings(w.buffered(), "1e0");
+ try testing.expectFmt("1", "{}", .{1.0});
}
fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void {
@@ -2065,12 +2086,12 @@ test printByteSize {
test "bytes.hex" {
const some_bytes = "\xCA\xFE\xBA\xBE";
- try std.testing.expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes});
- try std.testing.expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes});
- try std.testing.expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]});
- try std.testing.expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]});
+ try testing.expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes});
+ try testing.expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes});
+ try testing.expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]});
+ try testing.expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]});
const bytes_with_zeros = "\x00\x0E\xBA\xBE";
- try std.testing.expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros});
+ try testing.expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros});
}
test fixed {
@@ -2479,7 +2500,7 @@ pub const Allocating = struct {
}
test Allocating {
- var a: Allocating = .init(std.testing.allocator);
+ var a: Allocating = .init(testing.allocator);
defer a.deinit();
const w = &a.writer;