mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
test/fuzz-libghostty: basic afl++-based fuzzer for libghostty
This commit is contained in:
@@ -32,6 +32,7 @@ pub const modes = terminal.modes;
|
||||
pub const page = terminal.page;
|
||||
pub const parse_table = terminal.parse_table;
|
||||
pub const search = terminal.search;
|
||||
pub const sgr = terminal.sgr;
|
||||
pub const size = terminal.size;
|
||||
pub const x11_color = terminal.x11_color;
|
||||
|
||||
|
||||
4
test/fuzz-libghostty/AGENTS.md
Normal file
4
test/fuzz-libghostty/AGENTS.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# AFL++ Fuzzer for Libghostty
|
||||
|
||||
- `ghostty-fuzz` is a binary built with `afl-cc`
|
||||
- Build `ghostty-fuzz` with `zig build`
|
||||
62
test/fuzz-libghostty/build.zig
Normal file
62
test/fuzz-libghostty/build.zig
Normal file
@@ -0,0 +1,62 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// Create the C ABI library from Zig source that exports the
|
||||
// API that the `afl-cc` main.c entrypoint can call into. This
|
||||
// lets us just use standard `afl-cc` to fuzz test our library without
|
||||
// needing to write any Zig-specific fuzzing harnesses.
|
||||
const lib = lib: {
|
||||
// Zig module
|
||||
const lib_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/lib.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
if (b.lazyDependency("ghostty", .{
|
||||
.simd = false,
|
||||
})) |dep| {
|
||||
lib_mod.addImport(
|
||||
"ghostty-vt",
|
||||
dep.module("ghostty-vt"),
|
||||
);
|
||||
}
|
||||
|
||||
// C lib
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "ghostty-fuzz",
|
||||
.root_module = lib_mod,
|
||||
});
|
||||
|
||||
// Required to build properly with afl-cc
|
||||
lib.bundle_compiler_rt = true;
|
||||
lib.bundle_ubsan_rt = true;
|
||||
lib.root_module.stack_check = false;
|
||||
|
||||
break :lib lib;
|
||||
};
|
||||
|
||||
// Build a C entrypoint with afl-cc that links against the generated
|
||||
// static Zig library. afl-cc is expecte to be on the PATH.
|
||||
const exe = exe: {
|
||||
const cc = b.addSystemCommand(&.{"afl-cc"});
|
||||
cc.addArgs(&.{
|
||||
"-std=c11",
|
||||
"-O2",
|
||||
"-g",
|
||||
"-o",
|
||||
});
|
||||
const output = cc.addOutputFileArg("ghostty-fuzz");
|
||||
cc.addFileArg(b.path("src/main.c"));
|
||||
cc.addFileArg(lib.getEmittedBin());
|
||||
|
||||
break :exe output;
|
||||
};
|
||||
|
||||
// Install
|
||||
b.installArtifact(lib);
|
||||
const exe_install = b.addInstallBinFile(exe, "ghostty-fuzz");
|
||||
b.getInstallStep().dependOn(&exe_install.step);
|
||||
}
|
||||
14
test/fuzz-libghostty/build.zig.zon
Normal file
14
test/fuzz-libghostty/build.zig.zon
Normal file
@@ -0,0 +1,14 @@
|
||||
.{
|
||||
.name = .fuzz_libghostty,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0x2cb2c498237c5d43,
|
||||
.minimum_zig_version = "0.15.1",
|
||||
.dependencies = .{
|
||||
.ghostty = .{ .path = "../../" },
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
},
|
||||
}
|
||||
11
test/fuzz-libghostty/src/lib.zig
Normal file
11
test/fuzz-libghostty/src/lib.zig
Normal file
@@ -0,0 +1,11 @@
|
||||
const std = @import("std");
|
||||
const ghostty_vt = @import("ghostty-vt");
|
||||
|
||||
pub export fn ghostty_fuzz_parser(
|
||||
input_ptr: [*]const u8,
|
||||
input_len: usize,
|
||||
) callconv(.c) void {
|
||||
var p: ghostty_vt.Parser = .init();
|
||||
defer p.deinit();
|
||||
for (input_ptr[0..input_len]) |byte| _ = p.next(byte);
|
||||
}
|
||||
27
test/fuzz-libghostty/src/main.c
Normal file
27
test/fuzz-libghostty/src/main.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void ghostty_fuzz_parser(const uint8_t *input, size_t input_len);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint8_t buf[4096];
|
||||
size_t len = 0;
|
||||
FILE *f = stdin;
|
||||
|
||||
if (argc > 1) {
|
||||
f = fopen(argv[1], "rb");
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
len = fread(buf, 1, sizeof(buf), f);
|
||||
|
||||
if (argc > 1) {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
ghostty_fuzz_parser(buf, len);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user