libghostty-vt parser fuzzing, generic fuzz harness, using AFL++ (#11089)

This adds a `test/fuzz-libghostty` which is a standalone `zig build`
target for building an AFL++ instrumented executable for fuzzing the
libghostty-vt parser. I also added a `pkg/afl++` (based on zig-afl-kit)
so instrumenting objects and using AFL++ is a bit easier.

Fuzzing `libghostty-vt`'s parser is as easy as `zig build run`, but see
the README for a lot more details. I ran the fuzzer for ~14 hours total
and only found one crash #11088. I'm pretty confident at this point our
Parser layer isn't obviously crash-able, but need to instrument more
places to fuzz.

We don't use Zig's built-in fuzzing yet because as of 0.15 (our current
stable), it isn't ready and AFL++ is an industry proven tool to do this.
This commit is contained in:
Mitchell Hashimoto
2026-03-01 13:16:52 -08:00
committed by GitHub
681 changed files with 688 additions and 0 deletions

View File

@@ -102,6 +102,7 @@ jobs:
- test-gtk
- test-sentry-linux
- test-i18n
- test-fuzz-libghostty
- test-macos
- pinact
- prettier
@@ -1010,6 +1011,51 @@ jobs:
run: |
nix develop -c zig build -Di18n=${{ matrix.i18n }}
test-fuzz-libghostty:
name: Build test/fuzz-libghostty
runs-on: namespace-profile-ghostty-sm
needs: test
env:
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
with:
path: |
/nix
/zig
# Install Nix and use that to run our tests so our environment matches exactly.
- uses: cachix/install-nix-action@2126ae7fc54c9df00dd18f7f18754393182c73cd # v31.9.1
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1 # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Install AFL++ and LLVM
run: |
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y afl++ llvm
- name: Verify AFL++ and LLVM are available
run: |
afl-cc --version
if command -v llvm-config >/dev/null 2>&1; then
llvm-config --version
else
llvm-config-18 --version
fi
- name: Build fuzzer harness
run: |
nix develop -c sh -c 'cd test/fuzz-libghostty && zig build'
zig-fmt:
if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.zig == 'true'
needs: skip

23
pkg/afl++/LICENSE Normal file
View File

@@ -0,0 +1,23 @@
Based on zig-afl-kit: https://github.com/kristoff-it/zig-afl-kit
MIT License
Copyright (c) 2024 Loris Cro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

141
pkg/afl++/afl.c Normal file
View File

@@ -0,0 +1,141 @@
#include <limits.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// AFL++ fuzzer harness for Zig fuzz targets.
//
// This file is the C "glue" that connects AFL++'s runtime to Zig-defined
// fuzz test functions. We can't use AFL++'s compiler wrappers (afl-clang,
// afl-gcc) because the code under test is compiled with Zig, so we manually
// expand the AFL macros (__AFL_INIT, __AFL_LOOP, __AFL_FUZZ_INIT, etc.) and
// wire up the sanitizer coverage symbols ourselves.
// To ensure checks are not optimized out it is recommended to disable
// code optimization for the fuzzer harness main()
#pragma clang optimize off
#pragma GCC optimize("O0")
// Zig-exported entry points. zig_fuzz_init() performs one-time setup and
// zig_fuzz_test() runs one fuzz iteration on the given input buffer.
// The Zig object should export these.
void zig_fuzz_init();
void zig_fuzz_test(unsigned char*, size_t);
// Linker-provided symbols marking the boundaries of the __sancov_guards
// section. These must be declared extern so the linker provides the actual
// section boundaries from the instrumented code, rather than creating new
// variables that shadow them. On macOS (Mach-O), the linker uses a different
// naming convention for section boundaries than Linux (ELF), so we use asm
// labels to reference them.
#ifdef __APPLE__
extern uint32_t __start___sancov_guards __asm(
"section$start$__DATA$__sancov_guards");
extern uint32_t __stop___sancov_guards __asm(
"section$end$__DATA$__sancov_guards");
#else
extern uint32_t __start___sancov_guards;
extern uint32_t __stop___sancov_guards;
#endif
// Provided by afl-compiler-rt; initializes the guard array used by
// SanitizerCoverage's trace-pc-guard instrumentation mode.
void __sanitizer_cov_trace_pc_guard_init(uint32_t*, uint32_t*);
// Stubs for sanitizer coverage callbacks that the Zig-compiled code references
// but AFL's runtime (afl-compiler-rt) does not provide. Without these, linking
// would fail with undefined symbol errors.
__attribute__((visibility("default"))) __attribute__((
tls_model("initial-exec"))) _Thread_local uintptr_t __sancov_lowest_stack;
void __sanitizer_cov_trace_pc_indir() {}
void __sanitizer_cov_8bit_counters_init() {}
void __sanitizer_cov_pcs_init() {}
// Manual expansion of __AFL_FUZZ_INIT().
//
// Enables shared-memory fuzzing: AFL++ writes test cases directly into
// shared memory (__afl_fuzz_ptr) instead of passing them via stdin, which
// is much faster. When not running under AFL++ (e.g. standalone execution),
// __afl_fuzz_ptr will be NULL and we fall back to reading from stdin into
// __afl_fuzz_alt (a 1 MB static buffer).
int __afl_sharedmem_fuzzing = 1;
extern __attribute__((visibility("default"))) unsigned int* __afl_fuzz_len;
extern __attribute__((visibility("default"))) unsigned char* __afl_fuzz_ptr;
unsigned char __afl_fuzz_alt[1048576];
unsigned char* __afl_fuzz_alt_ptr = __afl_fuzz_alt;
int main(int argc, char** argv) {
// Tell AFL's coverage runtime about our guard section so it can track
// which edges in the instrumented Zig code have been hit.
__sanitizer_cov_trace_pc_guard_init(&__start___sancov_guards,
&__stop___sancov_guards);
// Manual expansion of __AFL_INIT() — deferred fork server mode.
//
// The magic string "##SIG_AFL_DEFER_FORKSRV##" is embedded in the binary
// so AFL++'s tooling can detect that this harness uses deferred fork
// server initialization. The `volatile` + `used` attributes prevent the
// compiler/linker from stripping it. We then call __afl_manual_init() to
// start the fork server at this point (after our setup) rather than at
// the very beginning of main().
static volatile const char* _A __attribute__((used, unused));
_A = (const char*)"##SIG_AFL_DEFER_FORKSRV##";
#ifdef __APPLE__
__attribute__((visibility("default"))) void _I(void) __asm__(
"___afl_manual_init");
#else
__attribute__((visibility("default"))) void _I(void) __asm__(
"__afl_manual_init");
#endif
_I();
zig_fuzz_init();
// Manual expansion of __AFL_FUZZ_TESTCASE_BUF.
// Use shared memory buffer if available, otherwise fall back to the
// static buffer (for standalone/non-AFL execution).
unsigned char* buf = __afl_fuzz_ptr ? __afl_fuzz_ptr : __afl_fuzz_alt_ptr;
// Manual expansion of __AFL_LOOP(UINT_MAX) — persistent mode loop.
//
// Persistent mode keeps the process alive across many test cases instead
// of fork()'ing for each one, dramatically improving throughput. The magic
// string "##SIG_AFL_PERSISTENT##" signals to AFL++ that this binary
// supports persistent mode. __afl_persistent_loop() returns non-zero
// while there are more inputs to process.
//
// When connected to AFL++, we loop UINT_MAX times (essentially forever,
// AFL will restart us periodically). When running standalone, we loop
// once so the harness can be used for manual testing/reproduction.
while (({
static volatile const char* _B __attribute__((used, unused));
_B = (const char*)"##SIG_AFL_PERSISTENT##";
extern __attribute__((visibility("default"))) int __afl_connected;
#ifdef __APPLE__
__attribute__((visibility("default"))) int _L(unsigned int) __asm__(
"___afl_persistent_loop");
#else
__attribute__((visibility("default"))) int _L(unsigned int) __asm__(
"__afl_persistent_loop");
#endif
_L(__afl_connected ? UINT_MAX : 1);
})) {
// Manual expansion of __AFL_FUZZ_TESTCASE_LEN.
// In shared-memory mode, the length is provided directly by AFL++.
// In standalone mode, we read from stdin into the fallback buffer.
int len =
__afl_fuzz_ptr ? *__afl_fuzz_len
: (*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff
? 0
: *__afl_fuzz_len;
if (len >= 0) {
zig_fuzz_test(buf, len);
}
}
return 0;
}

60
pkg/afl++/build.zig Normal file
View File

@@ -0,0 +1,60 @@
const std = @import("std");
/// Creates a build step that produces an AFL++-instrumented fuzzing
/// executable.
///
/// Returns a `LazyPath` to the resulting fuzzing executable.
pub fn addInstrumentedExe(
b: *std.Build,
obj: *std.Build.Step.Compile,
) std.Build.LazyPath {
// Force the build system to produce the binary artifact even though we
// only consume the LLVM bitcode below. Without this, the dependency
// tracking doesn't wire up correctly.
_ = obj.getEmittedBin();
const pkg = b.dependencyFromBuildZig(
@This(),
.{},
);
const afl_cc = b.addSystemCommand(&.{
b.findProgram(&.{"afl-cc"}, &.{}) catch
@panic("Could not find 'afl-cc', which is required to build"),
"-O3",
});
afl_cc.addArg("-o");
const fuzz_exe = afl_cc.addOutputFileArg(obj.name);
afl_cc.addFileArg(pkg.path("afl.c"));
afl_cc.addFileArg(obj.getEmittedLlvmBc());
return fuzz_exe;
}
/// Creates a run step that invokes `afl-fuzz` with the given instrumented
/// executable, input corpus directory, and output directory.
///
/// Returns the `Run` step so callers can wire it into a build step.
pub fn addFuzzerRun(
b: *std.Build,
exe: std.Build.LazyPath,
corpus_dir: std.Build.LazyPath,
output_dir: std.Build.LazyPath,
) *std.Build.Step.Run {
const run = b.addSystemCommand(&.{
b.findProgram(&.{"afl-fuzz"}, &.{}) catch
@panic("Could not find 'afl-fuzz', which is required to run"),
"-i",
});
run.addDirectoryArg(corpus_dir);
run.addArgs(&.{"-o"});
run.addDirectoryArg(output_dir);
run.addArgs(&.{"--"});
run.addFileArg(exe);
run.addArgs(&.{"@@"});
return run;
}
// Required so `zig build` works although it does nothing.
pub fn build(b: *std.Build) !void {
_ = b;
}

11
pkg/afl++/build.zig.zon Normal file
View File

@@ -0,0 +1,11 @@
.{
.name = .afl_plus_plus,
.fingerprint = 0x465bc4bebb188f16,
.version = "0.1.0",
.dependencies = .{},
.paths = .{
"build.zig",
"build.zig.zon",
"afl.c",
},
}

View File

@@ -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;

6
test/fuzz-libghostty/.gitattributes vendored Normal file
View File

@@ -0,0 +1,6 @@
# Hand-written seed corpus: binary files, track as-is
corpus/initial/** binary
# Generated/minimized corpora: binary, mark as generated
corpus/vt-parser-cmin/** binary linguist-generated=true
corpus/vt-parser-min/** binary linguist-generated=true

9
test/fuzz-libghostty/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
# Build artifacts
.zig-cache/
zig-out/
# AFL++ outputs
afl-out/
# Corpus trace files
corpus/**/.traces/

View File

@@ -0,0 +1,38 @@
# AFL++ Fuzzer for Libghostty
- `ghostty-fuzz` is a binary built with `afl-cc`
- Build `ghostty-fuzz` with `zig build`
- After running `afl-cmin`/`afl-tmin`, run `corpus/sanitize-filenames.sh`
before committing to replace colons with underscores (colons are invalid
on Windows NTFS).
## Important: stdin-based input
The instrumented binary (`afl.c` harness) reads fuzz input from **stdin**,
not from a file argument. This affects how you invoke AFL++ tools:
- **`afl-fuzz`**: Uses shared-memory fuzzing automatically; `@@` works
because AFL writes directly to shared memory, bypassing file I/O.
- **`afl-showmap`**: Must pipe input via stdin, **not** `@@`:
```sh
cat testcase | afl-showmap -o map.txt -- zig-out/bin/ghostty-fuzz
```
- **`afl-cmin`**: Do **not** use `@@`. Requires `AFL_NO_FORKSRV=1` with
the bash version due to a bug in the Python `afl-cmin` (AFL++ 4.35c):
```sh
AFL_NO_FORKSRV=1 /opt/homebrew/Cellar/afl++/4.35c/libexec/afl-cmin.bash \
-i afl-out/default/queue -o corpus/vt-parser-cmin \
-- zig-out/bin/ghostty-fuzz
```
- **`afl-tmin`**: Also requires `AFL_NO_FORKSRV=1`, no `@@`:
```sh
AFL_NO_FORKSRV=1 afl-tmin -i <input> -o <output> -- zig-out/bin/ghostty-fuzz
```
If you pass `@@` or a filename argument, `afl-showmap`/`afl-cmin`/`afl-tmin`
will see only ~4 tuples (the C main paths) and produce useless results.

View File

@@ -0,0 +1,137 @@
# AFL++ Fuzzer for Libghostty
This directory contains an [AFL++](https://aflplus.plus/) fuzzing harness for
libghostty-vt (Zig module). At the time of writing this README, it only
fuzzes the VT parser, but it can be extended to cover other components of
libghostty as well.
## Prerequisites
Install AFL++ so that `afl-cc` and `afl-fuzz` are on your `PATH`.
- **macOS (Homebrew):** `brew install aflplusplus`
- **Linux:** build from source or use your distro's package (e.g.
`apt install afl++` on Debian/Ubuntu).
## Building
From this directory (`test/fuzz-libghostty`):
```sh
zig build
```
This compiles a Zig static library (with the fuzz harness in `src/lib.zig`),
emits LLVM bitcode, then links it with `src/main.c` using `afl-cc` to produce
the instrumented binary at `zig-out/bin/ghostty-fuzz`.
## Running the Fuzzer
The build system has a convenience step that invokes `afl-fuzz` with the
correct arguments:
```sh
zig build run
```
This is equivalent to:
```sh
afl-fuzz -i corpus/initial -o afl-out -- zig-out/bin/ghostty-fuzz @@
```
You may want to run `afl-fuzz` directly with different options
for your own experimentation.
The fuzzer runs indefinitely. Let it run for as long as you like; meaningful
coverage is usually reached within a few hours, but longer runs can find
deeper bugs. Press `ctrl+c` to stop the fuzzer when you're done.
## Finding Crashes and Hangs
After (or during) a run, results are written to `afl-out/default/`:
```
afl-out/default/
├── crashes/ # Inputs that triggered crashes
├── hangs/ # Inputs that triggered hangs/timeouts
└── queue/ # All interesting inputs (the evolved corpus)
```
Each file in `crashes/` or `hangs/` is a raw byte file that triggered the
issue. The filename encodes metadata about how it was found (e.g.
`id:000000,sig:06,...`).
## Reproducing a Crash
Replay any crashing input by piping it into the harness:
```sh
cat afl-out/default/crashes/<filename> | zig-out/bin/ghostty-fuzz
```
## Corpus Management
After a fuzzing run, the queue in `afl-out/default/queue/` typically
contains many redundant inputs. Use `afl-cmin` to find the smallest
subset that preserves full edge coverage, and `afl-tmin` to shrink
individual test cases.
> **Important:** The instrumented binary reads input from **stdin**, not
> from file arguments. Do **not** use `@@` with `afl-cmin`, `afl-tmin`,
> or `afl-showmap` — it will cause them to see only the C harness
> coverage (~4 tuples) instead of the Zig VT parser coverage.
### Corpus minimization (`afl-cmin`)
Reduce the evolved queue to a minimal set covering all discovered edges:
```sh
AFL_NO_FORKSRV=1 afl-cmin.bash \
-i afl-out/default/queue \
-o corpus/vt-parser-cmin \
-- zig-out/bin/ghostty-fuzz
```
`AFL_NO_FORKSRV=1` is required because the Python `afl-cmin` wrapper has
a bug in AFL++ 4.35c. Use the `afl-cmin.bash` script instead (typically
found in AFL++'s `libexec` directory).
### Test case minimization (`afl-tmin`)
Shrink each file in the minimized corpus to the smallest input that
preserves its unique coverage:
```sh
mkdir -p corpus/vt-parser-min
for f in corpus/vt-parser-cmin/*; do
AFL_NO_FORKSRV=1 afl-tmin \
-i "$f" \
-o "corpus/vt-parser-min/$(basename "$f")" \
-- zig-out/bin/ghostty-fuzz
done
```
This is slow (hundreds of executions per file) but produces the most
compact corpus. It can be skipped if you only need edge-level
deduplication from `afl-cmin`.
### Windows compatibility
AFL++ output filenames contain colons (e.g., `id:000024,time:0,...`), which
are invalid on Windows (NTFS). After running `afl-cmin` or `afl-tmin`,
rename the output files to replace colons with underscores before committing:
```sh
./corpus/sanitize-filenames.sh
```
### Corpus directories
| Directory | Contents |
| ------------------------ | ----------------------------------------------- |
| `corpus/initial/` | Hand-written seed inputs for `afl-fuzz -i` |
| `corpus/vt-parser-cmin/` | Output of `afl-cmin` (edge-deduplicated corpus) |
| `corpus/vt-parser-min/` | Output of `afl-tmin` (individually minimized) |

View File

@@ -0,0 +1,59 @@
const std = @import("std");
const afl = @import("afl");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the fuzzer with afl-fuzz");
// 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.root_module.stack_check = false;
lib.root_module.fuzz = true;
break :lib lib;
};
// Build a C entrypoint with afl-cc that links against the generated
// static Zig library. afl-cc is expected to be on the PATH.
const exe = afl.addInstrumentedExe(b, lib);
// Runner to simplify running afl-fuzz.
// Use the cmin corpus (edge-deduplicated from prior runs) so that each
// fuzzing session starts from full coverage. Switch to "corpus/initial"
// if you don't have a cmin corpus yet.
const run = afl.addFuzzerRun(b, exe, b.path("corpus/vt-parser-cmin"), b.path("afl-out"));
// Install
b.installArtifact(lib);
const exe_install = b.addInstallBinFile(exe, "ghostty-fuzz");
b.getInstallStep().dependOn(&exe_install.step);
// Run
run_step.dependOn(&run.step);
}

View File

@@ -0,0 +1,15 @@
.{
.name = .fuzz_libghostty,
.version = "0.0.0",
.fingerprint = 0x2cb2c498237c5d43,
.minimum_zig_version = "0.15.1",
.dependencies = .{
.ghostty = .{ .path = "../../" },
.afl = .{ .path = "../../pkg/afl++" },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View File

@@ -0,0 +1 @@
Hello, World!

View File

@@ -0,0 +1,3 @@
line1
line2
line3

View File

@@ -0,0 +1 @@
col1 col2 col3

View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@
78

View File

@@ -0,0 +1 @@
=>

View File

@@ -0,0 +1 @@
DM

View File

@@ -0,0 +1 @@
c

View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@
Red Bold

View File

@@ -0,0 +1 @@
color

View File

@@ -0,0 +1 @@
truecolor

View File

@@ -0,0 +1 @@
[?1049h[?1049l

View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@
[61"p

View File

@@ -0,0 +1 @@
]0;My Window Title

View File

@@ -0,0 +1 @@
]0;Title\

View File

@@ -0,0 +1 @@
]1;icon

View File

@@ -0,0 +1 @@
]52;c;SGVsbG8=

View File

@@ -0,0 +1 @@
]8;;https://example.comlink]8;;

View File

@@ -0,0 +1 @@
]4;1;rgb:ff/00/00

