const std = @import("std"); /// Materialize terminal control characters as visible glyphs for failure output. /// This is test/debug support only: product rendering still writes real CR/LF/ESC. pub fn visibleControlsAlloc(allocator: std.mem.Allocator, bytes: []const u8) ![]u8 { var out = std.ArrayList(u8).empty; errdefer out.deinit(allocator); for (bytes) |byte| switch (byte) { '\r' => try out.appendSlice(allocator, "␍"), '\n' => try out.appendSlice(allocator, "␊\n"), 0x1b => try out.appendSlice(allocator, "␛"), '\t' => try out.appendSlice(allocator, "⇥"), else => if (byte < 0x20) { try out.appendSlice(allocator, "␀"); } else try out.append(allocator, byte), }; return out.toOwnedSlice(allocator); } pub fn hasBareLf(bytes: []const u8) bool { for (bytes, 0..) |byte, i| { if (byte == '\n' and (i == 0 or bytes[i - 1] != '\r')) return true; } return false; } test "regular: visible terminal controls expose newline and escape bytes" { const debug = try visibleControlsAlloc(std.testing.allocator, "a\nb\r\n\x1b[31m"); defer std.testing.allocator.free(debug); try std.testing.expectEqualStrings("a␊\nb␍␊\n␛[31m", debug); } test "adversarial: bare LF detector catches raw-mode skew risk" { try std.testing.expect(hasBareLf("a\nb")); try std.testing.expect(!hasBareLf("a\r\nb")); }