OCaml HTML5 parser/serialiser based on Python's JustHTML

Improve fuzz test debugging tools

- Add test_crash and test_pre executables to dune build
- Show namespace in DOM dump for debugging SVG/MathML issues
- Print full s2/s3 serialization output for easier diff analysis

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+6
+2
fuzz/dune
··· 5 5 (executable 6 6 (name fuzz_afl) 7 7 (libraries bytesrw html5rw afl-persistent)) 8 + (executable (name test_crash) (libraries bytesrw html5rw)) 9 + (executable (name test_pre) (libraries bytesrw html5rw))
+4
fuzz/test_crash.ml
··· 4 4 let rec dump_node indent (node : Html5rw.Dom.node) = 5 5 let padding = String.make (indent * 2) ' ' in 6 6 Printf.printf "%s[%s]" padding (String.escaped node.name); 7 + (match node.namespace with Some ns -> Printf.printf " ns=%s" ns | None -> ()); 7 8 if node.attrs <> [] then begin 8 9 Printf.printf " attrs=%d" (List.length node.attrs) 9 10 end; ··· 29 30 Printf.printf "=== After 3rd parse ===\n"; 30 31 dump_node 0 (Html5rw.root r3); 31 32 Printf.printf "\ns3 (%d): %s\n\n" (String.length s3) (String.escaped (String.sub s3 0 (min 200 (String.length s3)))); 33 + 34 + Printf.printf "=== FULL s2 ===\n%s\n\n" (String.escaped s2); 35 + Printf.printf "=== FULL s3 ===\n%s\n\n" (String.escaped s3); 32 36 33 37 if s2 = s3 then 34 38 Printf.printf "ROUNDTRIP OK\n"