View File

@@ -0,0 +1 @@
]10;rgb:ff/ff/ff

View File

@@ -0,0 +1 @@
P+q544e\

View File

@@ -0,0 +1 @@
P\$qm\

View File

@@ -0,0 +1 @@
P1000p\

View File

@@ -0,0 +1 @@
<EFBFBD>test<EFBFBD>

View File

@@ -0,0 +1 @@
<EFBFBD>m

View File

@@ -0,0 +1 @@
<EFBFBD>test<EFBFBD>

View File

@@ -0,0 +1 @@
éàü

View File

@@ -0,0 +1 @@
–—

View File

@@ -0,0 +1 @@
😀🎉

View File

@@ -0,0 +1 @@
beforeredafter

View File

@@ -0,0 +1 @@
]0;title

View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@
[4:3m

View File

@@ -0,0 +1 @@
[

View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@
]0;partial

View File

@@ -0,0 +1 @@
ABC

View File

@@ -0,0 +1 @@
(0lqqk(B

View File

@@ -0,0 +1 @@
[?25l[?25h

View File

@@ -0,0 +1 @@
[>c

View File

@@ -0,0 +1 @@


View File

@@ -0,0 +1 @@
_application\

View File

@@ -0,0 +1,23 @@
#!/bin/sh
# Rename AFL++ output files to replace colons with underscores.
# Colons are invalid on Windows (NTFS).
#
# Usage: ./sanitize-filenames.sh [directory ...]
# Defaults to vt-parser-cmin and vt-parser-min in the same directory as this script.
cd "$(dirname "$0")" || exit 1
if [ $# -gt 0 ]; then
set -- "$@"
else
set -- vt-parser-cmin vt-parser-min
fi
for dir in "$@"; do
[ -d "$dir" ] || continue
for f in "$dir"/*; do
[ -f "$f" ] || continue
newname=$(echo "$f" | tr ':' '_')
[ "$f" != "$newname" ] && mv "$f" "$newname"
done
done

View File

@@ -0,0 +1 @@
😀🎉dow <20><><EFBFBD><EFBFBD><EFBFBD>VVVVUV[4:0{<7B><EFBFBD>

View File

@@ -0,0 +1 @@
do<64><6F><EFBFBD>VVVVUV[4:{<7B><EFBFBD>>0

View File

@@ -0,0 +1 @@
<EFBFBD>]93kA<01>]N6ڞ<><DA9E><EFBFBD><EFBFBD><EFBFBD>t]15Q]118]116@]119;<3B>]++++q;3;15Q]118]116f5N@]119;<3B>W5;6;<3B>(

View File

@@ -0,0 +1 @@
<EFBFBD>]<5D>i5N@]112;p];p<1A><>4<EFBFBD><34>

View File

@@ -0,0 +1 @@
<EFBFBD>]9[<5B>]114;p]9;;;plm5@l10'e]1;i[<5B>]114;p]9;;;plm5@

View File

@@ -0,0 +1 @@
 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>]9><0F><>]8]9;1;44444444444444444444444444444<34>@N@lltt<74>;V[4]1p4:3m^

View File

@@ -0,0 +1 @@
;6]66;;]<5D><><EFBFBD><EFBFBD>]1331e'<27>;6]66;;]<5D><><EFBFBD><EFBFBD>]1331e<31>66<36><36>j<EFBFBD>f;o<1A><>4];6]66<36><36>66<36><36>j<EFBFBD>f:p<18><>4<EFBFBD><34>

Some files were not shown because too many files have changed in this diff Show More