Coverage Report

Created: 2025-06-16 06:13

/src/ttf-parser/fuzz/fuzz_targets/fuzz-table.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 std::num::NonZeroU16;
19
use ttf_parser::{GlyphId};
20
use ttf_parser::{ankr, avar, cmap, feat, fvar, gdef, gvar, hmtx, hvar, kern, kerx};
21
use ttf_parser::{loca, math, maxp, morx, mvar, name, sbix, stat, svg, trak, vhea, vorg, vvar};
22
23
fuzz_target!(|fuzz_data: &[u8]| {
24
    // Skip this iteration if data is empty
25
    if fuzz_data.is_empty() {
26
        return;
27
    }
28
29
    // Randomly choose a fuzzing target function
30
    let choice = fuzz_data[0] % 26;
31
    let data = &fuzz_data[1..];
32
    match choice {
33
        0 => {
34
            // Fuzz cmap module
35
            if let Some(subtable0) = cmap::Subtable0::parse(data) {
36
                subtable0.glyph_index(0x41);
37
                subtable0.glyph_index(0x42);
38
                let mut codepoints = vec![];
39
1.77k
                subtable0.codepoints(|c| codepoints.push(c));
40
            }
41
            if let Some(subtable4) = cmap::Subtable4::parse(data) {
42
                subtable4.glyph_index(0x41);
43
                subtable4.glyph_index(0x42);
44
                let mut codepoints = vec![];
45
23.9M
                subtable4.codepoints(|c| codepoints.push(c));
46
            }
47
        }
48
        1 => {
49
            // Fuzz ankr module
50
            if let Some(table) = ankr::Table::parse(NonZeroU16::new(1).unwrap(), data) {
51
                if let Some(points) = table.points(GlyphId(0)) {
52
                    for point in points {
53
                        let _ = point.x;
54
                        let _ = point.y;
55
                    }
56
                }
57
            }
58
        }
59
        2 => {
60
            // Fuzz feat module
61
            if let Some(feat_table) = feat::Table::parse(data) {
62
                for feature in feat_table.names {
63
                    let _ = feature.exclusive;
64
                    let _ = feature.default_setting_index;
65
                }
66
            }
67
        }
68
        3 => {
69
            // Fuzz hmtx module
70
            if let Some(hmtx_table) = hmtx::Table::parse(1, NonZeroU16::new(1).unwrap(), data) {
71
                let _ = hmtx_table.number_of_metrics;
72
            }
73
        }
74
        4 => {
75
            // Fuzz maxp module
76
            if let Some(maxp_table) = maxp::Table::parse(data) {
77
                let _ = maxp_table.number_of_glyphs;
78
            }
79
        }
80
        5 => {
81
            // Fuzz sbix module
82
            if let Some(table) = sbix::Table::parse(NonZeroU16::new(1).unwrap(), data) {
83
                for strike in table.strikes {
84
                    for i in 0..strike.len() {
85
                        if let Some(glyph_data) = strike.get(GlyphId(i as u16)) {
86
                            let _ = glyph_data.x;
87
                            let _ = glyph_data.y;
88
                            let _ = glyph_data.width;
89
                            let _ = glyph_data.height;
90
                            let _ = glyph_data.pixels_per_em;
91
                            let _ = glyph_data.format;
92
                        }
93
                    }
94
                }
95
            }
96
        }
97
        6 => {
98
            // Fuzz trak module
99
            if let Some(trak_table) = trak::Table::parse(data) {
100
                for track in trak_table.horizontal.tracks {
101
                    let _ = track.value;
102
                    for value in track.values {
103
                        let _ = value;
104
                    }
105
                }
106
            }
107
        }
108
        7 => {
109
            // Fuzz kern module
110
            if let Some(kern_table) = kern::Table::parse(data) {
111
                for subtable in kern_table.subtables.into_iter() {
112
                    if let Some(kern_val) = subtable.glyphs_kerning(GlyphId(1), GlyphId(2)) {
113
                        let _ = kern_val;
114
                    }
115
                }
116
            }
117
        }
118
        8 => {
119
            // Fuzz kerx module
120
            if let Some(kerx_table) = kerx::Table::parse(NonZeroU16::new(1).unwrap(), data) {
121
                for subtable in kerx_table.subtables.into_iter() {
122
                    if let Some(kerx_val) = subtable.glyphs_kerning(GlyphId(1), GlyphId(2)) {
123
                        let _ = kerx_val;
124
                    }
125
                }
126
            }
127
        }
128
        9 => {
129
            // Fuzz loca module
130
            if let Some(loca_table) = loca::Table::parse(NonZeroU16::new(1).unwrap(), ttf_parser::head::IndexToLocationFormat::Short, data) {
131
                if let Some(range) = loca_table.glyph_range(GlyphId(1)) {
132
                    let _ = range.start;
133
                    let _ = range.end;
134
                }
135
            }
136
        }
137
        10 => {
138
            // Fuzz math constants module
139
            if let Some(math_table) = math::Table::parse(data) {
140
                if let Some(constants) = math_table.constants {
141
                    let _ = constants.axis_height();
142
                    let _ = constants.script_percent_scale_down();
143
                }
144
            }
145
        }
146
        11 => {
147
            // Fuzz math kern info module
148
            if let Some(math_table) = math::Table::parse(data) {
149
                if let Some(glyph_info) = math_table.glyph_info {
150
                    if let Some(kern_infos) = glyph_info.kern_infos {
151
                        if let Some(kern_info) = kern_infos.get(GlyphId(1)) {
152
                            let _ = kern_info.top_right;
153
                            let _ = kern_info.bottom_left;
154
                        }
155
                    }
156
                }
157
            }
158
        }
159
        12 => {
160
            // Fuzz gvar module
161
            let _ = gvar::Table::parse(data);
162
        }
163
        13 => {
164
            // Fuzz hvar module
165
            let _ = hvar::Table::parse(data);
166
        }
167
        14 => {
168
            // Fuzz avar module
169
            let _ = avar::Table::parse(data);
170
        }
171
        15 => {
172
            // Fuzz fvar module
173
            if let Some(fvar_table) = fvar::Table::parse(data) {
174
                for axis in fvar_table.axes {
175
                    let _ = axis.tag;
176
                }
177
            }
178
        }
179
        16 => {
180
            // Fuzz gdef module
181
            if let Some(gdef_table) = gdef::Table::parse(data) {
182
                let _ = gdef_table.glyph_class(GlyphId(1));
183
            }
184
        }
185
        17 => {
186
            // Fuzz morx module
187
            if let Some(morx_table) = morx::Table::parse(NonZeroU16::new(1).unwrap(), data) {
188
                for chain in morx_table.chains {
189
                    let _ = chain.default_flags;
190
                    for feature in chain.features {
191
                        let _ = feature.kind;
192
                    }
193
                }
194
            }
195
        }
196
        18 => {
197
            // Fuzz mvar module
198
            if let Some(mvar_table) = mvar::Table::parse(data) {
199
                let _ = mvar_table.metric_offset(ttf_parser::Tag::from_bytes(b"wdth"), &[]);
200
            }
201
        }
202
        19 => {
203
            // Fuzz name module
204
            if let Some(name_table) = name::Table::parse(data) {
205
                for index in 0..name_table.names.len() {
206
                    if let Some(name) = name_table.names.get(index) {
207
                        let _ = name.to_string();
208
                    }
209
                }
210
            }
211
        }
212
        20 => {
213
            // Fuzz stat module
214
            if let Some(stat_table) = stat::Table::parse(data) {
215
                for subtable in stat_table.subtables() {
216
                    let _ = subtable.name_id();
217
                }
218
            }
219
        }
220
        21 => {
221
            // Fuzz svg module
222
            if let Some(svg_table) = svg::Table::parse(data) {
223
                for index in 0..svg_table.documents.len() {
224
                    if let Some(svg_doc) = svg_table.documents.get(index) {
225
                        let _ = svg_doc.glyphs_range();
226
                    }
227
                }
228
            }
229
        }
230
        22 => {
231
            // Fuzz trak module
232
            if let Some(trak_table) = trak::Table::parse(data) {
233
                for track in trak_table.horizontal.tracks {
234
                    let _ = track.value;
235
                    for value in track.values {
236
                        let _ = value;
237
                    }
238
                }
239
            }
240
        }
241
        23 => {
242
            // Fuzz vhea module
243
            if let Some(vhea_table) = vhea::Table::parse(data) {
244
                let _ = vhea_table.ascender;
245
                let _ = vhea_table.descender;
246
                let _ = vhea_table.line_gap;
247
                let _ = vhea_table.number_of_metrics;
248
            }
249
        }
250
        24 => {
251
            // Fuzz vorg module
252
            if let Some(vorg_table) = vorg::Table::parse(data) {
253
                let _ = vorg_table.default_y;
254
                for metrics in vorg_table.metrics {
255
                    let _ = metrics.glyph_id;
256
                    let _ = metrics.y;
257
                }
258
            }
259
        }
260
        25 => {
261
            // Fuzz vvar module
262
            if let Some(vvar_table) = vvar::Table::parse(data) {
263
                let _ = vvar_table.advance_offset(GlyphId(1), &[]);
264
                let _ = vvar_table.top_side_bearing_offset(GlyphId(1), &[]);
265
                let _ = vvar_table.bottom_side_bearing_offset(GlyphId(1), &[]);
266
                let _ = vvar_table.vertical_origin_offset(GlyphId(1), &[]);
267
            }
268
        }
269
        _ => {}
270
    }
271
});