Coverage Report

Created: 2025-11-09 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ttf-parser/fuzz/fuzz_targets/fuzz-cpal.rs
Line
Count
Source
1
// Copyright 2025 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#![no_main]
16
17
use libfuzzer_sys::fuzz_target;
18
use ttf_parser::{colr, GlyphId, cpal, RgbaColor};
19
20
fuzz_target!(|data: &[u8]| {
21
    if data.len() < 10 {
22
        return;
23
    }
24
25
    // Fuzz CPAL/COLR parse
26
    if let Some(cpal_table) = cpal::Table::parse(data) {
27
        if let Some(colr_table) = colr::Table::parse(cpal_table, data) {
28
            let mut painter = VecPainter(vec![]);
29
            let glyph_id = GlyphId(data[0] as u16);
30
            let _ = colr_table.paint(glyph_id, 0, &mut painter, &[], RgbaColor::new(0, 0, 0, 255));
31
        }
32
    }
33
});
34
35
// Custom VecPainter
36
struct VecPainter(Vec<Command>);
37
38
impl<'a> colr::Painter<'a> for VecPainter {
39
21.2M
    fn outline_glyph(&mut self, glyph_id: GlyphId) {
40
21.2M
        self.0.push(Command::OutlineGlyph(glyph_id));
41
21.2M
    }
42
43
1.87M
    fn paint(&mut self, paint: colr::Paint<'a>) {
44
1.87M
        let custom_paint = match paint {
45
3.92k
            colr::Paint::Solid(color) => CustomPaint::Solid(color),
46
1.35M
            colr::Paint::LinearGradient(lg) => CustomPaint::LinearGradient(
47
1.35M
                lg.x0, lg.y0, lg.x1, lg.y1, lg.x2, lg.y2, lg.extend,
48
1.35M
                lg.stops(0, &[]).map(|stop| CustomStop(stop.stop_offset, stop.color)).collect(),
49
            ),
50
485k
            colr::Paint::RadialGradient(rg) => CustomPaint::RadialGradient(
51
485k
                rg.x0, rg.y0, rg.r0, rg.r1, rg.x1, rg.y1, rg.extend,
52
485k
                rg.stops(0, &[]).map(|stop| CustomStop(stop.stop_offset, stop.color)).collect(),
53
            ),
54
30.3k
            colr::Paint::SweepGradient(sg) => CustomPaint::SweepGradient(
55
30.3k
                sg.center_x, sg.center_y, sg.start_angle, sg.end_angle, sg.extend,
56
676k
                sg.stops(0, &[]).map(|stop| CustomStop(stop.stop_offset, stop.color)).collect(),
57
            ),
58
        };
59
60
1.87M
        self.0.push(Command::Paint(custom_paint));
61
1.87M
    }
62
63
17.6M
    fn push_layer(&mut self, mode: colr::CompositeMode) {
64
17.6M
        self.0.push(Command::PushLayer(mode));
65
17.6M
    }
66
67
17.6M
    fn pop_layer(&mut self) {
68
17.6M
        self.0.push(Command::PopLayer);
69
17.6M
    }
70
71
5.23M
    fn push_transform(&mut self, transform: ttf_parser::Transform) {
72
5.23M
        self.0.push(Command::Transform(transform));
73
5.23M
    }
74
75
5.23M
    fn pop_transform(&mut self) {
76
5.23M
        self.0.push(Command::PopTransform);
77
5.23M
    }
78
79
21.2M
    fn push_clip(&mut self) {
80
21.2M
        self.0.push(Command::PushClip);
81
21.2M
    }
82
83
366k
    fn push_clip_box(&mut self, clipbox: colr::ClipBox) {
84
366k
        self.0.push(Command::PushClipBox(clipbox));
85
366k
    }
86
87
21.6M
    fn pop_clip(&mut self) {
88
21.6M
        self.0.push(Command::PopClip);  
89
21.6M
    }
90
}
91
92
#[derive(Clone, Debug, PartialEq)]
93
struct CustomStop(f32, RgbaColor);
94
95
#[derive(Clone, Debug, PartialEq)]
96
enum CustomPaint {
97
    Solid(RgbaColor),
98
    LinearGradient(f32, f32, f32, f32, f32, f32, colr::GradientExtend, Vec<CustomStop>),
99
    RadialGradient(f32, f32, f32, f32, f32, f32, colr::GradientExtend, Vec<CustomStop>),
100
    SweepGradient(f32, f32, f32, f32, colr::GradientExtend, Vec<CustomStop>),
101
}
102
103
#[derive(Clone, Debug, PartialEq)]
104
enum Command {
105
    OutlineGlyph(GlyphId),
106
    Paint(CustomPaint),
107
    PushLayer(colr::CompositeMode),
108
    PopLayer,
109
    Transform(ttf_parser::Transform),
110
    PopTransform,
111
    PushClip,
112
    PushClipBox(colr::ClipBox),
113
    PopClip,
114
}