Coverage Report

Created: 2025-06-16 06:50

/src/pulldown-cmark/fuzz/fuzz_targets/commonmark_js.rs
Line
Count
Source
1
#![no_main]
2
3
//! Differential fuzzing of pulldown-cmark and commonmark.js.
4
//!
5
//! This fuzzer sends the same input to both Markdown parsers and
6
//! compares the output. The output from commonmark.js is turned into
7
//! `pulldown_cmark::Event` values for this purpose.
8
//!
9
//! Run the fuzzer like this to only test ASCII input (which is
10
//! usually enough to find parsing differences):
11
//!
12
//!     cargo fuzz run commonmark_js -- -only_ascii=1
13
14
use libfuzzer_sys::fuzz_target;
15
use pretty_assertions::assert_eq;
16
use pulldown_cmark_fuzz::{commonmark_js, normalize, print_events, pulldown_cmark, xml_to_events};
17
18
fuzz_target!(|text: String| {
19
    // There are some differences in handling of non-UTF-8 input.
20
224M
    if text.bytes().any(|b| b.is_ascii_control() && b != b'\n') {
21
        return;
22
    }
23
24
    // There are some trivial differences due to trailing whitespace.
25
    let text = text
26
        .lines()
27
13.1M
        .map(|line| line.trim_end())
28
        .collect::<Vec<_>>()
29
        .join("\n");
30
31
    let pulldown_cmark_events = normalize(pulldown_cmark(&text));
32
    let commonmark_js_xml = &commonmark_js(&text).unwrap();
33
34
    let raw_events = match xml_to_events(commonmark_js_xml) {
35
        Ok(raw_events) => raw_events,
36
        Err(err) => {
37
            print_events(&text, &pulldown_cmark_events);
38
            eprintln!("XML from commonmark.js:\n{commonmark_js_xml}");
39
            panic!("Could not parse XML: {}", err);
40
        }
41
    };
42
43
    let commonmark_js_events = normalize(raw_events);
44
    if pulldown_cmark_events != commonmark_js_events {
45
        eprintln!("Events from pulldown-cmark:\n\n```rust");
46
        print_events(&text, &pulldown_cmark_events);
47
        eprintln!("```");
48
        eprintln!();
49
50
        eprintln!("Events from commonmark.js:\n\n```rust");
51
        print_events(&text, &commonmark_js_events);
52
        eprintln!("```");
53
        eprintln!();
54
55
        let dingus_url = format!(
56
            "https://spec.commonmark.org/dingus/?text={}",
57
            urlencoding::encode(&text)
58
        );
59
        eprintln!("XML from [commonmark.js]({dingus_url}):\n\n```xml\n{commonmark_js_xml}```");
60
        eprintln!();
61
62
        assert_eq!(pulldown_cmark_events, commonmark_js_events);
63
    }
64
});