Coverage Report

Created: 2025-07-23 06:50

/src/fontations/fuzz/fuzz_targets/fuzz_range_set.rs
Line
Count
Source
1
#![no_main]
2
//! Fuzzes the incremental_font_transfer patch_group.rs API
3
4
use std::ops::RangeInclusive;
5
6
use libfuzzer_sys::{arbitrary, fuzz_target};
7
use read_fonts::collections::{IntSet, RangeSet};
8
9
372k
#[derive(Debug, arbitrary::Arbitrary)]
Unexecuted instantiation: <fuzz_range_set::Operation as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <fuzz_range_set::Operation as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <fuzz_range_set::Operation as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <fuzz_range_set::Operation as arbitrary::Arbitrary>::try_size_hint::{closure#0}
<fuzz_range_set::Operation as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
9
86
#[derive(Debug, arbitrary::Arbitrary)]
<fuzz_range_set::Operation as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
9
372k
#[derive(Debug, arbitrary::Arbitrary)]
<fuzz_range_set::Operation as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
9
86
#[derive(Debug, arbitrary::Arbitrary)]
10
enum Operation {
11
    Insert(RangeInclusive<u16>),
12
    Extend(Vec<RangeInclusive<u16>>),
13
    Intersection,
14
    Iter,
15
}
16
17
373k
#[derive(Debug, arbitrary::Arbitrary)]
Unexecuted instantiation: <fuzz_range_set::SetIndex as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <fuzz_range_set::SetIndex as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <fuzz_range_set::SetIndex as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <fuzz_range_set::SetIndex as arbitrary::Arbitrary>::try_size_hint::{closure#0}
<fuzz_range_set::SetIndex as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
17
1.31k
#[derive(Debug, arbitrary::Arbitrary)]
<fuzz_range_set::SetIndex as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
17
372k
#[derive(Debug, arbitrary::Arbitrary)]
<fuzz_range_set::SetIndex as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
17
1.31k
#[derive(Debug, arbitrary::Arbitrary)]
18
enum SetIndex {
19
    One,
20
    Two,
21
}
22
23
#[derive(Default)]
24
struct State {
25
    range_set: RangeSet<u16>,
26
    int_set: IntSet<u16>,
27
}
28
29
const OP_COUNT_LIMIT: u64 = 1000;
30
31
22.1k
fn range_len(range: &RangeInclusive<u16>) -> u64 {
32
22.1k
    if range.end() > range.start() {
33
12.0k
        let count = *range.end() as u64 - *range.start() as u64;
34
12.0k
        count.saturating_mul(count.ilog2() as u64)
35
    } else {
36
10.0k
        0
37
    }
38
22.1k
}
39
40
fuzz_target!(|operations: Vec<(Operation, SetIndex)>| {
41
    let mut state1: State = Default::default();
42
    let mut state2: State = Default::default();
43
    let mut op_count = 0u64;
44
    for (op, index) in operations {
45
        let (state, state_other) = match index {
46
            SetIndex::One => (&mut state1, &mut state2),
47
            SetIndex::Two => (&mut state2, &mut state1),
48
        };
49
50
        match op {
51
            Operation::Insert(range) => {
52
                op_count = op_count.saturating_add(range_len(&range));
53
                if op_count > OP_COUNT_LIMIT {
54
                    return;
55
                }
56
57
                state.range_set.insert(range.clone());
58
                state.int_set.insert_range(range.clone());
59
            }
60
            Operation::Extend(ranges) => {
61
                for range in ranges.iter() {
62
                    op_count = op_count.saturating_add(range_len(range));
63
                    if op_count > OP_COUNT_LIMIT {
64
                        return;
65
                    }
66
                    state.int_set.insert_range(range.clone());
67
                }
68
                state.range_set.extend(ranges.into_iter());
69
            }
70
            Operation::Iter => {
71
                op_count = op_count.saturating_add(state.int_set.iter_ranges().count() as u64);
72
                if op_count > OP_COUNT_LIMIT {
73
                    return;
74
                }
75
76
                assert!(state.range_set.iter().eq(state.int_set.iter_ranges()));
77
            }
78
            Operation::Intersection => {
79
                op_count = op_count.saturating_add(state.int_set.len());
80
                op_count = op_count.saturating_add(state_other.int_set.len());
81
                if op_count > OP_COUNT_LIMIT {
82
                    return;
83
                }
84
85
                let mut tmp = state.int_set.clone();
86
                tmp.intersect(&state_other.int_set);
87
                assert!(state
88
                    .range_set
89
                    .intersection(&state_other.range_set)
90
                    .eq(tmp.iter_ranges()));
91
            }
92
        }
93
    }
94
});