Coverage Report

Created: 2026-05-16 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpv/fuzzers/fuzzer_load.c
Line
Count
Source
1
/*
2
 * This file is part of mpv.
3
 *
4
 * mpv is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * mpv is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
#include <stdio.h>
19
#include <stdlib.h>
20
#include <string.h>
21
22
#include <fcntl.h>
23
#include <sys/mman.h>
24
#include <unistd.h>
25
26
#include "common.h"
27
28
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
29
20.2k
{
30
20.2k
    if (size > MAX_FUZZ_SIZE)
31
6
        return 0;
32
33
20.2k
#ifdef MPV_LOAD_CONFIG_FILE
34
    // config file size limit, see m_config_parse_config_file()
35
20.2k
    if (size > 1000000000)
36
0
        return 0;
37
20.2k
#endif
38
39
#ifdef MPV_LOAD_INPUT_CONF
40
    // input config file size limit, see parse_config_file() in input.c
41
    if (size > 1000000)
42
        return 0;
43
#endif
44
45
    // fmemopen doesn't have associated file descriptor, so we do copy.
46
20.2k
    int fd = memfd_create("fuzz_mpv_load", MFD_CLOEXEC | MFD_ALLOW_SEALING);
47
20.2k
    if (fd == -1)
48
0
        exit(1);
49
20.2k
    if (fd != 42 && (dup3(fd, 42, O_CLOEXEC) != 42 || close(fd)))
50
0
        exit(1);
51
20.2k
    fd = 42;
52
20.2k
    ssize_t written = 0;
53
40.4k
    while (written < size) {
54
20.2k
        ssize_t result = write(fd, data + written, size - written);
55
20.2k
        if (result == -1)
56
0
            exit(1);
57
20.2k
        written += result;
58
20.2k
    }
59
20.2k
    if (fcntl(fd, F_ADD_SEALS, F_SEAL_WRITE | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL) != 0)
60
0
        exit(1);
61
20.2k
    if (lseek(fd, 0, SEEK_SET) != 0)
62
0
        exit(1);
63
20.2k
    char filename[5 + 10 + 1];
64
20.2k
    if (sprintf(filename, "fd://%d", fd) <= 5)
65
0
        exit(1);
66
67
20.2k
    set_fontconfig_sysroot();
68
69
20.2k
    mpv_handle *ctx = mpv_create();
70
20.2k
    if (!ctx)
71
0
        exit(1);
72
73
20.2k
    check_error(mpv_set_option_string(ctx, "vo", "null"));
74
20.2k
    check_error(mpv_set_option_string(ctx, "ao", "null"));
75
20.2k
    check_error(mpv_set_option_string(ctx, "ao-null-untimed", "yes"));
76
20.2k
    check_error(mpv_set_option_string(ctx, "untimed", "yes"));
77
20.2k
    check_error(mpv_set_option_string(ctx, "video-osd", "no"));
78
20.2k
    check_error(mpv_set_option_string(ctx, "msg-level", "all=trace"));
79
20.2k
    check_error(mpv_set_option_string(ctx, "network-timeout", "1"));
80
#ifdef MPV_DEMUXER
81
    check_error(mpv_set_option_string(ctx, "demuxer", MPV_DEMUXER));
82
#endif
83
84
20.2k
    check_error(mpv_initialize(ctx));
85
86
20.2k
    const char *cmd[] = {"load" MPV_LOAD, filename, NULL};
87
20.2k
    check_error(mpv_command(ctx, cmd));
88
89
#ifdef MPV_LOADFILE
90
    player_loop(ctx);
91
#endif
92
93
20.2k
    mpv_terminate_destroy(ctx);
94
95
20.2k
    if (close(fd))
96
0
        exit(1);
97
98
20.2k
    return 0;
99
20.2k
}