mymarkdown

My markdown
git clone https://git.grace.moe/mymarkdown
Log | Files | Refs

commit 200c1f7c82ca4056761cd0d0ed2e368eec504501
parent 71831825ee34cefa215e26379e45c96d9b9f4e14
Author: gracefu <81774659+gracefuu@users.noreply.github.com>
Date:   Thu, 22 May 2025 14:01:12 +0800

Do a bit of fuzzing

Diffstat:
Msrc/AstGen3.zig | 2+-
Msrc/main.zig | 10+++++-----
Msrc/test.zig | 36+++++++++++++++++++++++++++++++++---
3 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/AstGen3.zig b/src/AstGen3.zig @@ -544,7 +544,7 @@ fn parseColumn( }, '*' => { - if (std.mem.eql(u8, line.toUnpaddedSlice()[0..3], "***")) { + if (std.mem.eql(u8, line.toUnpaddedSlice().ptr[0..3], "***")) { const after_stars = line.sliceOpen(3); if (after_stars.len == after_stars.indexOfNotSpaceOrTab()) { self.scanner.advance(); diff --git a/src/main.zig b/src/main.zig @@ -9,16 +9,16 @@ fn readInput(gpa: std.mem.Allocator, arena: std.mem.Allocator) !std.ArrayList(u8 defer tracy_frame.end(); if (stdin.stat()) |stat| { if (stat.size > 0) { - var al: std.ArrayList(u8) = try .initCapacity(arena, stat.size + mymarkdown.PADDING); - try stdin.reader().readAllArrayList(&al, std.math.maxInt(u32) - mymarkdown.PADDING); - try al.appendNTimes('\n', mymarkdown.PADDING); + var al: std.ArrayList(u8) = try .initCapacity(arena, stat.size + mymarkdown.PADDING + 1); + try stdin.reader().readAllArrayList(&al, std.math.maxInt(u32) - mymarkdown.PADDING - 1); + try al.appendNTimes('\n', mymarkdown.PADDING + 1); return al; } } else |_| {} var al: std.ArrayList(u8) = try .initCapacity(gpa, 4096); errdefer al.deinit(); - try stdin.reader().readAllArrayList(&al, std.math.maxInt(u32) - mymarkdown.PADDING); - try al.appendNTimes('\n', mymarkdown.PADDING); + try stdin.reader().readAllArrayList(&al, std.math.maxInt(u32) - mymarkdown.PADDING - 1); + try al.appendNTimes('\n', mymarkdown.PADDING + 1); return al; } diff --git a/src/test.zig b/src/test.zig @@ -12,11 +12,23 @@ fn readFile(gpa: std.mem.Allocator, path: []const u8) !std.ArrayList(u8) { const input_file = try std.fs.cwd().openFile(path, .{}); defer input_file.close(); const file_size = (try input_file.stat()).size; - try input_instance.ensureTotalCapacity(file_size + PADDING); - try input_file.reader().readAllArrayList(&input_instance, std.math.maxInt(u32) - PADDING); + try input_instance.ensureTotalCapacity(file_size + PADDING + 1); + try input_file.reader().readAllArrayList(&input_instance, std.math.maxInt(u32) - PADDING - 1); return input_instance; } +fn testForCrashes(gpa: std.mem.Allocator, input: []const u8) !void { + const padded_input = try std.mem.concat(gpa, u8, &.{ input, "\n" ** (PADDING + 1) }); + defer gpa.free(padded_input); + + const ast = try parse3(gpa, null, padded_input); + defer ast.deinit(gpa); + + var output_instance: std.ArrayList(u8) = .init(gpa); + defer output_instance.deinit(); + try ast.renderAst(output_instance.writer(), padded_input); +} + fn testSnapshot(gpa: std.mem.Allocator, path: []const u8) !void { return testSnapshotImpl(gpa, path); // std.testing.checkAllAllocationFailures( @@ -34,7 +46,7 @@ fn testSnapshotImpl(gpa: std.mem.Allocator, path: []const u8) !void { var input_instance = try readFile(gpa, path); defer input_instance.deinit(); - try input_instance.appendNTimes('\n', 128); + try input_instance.appendNTimes('\n', PADDING + 1); const ast = try parse3(gpa, null, input_instance.items); defer ast.deinit(gpa); @@ -121,6 +133,24 @@ test "Sample" { try testSnapshot(std.testing.allocator, "src/test/sample.my"); } +test "fuzz" { + var arena_instance: std.heap.ArenaAllocator = .init(std.testing.allocator); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); + try std.testing.fuzz(std.testing.allocator, testForCrashes, .{ + .corpus = &.{ + // (try readFile(arena, "src/test/empty.my")).items, + (try readFile(arena, "src/test/paragraph.my")).items, + (try readFile(arena, "src/test/heading.my")).items, + (try readFile(arena, "src/test/quote.my")).items, + (try readFile(arena, "src/test/list.my")).items, + (try readFile(arena, "src/test/elaboration.my")).items, + (try readFile(arena, "src/test/thematic_break.my")).items, + (try readFile(arena, "src/test/sample.my")).items, + }, + }); +} + test "Super long line" { const input = try std.testing.allocator.create([(1 << 24) * 4 + PADDING + 1]u8); defer std.testing.allocator.destroy(input);