···11-(*---------------------------------------------------------------------------
22- Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
33- SPDX-License-Identifier: ISC
44- ---------------------------------------------------------------------------*)
55-66-(** AFL-specific fuzzer for yamlrw parser.
77-88- This is a standalone AFL fuzzer that reads input from a file or stdin and
99- exercises the parser. Build with afl-instrument for best results.
1010-1111- Usage:
1212- {[
1313- # Build with AFL instrumentation
1414- opam switch create . ocaml-variants.5.2.0+options ocaml-option-afl
1515- dune build fuzz/fuzz_afl.exe
1616-1717- # Create seed corpus
1818- mkdir -p fuzz/input
1919- echo -n "" > fuzz/input/empty
2020- echo "null" > fuzz/input/null
2121- echo "true" > fuzz/input/bool
2222- echo "42" > fuzz/input/int
2323- echo "3.14" > fuzz/input/float
2424- echo "hello" > fuzz/input/string
2525- echo "key: value" > fuzz/input/mapping
2626- echo -e "- a\n- b" > fuzz/input/sequence
2727- echo -e "---\nfoo\n..." > fuzz/input/document
2828- echo "&anchor value" > fuzz/input/anchor
2929- echo "!tag value" > fuzz/input/tag
3030- echo -e "|\n literal\n block" > fuzz/input/literal
3131- echo -e ">\n folded\n block" > fuzz/input/folded
3232- echo "'single quoted'" > fuzz/input/single
3333- echo '"double quoted"' > fuzz/input/double
3434-3535- # Run AFL
3636- afl-fuzz -m none -i fuzz/input -o _fuzz -- _build/default/fuzz/fuzz_afl.exe @@
3737- ]} *)
3838-3939-(** Read entire file as string *)
4040-let read_file filename =
4141- let ic = open_in_bin filename in
4242- let n = in_channel_length ic in
4343- let s = really_input_string ic n in
4444- close_in ic;
4545- s
4646-4747-(** Read from stdin until EOF *)
4848-let read_stdin () =
4949- let buf = Buffer.create 1024 in
5050- try
5151- while true do
5252- Buffer.add_channel buf stdin 1024
5353- done;
5454- assert false
5555- with End_of_file -> Buffer.contents buf
5656-5757-(** Fuzz target: exercises all major parsing paths *)
5858-let fuzz_target input =
5959- (* Test value parsing *)
6060- (try
6161- let v = Yamlrw.of_string input in
6262- (* Exercise serialization *)
6363- let _ = Yamlrw.to_string v in
6464- (* Exercise different styles *)
6565- let _ = Yamlrw.to_string ~layout_style:`Block v in
6666- let _ = Yamlrw.to_string ~layout_style:`Flow v in
6767- (* Exercise pp *)
6868- let _ = Format.asprintf "%a" Yamlrw.pp v in
6969- ()
7070- with Yamlrw.Yamlrw_error _ -> ());
7171-7272- (* Test yaml parsing (with alias resolution) *)
7373- (try
7474- let y = Yamlrw.yaml_of_string ~resolve_aliases:true input in
7575- let _ = Yamlrw.yaml_to_string y in
7676- ()
7777- with Yamlrw.Yamlrw_error _ -> ());
7878-7979- (* Test yaml parsing (without alias resolution) *)
8080- (try
8181- let y = Yamlrw.yaml_of_string ~resolve_aliases:false input in
8282- let _ = Yamlrw.yaml_to_string y in
8383- ()
8484- with Yamlrw.Yamlrw_error _ -> ());
8585-8686- (* Test document parsing *)
8787- (try
8888- let docs = Yamlrw.documents_of_string input in
8989- let _ = Yamlrw.documents_to_string docs in
9090- ()
9191- with Yamlrw.Yamlrw_error _ -> ());
9292-9393- (* Test encoding detection *)
9494- let enc, _ = Yamlrw.Encoding.detect input in
9595- let _ = Yamlrw.Encoding.to_string enc in
9696-9797- (* Test streaming parser *)
9898- (try
9999- let parser = Yamlrw.Stream.parser input in
100100- Yamlrw.Stream.iter (fun _ _ _ -> ()) parser
101101- with Yamlrw.Yamlrw_error _ -> ());
102102-103103- (* Test scanner directly *)
104104- try
105105- let scanner = Yamlrw.Scanner.of_string input in
106106- let _ = Yamlrw.Scanner.to_list scanner in
107107- ()
108108- with Yamlrw.Yamlrw_error _ -> ()
109109-110110-let () =
111111- let input =
112112- if Array.length Sys.argv > 1 then read_file Sys.argv.(1) else read_stdin ()
113113- in
114114- fuzz_target input
fuzz/fuzz_common.ml
fuzz/helpers/fuzz_helpers.ml
+1-1
fuzz/fuzz_emitter.ml
···66(** Fuzz tests for the Emitter module - test random event sequences *)
7788open Crowbar
99-open Fuzz_common
99+open Fuzz_helpers
10101111(** Event type for fuzzing *)
1212type fuzz_event =
+1-1
fuzz/fuzz_tag.ml
···66(** Fuzz tests for Tag module *)
7788open Crowbar
99-open Fuzz_common
99+open Fuzz_helpers
10101111(** Test that of_string never crashes on arbitrary input *)
1212let test_of_string_crash buf =
+1-1
fuzz/fuzz_value.ml
···66(** Fuzz tests for Value module *)
7788open Crowbar
99-open Fuzz_common
99+open Fuzz_helpers
10101111(** Generator for Value.t *)
1212let rec value_gen depth =
+1-1
fuzz/fuzz_yamlrw.ml
···66(** Fuzz tests for the main Yamlrw parsing and serialization *)
7788open Crowbar
99-open Fuzz_common
99+open Fuzz_helpers
10101111(** Test that of_string never crashes on arbitrary input *)
1212let test_of_string_crash buf =