Coverage Report

Created: 2026-09-28 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vte/utf8parse/fuzz/fuzz_targets/parse.rs
Line
Count
Source
1
// Copyright 2024 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 utf8parse::{Parser, Receiver};
19
20
// Create dummy receiver for fuzzing
21
struct FuzzReceiver;
22
impl Receiver for FuzzReceiver {
23
11.0M
    fn codepoint(&mut self, _c: char) {
24
        // Do nothing
25
11.0M
    }
26
27
403k
    fn invalid_sequence(&mut self) {
28
        // Do nothing
29
403k
    }
30
}
31
32
fuzz_target!(|data: &[u8]| {
33
    if data.is_empty() {
34
        // Skip this iteration if there is no data
35
        return;
36
    }
37
38
    let mut parser = Parser::new();
39
    let mut receiver = FuzzReceiver;
40
41
    // Process parsing
42
5.09M
    fn process_byte_sequence(parser: &mut Parser, receiver: &mut FuzzReceiver, bytes: &[u8]) {
43
16.6M
        for &byte in bytes {
44
11.5M
            parser.advance(receiver, byte);
45
11.5M
        }
46
5.09M
    }
47
48
    let mut remaining_data = data;
49
50
    // Randomly create fuzz data with different constraint for fuzzing
51
    match remaining_data.get(0) {
52
        Some(&choice) => match choice % 3 {
53
            0 => {
54
                // Half and half
55
                let half = remaining_data.len() / 2;
56
                let (first_half, second_half) = remaining_data.split_at(half);
57
                process_byte_sequence(&mut parser, &mut receiver, first_half);
58
                process_byte_sequence(&mut parser, &mut receiver, second_half);
59
            }
60
            1 => {
61
                // Split data into uneven portion
62
                let chunk_size = (remaining_data[0] % 8) as usize + 1;
63
                let (chunk, rest) = remaining_data.split_at(remaining_data.len().min(chunk_size));
64
                process_byte_sequence(&mut parser, &mut receiver, chunk);
65
                remaining_data = rest;
66
67
                while !remaining_data.is_empty() {
68
                    let chunk_size = (remaining_data[0] % 6) as usize + 1;
69
                    let (chunk, rest) = remaining_data.split_at(remaining_data.len().min(chunk_size));
70
                    process_byte_sequence(&mut parser, &mut receiver, chunk);
71
                    remaining_data = rest;
72
                }
73
            }
74
            2 => {
75
                // Malformed input
76
                let incomplete_seq = vec![0xF0];
77
                process_byte_sequence(&mut parser, &mut receiver, &incomplete_seq);
78
79
                let chunk_size = (remaining_data[0] % 5) as usize + 1;
80
                let (chunk, _) = remaining_data.split_at(remaining_data.len().min(chunk_size));
81
                process_byte_sequence(&mut parser, &mut receiver, chunk);
82
            }
83
            _ => {
84
                // Should not reach here, fail safe
85
            }
86
        },
87
        None => return,
88
    }
89
});