Coverage Report

Created: 2023-01-17 06:24

/src/htslib/test/fuzz/hts_open_fuzzer.c
Line
Count
Source (jump to first uncovered line)
1
/*  test/fuzz/hts_open_fuzzer.c -- Fuzz driver for hts_open.
2
3
    Copyright (C) 2018 Google LLC.
4
    Copyright (C) 2019-2020 Genome Research Ltd.
5
6
    Author: Markus Kusano <kusano@google.com>
7
8
Permission is hereby granted, free of charge, to any person obtaining a copy
9
of this software and associated documentation files (the "Software"), to deal
10
in the Software without restriction, including without limitation the rights
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
copies of the Software, and to permit persons to whom the Software is
13
furnished to do so, subject to the following conditions:
14
15
The above copyright notice and this permission notice shall be included in
16
all copies or substantial portions of the Software.
17
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
DEALINGS IN THE SOFTWARE.  */
25
26
#include <config.h>
27
28
#include <stddef.h>
29
#include <stdint.h>
30
#include <stdio.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <unistd.h>
34
35
#include "../../htslib/hfile.h"
36
#include "../../htslib/hts.h"
37
#include "../../htslib/sam.h"
38
#include "../../htslib/vcf.h"
39
40
1.76k
static void hts_close_or_abort(htsFile* file) {
41
1.76k
    if (hts_close(file) != 0) {
42
0
        abort();
43
0
    }
44
1.76k
}
45
46
919
static void view_sam(htsFile *in) {
47
919
    if (!in) {
48
0
        return;
49
0
    }
50
919
    samFile *out = sam_open("/dev/null", "w");
51
919
    if (!out) {
52
0
        abort();
53
0
    }
54
919
    sam_hdr_t *hdr = sam_hdr_read(in);
55
919
    if (hdr == NULL) {
56
34
        hts_close_or_abort(out);
57
34
        return;
58
34
    }
59
60
    // This will force the header to be parsed.
61
885
    (void) sam_hdr_count_lines(hdr, "SQ");
62
63
885
    if (sam_hdr_write(out, hdr) != 0) {
64
0
        sam_hdr_destroy(hdr);
65
0
        hts_close_or_abort(out);
66
0
        return;
67
0
    }
68
885
    bam1_t *b = bam_init1();
69
885
    if (b == NULL) {
70
0
        sam_hdr_destroy(hdr);
71
0
        hts_close_or_abort(out);
72
0
        return;
73
0
    }
74
18.6k
    while (sam_read1(in, hdr, b) >= 0) {
75
17.7k
        if (sam_write1(out, hdr, b) < 0) {
76
17
            break;
77
17
        }
78
17.7k
    }
79
885
    bam_destroy1(b);
80
81
885
    sam_hdr_destroy(hdr);
82
885
    hts_close_or_abort(out);
83
885
}
84
85
847
static void view_vcf(htsFile *in) {
86
847
    if (!in) {
87
0
        return;
88
0
    }
89
847
    vcfFile *out = vcf_open("/dev/null", "w");
90
847
    if (!out) {
91
0
        abort();
92
0
    }
93
847
    bcf_hdr_t *hdr = bcf_hdr_read(in);
94
847
    if (hdr == NULL) {
95
120
        hts_close_or_abort(out);
96
120
        return;
97
120
    }
98
99
727
    if (bcf_hdr_write(out, hdr) != 0) {
100
0
        bcf_hdr_destroy(hdr);
101
0
        hts_close_or_abort(out);
102
0
    }
103
727
    bcf1_t *rec = bcf_init();
104
727
    if (rec == NULL) {
105
0
        bcf_hdr_destroy(hdr);
106
0
        hts_close_or_abort(out);
107
0
    }
108
37.9k
    while (bcf_read(in, hdr, rec) >= 0) {
109
37.2k
        if (bcf_write(out, hdr, rec) < 0) {
110
39
            break;
111
39
        }
112
37.2k
    }
113
727
    bcf_destroy(rec);
114
115
727
    bcf_hdr_destroy(hdr);
116
727
    hts_close_or_abort(out);
117
727
}
118
119
1.79k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
120
1.79k
    hFILE *memfile;
121
1.79k
    uint8_t *copy = malloc(size);
122
1.79k
    if (copy == NULL) {
123
0
        abort();
124
0
    }
125
1.79k
    memcpy(copy, data, size);
126
    // hopen does not take ownership of `copy`, but hts_hopen does.
127
1.79k
    memfile = hopen("mem:", "rb:", copy, size);
128
1.79k
    if (memfile == NULL) {
129
0
        free(copy);
130
0
        return 0;
131
0
    }
132
133
1.79k
    htsFile *ht_file = hts_hopen(memfile, "data", "rb");
134
1.79k
    if (ht_file == NULL) {
135
33
        if (hclose(memfile) != 0) {
136
0
            abort();
137
0
        }
138
33
        return 0;
139
33
    }
140
1.76k
    switch (ht_file->format.category) {
141
919
        case sequence_data:
142
919
            view_sam(ht_file);
143
919
            break;
144
847
        case variant_data:
145
847
            view_vcf(ht_file);
146
847
            break;
147
0
        default:
148
0
            break;
149
1.76k
    }
150
1.76k
    hts_close(ht_file);
151
1.76k
    return 0;
152
1.76k
}