authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-08-26 14:17:43-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-08-28 00:26:13+02:00
loge19a73c2d5b61d783470daa8aabbaba23ceb4578
treed5d66640f552c07d03e2f713e95801e84d261234
parentba74ad552592108ccc3e0ad6fb94eff639db2e45

Fix std.zig.StringEscapeWriter drain function returning the wrong information

`drain` should return the number of bytes consumed from `data` Fixes #36647

1 files changed, 18 insertions(+), 3 deletions(-)

lib/std/zig.zig+18-3
......@@ -601,20 +601,35 @@ pub const StringEscapeWriter = struct {
601601 fn drain(w: *Writer, data: []const []const u8, splat: usize) Io.Writer.Error!usize {
602602 const sew: *StringEscapeWriter = @alignCast(@fieldParentPtr("writer", w));
603603 const out = sew.out;
604 _ = try stringEscapeCounting(w.buffered(), out);
604 try stringEscape(w.buffered(), out);
605605 w.end = 0;
606606 var n: usize = 0;
607607 for (data[0 .. data.len - 1]) |bytes| {
608 n += try stringEscapeCounting(bytes, out);
608 try stringEscape(bytes, out);
609 n += bytes.len;
609610 }
610611 const pattern = data[data.len - 1];
611612 for (0..splat) |_| {
612 n += try stringEscapeCounting(pattern, out);
613 try stringEscape(pattern, out);
614 n += pattern.len;
613615 }
614616 return n;
615617 }
616618};
617619
620test StringEscapeWriter {
621 const bytes = "\x7f\t\n\r\\\"abc";
622 const escaped = "\\x7f\\t\\n\\r\\\\\\\"abc";
623
624 var out_buf: [escaped.len]u8 = undefined;
625 var out: Io.Writer = .fixed(&out_buf);
626 var w: StringEscapeWriter = .init(&out, &.{});
627
628 const n = try w.writer.write(bytes);
629 try std.testing.expectEqual(bytes.len, n);
630 try std.testing.expectEqualStrings(escaped, out.buffered());
631}
632
618633/// Print as escaped contents of a single-quoted string.
619634pub fn charEscape(codepoint: u21, w: *Writer) Writer.Error!void {
620635 switch (codepoint) {