From 6363198a0cc78a525c0ec0672f2030d3a3232adb Mon Sep 17 00:00:00 2001 From: James Bonfield Date: Thu, 16 Nov 2023 17:30:24 +0000 Subject: [PATCH] Improve the SAM/BAM/CRAM fuzzer to write BAM and CRAM too. TODO: add BCF as well. --- Makefile | 4 +++ test/fuzz/hts_open_fuzzer.c | 51 +++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 9a0c86c477..643f5fbbaf 100644 --- a/Makefile +++ b/Makefile @@ -623,6 +623,10 @@ check test: all $(HTSCODECS_TEST_TARGETS) test/hts_endian: test/hts_endian.o $(CC) $(LDFLAGS) -o $@ test/hts_endian.o $(LIBS) +# To build the fuzzer, try: +# make CC="clang16 -fsanitize=address,undefined,fuzzer" \ +# CFLAGS="-g -O3 -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \ +# test/fuzz/hts_open_fuzzer test/fuzz/hts_open_fuzzer: test/fuzz/hts_open_fuzzer.o libhts.a $(CC) $(LDFLAGS) -o $@ test/fuzz/hts_open_fuzzer.o libhts.a $(LIBS) -lpthread diff --git a/test/fuzz/hts_open_fuzzer.c b/test/fuzz/hts_open_fuzzer.c index 355f790a57..7bd34e6717 100644 --- a/test/fuzz/hts_open_fuzzer.c +++ b/test/fuzz/hts_open_fuzzer.c @@ -47,39 +47,74 @@ static void view_sam(htsFile *in) { if (!in) { return; } - samFile *out = sam_open("/dev/null", "w"); - if (!out) { + samFile *outS = sam_open("/dev/null", "w"); + samFile *outB = sam_open("/dev/null", "wb"); + samFile *outC = sam_open("/dev/null", "wC"); + if (!outS || !outB || !outC) { abort(); } + // Not critical if this doesn't work, but can test more if + // we're in the right location. + if (hts_set_fai_filename(outC, "../c2.fa") < 0) { + static int warned = 0; + if (!warned) { + warned = 1; + fprintf(stderr, "Warning couldn't find the c2.fa file\n"); + } + } sam_hdr_t *hdr = sam_hdr_read(in); if (hdr == NULL) { - hts_close_or_abort(out); + hts_close_or_abort(outS); + hts_close_or_abort(outB); + hts_close_or_abort(outC); return; } // This will force the header to be parsed. (void) sam_hdr_count_lines(hdr, "SQ"); - if (sam_hdr_write(out, hdr) != 0) { + if (sam_hdr_write(outS, hdr) != 0) { sam_hdr_destroy(hdr); - hts_close_or_abort(out); + hts_close_or_abort(outS); + hts_close_or_abort(outB); + hts_close_or_abort(outC); + return; + } + if (sam_hdr_write(outB, hdr) != 0) { + sam_hdr_destroy(hdr); + hts_close_or_abort(outS); + hts_close_or_abort(outB); + hts_close_or_abort(outC); + return; + } + if (sam_hdr_write(outC, hdr) != 0) { + sam_hdr_destroy(hdr); + hts_close_or_abort(outS); + hts_close_or_abort(outB); + hts_close_or_abort(outC); return; } bam1_t *b = bam_init1(); if (b == NULL) { sam_hdr_destroy(hdr); - hts_close_or_abort(out); + hts_close_or_abort(outS); + hts_close_or_abort(outB); + hts_close_or_abort(outC); return; } while (sam_read1(in, hdr, b) >= 0) { - if (sam_write1(out, hdr, b) < 0) { + if (sam_write1(outS, hdr, b) < 0 || + sam_write1(outB, hdr, b) < 0 || + sam_write1(outC, hdr, b) < 0) { break; } } bam_destroy1(b); sam_hdr_destroy(hdr); - hts_close_or_abort(out); + hts_close_or_abort(outS); + hts_close_or_abort(outB); + hts_close_or_abort(outC); } static void view_vcf(htsFile *in) {