Skip to content

Commit 1ad97ed

Browse files
Add fuzz targets for custom Block, Mark, and Content serde (#90)
The hand-written Serialize/Deserialize impls from PR #87 are the most complex recent addition. These fuzz targets exercise all type dispatch paths with arbitrary input to catch panics or unexpected behavior in the custom deserialization logic.
1 parent b24ce7f commit 1ad97ed

4 files changed

Lines changed: 71 additions & 0 deletions

File tree

fuzz/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,24 @@ path = "fuzz_targets/manifest_parser.rs"
3636
test = false
3737
doc = false
3838
bench = false
39+
40+
[[bin]]
41+
name = "block_parser"
42+
path = "fuzz_targets/block_parser.rs"
43+
test = false
44+
doc = false
45+
bench = false
46+
47+
[[bin]]
48+
name = "mark_parser"
49+
path = "fuzz_targets/mark_parser.rs"
50+
test = false
51+
doc = false
52+
bench = false
53+
54+
[[bin]]
55+
name = "content_parser"
56+
path = "fuzz_targets/content_parser.rs"
57+
test = false
58+
doc = false
59+
bench = false

fuzz/fuzz_targets/block_parser.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//! Fuzz target for Block deserialization.
2+
//!
3+
//! This target tests the custom `Deserialize` impl for `Block` which
4+
//! dispatches on the `"type"` field to construct the correct variant.
5+
//! Exercises all 20+ block type code paths with arbitrary JSON input.
6+
7+
#![no_main]
8+
9+
use libfuzzer_sys::fuzz_target;
10+
11+
fuzz_target!(|data: &[u8]| {
12+
// Try parsing as a single Block
13+
let _ = serde_json::from_slice::<cdx_core::content::Block>(data);
14+
15+
// Also try parsing as a Vec<Block> (nested children)
16+
let _ = serde_json::from_slice::<Vec<cdx_core::content::Block>>(data);
17+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//! Fuzz target for Content deserialization.
2+
//!
3+
//! This target tests parsing of the full `Content` structure which
4+
//! contains a version field and a blocks array. Exercises the complete
5+
//! content deserialization pipeline including nested blocks and text
6+
//! nodes with marks.
7+
8+
#![no_main]
9+
10+
use libfuzzer_sys::fuzz_target;
11+
12+
fuzz_target!(|data: &[u8]| {
13+
// Try parsing as a full Content structure
14+
let _ = serde_json::from_slice::<cdx_core::content::Content>(data);
15+
});

fuzz/fuzz_targets/mark_parser.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! Fuzz target for Mark deserialization.
2+
//!
3+
//! This target tests the custom `Deserialize` impl for `Mark` which
4+
//! handles both simple string marks (e.g., `"bold"`) and complex object
5+
//! marks (e.g., `{"type": "link", "href": "..."}`). Exercises all 15+
6+
//! mark type code paths with arbitrary input.
7+
8+
#![no_main]
9+
10+
use libfuzzer_sys::fuzz_target;
11+
12+
fuzz_target!(|data: &[u8]| {
13+
// Try parsing as a single Mark
14+
let _ = serde_json::from_slice::<cdx_core::content::Mark>(data);
15+
16+
// Also try parsing as a Vec<Mark> (text node marks array)
17+
let _ = serde_json::from_slice::<Vec<cdx_core::content::Mark>>(data);
18+
});

0 commit comments

Comments
 (0)