Coverage Report

Created: 2026-10-28 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/fuzz/fuzz_targets/helpers.rs
Line
Count
Source
1
//! Common helpers
2
3
use read_fonts::{FileRef, ReadError};
4
use skrifa::{
5
    instance::{Location, Size},
6
    FontRef, MetadataProvider,
7
};
8
9
// We use allow dead here because the many-binary fuzzer rigging really likes to complain things are never used
10
11
#[allow(dead_code)]
12
const AXIS_LIMIT: usize = 5; // 3 options per axis * up to 5 axes
13
14
#[allow(dead_code)]
15
48
pub fn fuzz_sizes() -> Vec<Size> {
16
48
    vec![Size::unscaled(), Size::new(64.0), Size::new(512.0)]
17
48
}
Unexecuted instantiation: fuzz_basic_metadata::helpers::fuzz_sizes
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::fuzz_sizes
Unexecuted instantiation: fuzz_skrifa_outline::helpers::fuzz_sizes
Unexecuted instantiation: fuzz_name::helpers::fuzz_sizes
fuzz_skrifa_color::helpers::fuzz_sizes
Line
Count
Source
15
48
pub fn fuzz_sizes() -> Vec<Size> {
16
48
    vec![Size::unscaled(), Size::new(64.0), Size::new(512.0)]
17
48
}
18
19
#[allow(dead_code)]
20
144
pub fn fuzz_locations(font: &FontRef) -> Vec<Location> {
21
144
    let axes = font.axes();
22
144
    let mut locations = vec![Vec::new()];
23
24
    // Cross unique min,default,max on every axis
25
144
    for axis in axes.iter().take(AXIS_LIMIT) {
26
39
        let mut values = vec![axis.default_value()];
27
39
        if axis.min_value() != axis.default_value() {
28
33
            values.push(axis.min_value());
29
33
        }
30
39
        if axis.max_value() != axis.default_value() {
31
33
            values.push(axis.max_value());
32
33
        }
33
39
        locations = locations
34
39
            .into_iter()
35
573
            .flat_map(|l| {
36
1.39k
                values.iter().map(move |v| {
37
1.39k
                    let mut l = l.clone();
38
1.39k
                    l.push(*v);
39
1.39k
                    l
40
1.39k
                })
Unexecuted instantiation: fuzz_basic_metadata::helpers::fuzz_locations::{closure#0}::{closure#0}
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::fuzz_locations::{closure#0}::{closure#0}
Unexecuted instantiation: fuzz_skrifa_outline::helpers::fuzz_locations::{closure#0}::{closure#0}
Unexecuted instantiation: fuzz_name::helpers::fuzz_locations::{closure#0}::{closure#0}
fuzz_skrifa_color::helpers::fuzz_locations::{closure#0}::{closure#0}
Line
Count
Source
36
1.39k
                values.iter().map(move |v| {
37
1.39k
                    let mut l = l.clone();
38
1.39k
                    l.push(*v);
39
1.39k
                    l
40
1.39k
                })
41
573
            })
Unexecuted instantiation: fuzz_basic_metadata::helpers::fuzz_locations::{closure#0}
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::fuzz_locations::{closure#0}
Unexecuted instantiation: fuzz_skrifa_outline::helpers::fuzz_locations::{closure#0}
Unexecuted instantiation: fuzz_name::helpers::fuzz_locations::{closure#0}
fuzz_skrifa_color::helpers::fuzz_locations::{closure#0}
Line
Count
Source
35
573
            .flat_map(|l| {
36
573
                values.iter().map(move |v| {
37
                    let mut l = l.clone();
38
                    l.push(*v);
39
                    l
40
                })
41
573
            })
42
39
            .collect();
43
    }
44
45
144
    locations
46
144
        .iter()
47
966
        .map(|positions| create_location(font, positions))
Unexecuted instantiation: fuzz_basic_metadata::helpers::fuzz_locations::{closure#1}
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::fuzz_locations::{closure#1}
Unexecuted instantiation: fuzz_skrifa_outline::helpers::fuzz_locations::{closure#1}
Unexecuted instantiation: fuzz_name::helpers::fuzz_locations::{closure#1}
fuzz_skrifa_color::helpers::fuzz_locations::{closure#1}
Line
Count
Source
47
966
        .map(|positions| create_location(font, positions))
48
144
        .collect()
49
144
}
Unexecuted instantiation: fuzz_basic_metadata::helpers::fuzz_locations
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::fuzz_locations
Unexecuted instantiation: fuzz_skrifa_outline::helpers::fuzz_locations
Unexecuted instantiation: fuzz_name::helpers::fuzz_locations
fuzz_skrifa_color::helpers::fuzz_locations
Line
Count
Source
20
144
pub fn fuzz_locations(font: &FontRef) -> Vec<Location> {
21
144
    let axes = font.axes();
22
144
    let mut locations = vec![Vec::new()];
23
24
    // Cross unique min,default,max on every axis
25
144
    for axis in axes.iter().take(AXIS_LIMIT) {
26
39
        let mut values = vec![axis.default_value()];
27
39
        if axis.min_value() != axis.default_value() {
28
33
            values.push(axis.min_value());
29
33
        }
30
39
        if axis.max_value() != axis.default_value() {
31
33
            values.push(axis.max_value());
32
33
        }
33
39
        locations = locations
34
39
            .into_iter()
35
39
            .flat_map(|l| {
36
                values.iter().map(move |v| {
37
                    let mut l = l.clone();
38
                    l.push(*v);
39
                    l
40
                })
41
            })
42
39
            .collect();
43
    }
44
45
144
    locations
46
144
        .iter()
47
144
        .map(|positions| create_location(font, positions))
48
144
        .collect()
49
144
}
50
51
966
fn create_location(font: &FontRef, axis_positions: &[f32]) -> Location {
52
966
    let raw_location = font
53
966
        .axes()
54
966
        .iter()
55
966
        .zip(axis_positions)
56
4.07k
        .map(|(axis, pos)| (axis.tag(), *pos))
Unexecuted instantiation: fuzz_basic_metadata::helpers::create_location::{closure#0}
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::create_location::{closure#0}
Unexecuted instantiation: fuzz_skrifa_outline::helpers::create_location::{closure#0}
Unexecuted instantiation: fuzz_name::helpers::create_location::{closure#0}
fuzz_skrifa_color::helpers::create_location::{closure#0}
Line
Count
Source
56
4.07k
        .map(|(axis, pos)| (axis.tag(), *pos))
57
966
        .collect::<Vec<_>>();
58
966
    font.axes().location(raw_location)
59
966
}
Unexecuted instantiation: fuzz_basic_metadata::helpers::create_location
Unexecuted instantiation: fuzz_skrifa_charmap::helpers::create_location
Unexecuted instantiation: fuzz_skrifa_outline::helpers::create_location
Unexecuted instantiation: fuzz_name::helpers::create_location
fuzz_skrifa_color::helpers::create_location
Line
Count
Source
51
966
fn create_location(font: &FontRef, axis_positions: &[f32]) -> Location {
52
966
    let raw_location = font
53
966
        .axes()
54
966
        .iter()
55
966
        .zip(axis_positions)
56
966
        .map(|(axis, pos)| (axis.tag(), *pos))
57
966
        .collect::<Vec<_>>();
58
966
    font.axes().location(raw_location)
59
966
}
60
61
/// Makes fuzzing agnostic of collection and non-collection inputs
62
///
63
/// Picks a single font if data is a collection.
64
6.38k
pub(crate) fn select_font(data: &[u8]) -> Result<FontRef<'_>, ReadError> {
65
    // Take the last byte as the collection index to let the fuzzer guide
66
6.38k
    let i = data.last().copied().unwrap_or_default();
67
6.38k
    match FileRef::new(data)? {
68
1.05k
        FileRef::Collection(cr) => {
69
1.05k
            let _ = cr.len();
70
1.05k
            let _ = cr.is_empty();
71
1.05k
            let _ = cr.iter().count();
72
1.05k
            cr.get(i.into())
73
        }
74
4.20k
        FileRef::Font(f) => Ok(f),
75
    }
76
6.38k
}
fuzz_basic_metadata::helpers::select_font
Line
Count
Source
64
1.36k
pub(crate) fn select_font(data: &[u8]) -> Result<FontRef<'_>, ReadError> {
65
    // Take the last byte as the collection index to let the fuzzer guide
66
1.36k
    let i = data.last().copied().unwrap_or_default();
67
1.36k
    match FileRef::new(data)? {
68
347
        FileRef::Collection(cr) => {
69
347
            let _ = cr.len();
70
347
            let _ = cr.is_empty();
71
347
            let _ = cr.iter().count();
72
347
            cr.get(i.into())
73
        }
74
675
        FileRef::Font(f) => Ok(f),
75
    }
76
1.36k
}
fuzz_skrifa_charmap::helpers::select_font
Line
Count
Source
64
3.41k
pub(crate) fn select_font(data: &[u8]) -> Result<FontRef<'_>, ReadError> {
65
    // Take the last byte as the collection index to let the fuzzer guide
66
3.41k
    let i = data.last().copied().unwrap_or_default();
67
3.41k
    match FileRef::new(data)? {
68
322
        FileRef::Collection(cr) => {
69
322
            let _ = cr.len();
70
322
            let _ = cr.is_empty();
71
322
            let _ = cr.iter().count();
72
322
            cr.get(i.into())
73
        }
74
2.70k
        FileRef::Font(f) => Ok(f),
75
    }
76
3.41k
}
Unexecuted instantiation: fuzz_skrifa_outline::helpers::select_font
fuzz_name::helpers::select_font
Line
Count
Source
64
1.53k
pub(crate) fn select_font(data: &[u8]) -> Result<FontRef<'_>, ReadError> {
65
    // Take the last byte as the collection index to let the fuzzer guide
66
1.53k
    let i = data.last().copied().unwrap_or_default();
67
1.53k
    match FileRef::new(data)? {
68
372
        FileRef::Collection(cr) => {
69
372
            let _ = cr.len();
70
372
            let _ = cr.is_empty();
71
372
            let _ = cr.iter().count();
72
372
            cr.get(i.into())
73
        }
74
780
        FileRef::Font(f) => Ok(f),
75
    }
76
1.53k
}
fuzz_skrifa_color::helpers::select_font
Line
Count
Source
64
60
pub(crate) fn select_font(data: &[u8]) -> Result<FontRef<'_>, ReadError> {
65
    // Take the last byte as the collection index to let the fuzzer guide
66
60
    let i = data.last().copied().unwrap_or_default();
67
60
    match FileRef::new(data)? {
68
9
        FileRef::Collection(cr) => {
69
9
            let _ = cr.len();
70
9
            let _ = cr.is_empty();
71
9
            let _ = cr.iter().count();
72
9
            cr.get(i.into())
73
        }
74
48
        FileRef::Font(f) => Ok(f),
75
    }
76
60
}