1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg 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 * FFmpeg 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 GNU 12 * 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 FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include "config.h" 20#include "libavutil/imgutils.h" 21#include "libavutil/opt.h" 22 23#include "libavcodec/avcodec.h" 24#include "libavcodec/bsf.h" 25#include "libavcodec/bsf_internal.h" 26#include "libavcodec/bytestream.h" 27#include "libavcodec/internal.h" 28 29int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); 30 31static void error(const char *err) 32{ 33 fprintf(stderr, "%s", err); 34 exit(1); 35} 36 37static const AVBitStreamFilter *f = NULL; 38 39static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL; 40 41int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 42 const uint64_t fuzz_tag = FUZZ_TAG; 43 const uint8_t *last = data; 44 const uint8_t *end = data + size; 45 AVBSFContext *bsf = NULL; 46 AVPacket *pkt; 47 uint64_t keyframes = 0; 48 uint64_t flushpattern = -1; 49 int res; 50 51 if (!f) { 52#ifdef FFMPEG_BSF 53#define BSF_SYMBOL0(BSF) ff_##BSF##_bsf 54#define BSF_SYMBOL(BSF) BSF_SYMBOL0(BSF) 55 extern const AVBitStreamFilter BSF_SYMBOL(FFMPEG_BSF); 56 f = &BSF_SYMBOL(FFMPEG_BSF); 57#endif 58 av_log_set_level(AV_LOG_PANIC); 59 } 60 61 res = f ? av_bsf_alloc(f, &bsf) : av_bsf_get_null_filter(&bsf); 62 if (res < 0) 63 error("Failed memory allocation"); 64 f = bsf->filter; 65 66 if (size > 1024) { 67 GetByteContext gbc; 68 int extradata_size; 69 int flags; 70 size -= 1024; 71 bytestream2_init(&gbc, data + size, 1024); 72 bsf->par_in->width = bytestream2_get_le32(&gbc); 73 bsf->par_in->height = bytestream2_get_le32(&gbc); 74 bsf->par_in->bit_rate = bytestream2_get_le64(&gbc); 75 bsf->par_in->bits_per_coded_sample = bytestream2_get_le32(&gbc); 76 77 if (f->codec_ids) { 78 int i, id; 79 for (i = 0; f->codec_ids[i] != AV_CODEC_ID_NONE; i++); 80 id = f->codec_ids[bytestream2_get_byte(&gbc) % i]; 81 bsf->par_in->codec_id = id; 82 bsf->par_in->codec_tag = bytestream2_get_le32(&gbc); 83 } 84 85 extradata_size = bytestream2_get_le32(&gbc); 86 87 bsf->par_in->sample_rate = bytestream2_get_le32(&gbc); 88 bsf->par_in->ch_layout.nb_channels = (unsigned)bytestream2_get_le32(&gbc) % FF_SANE_NB_CHANNELS; 89 bsf->par_in->block_align = bytestream2_get_le32(&gbc); 90 keyframes = bytestream2_get_le64(&gbc); 91 flushpattern = bytestream2_get_le64(&gbc); 92 flags = bytestream2_get_byte(&gbc); 93 94 if (flags & 0x20) { 95 if (!strcmp(f->name, "av1_metadata")) 96 av_opt_set_int(bsf->priv_data, "td", bytestream2_get_byte(&gbc) % 3, 0); 97 else if (!strcmp(f->name, "h264_metadata") || !strcmp(f->name, "h265_metadata")) 98 av_opt_set_int(bsf->priv_data, "aud", bytestream2_get_byte(&gbc) % 3, 0); 99 else if (!strcmp(f->name, "extract_extradata")) 100 av_opt_set_int(bsf->priv_data, "remove", bytestream2_get_byte(&gbc) & 1, 0); 101 } 102 103 if (extradata_size < size) { 104 bsf->par_in->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 105 if (bsf->par_in->extradata) { 106 bsf->par_in->extradata_size = extradata_size; 107 size -= bsf->par_in->extradata_size; 108 memcpy(bsf->par_in->extradata, data + size, bsf->par_in->extradata_size); 109 } 110 } 111 if (av_image_check_size(bsf->par_in->width, bsf->par_in->height, 0, bsf)) 112 bsf->par_in->width = bsf->par_in->height = 0; 113 } 114 115 res = av_bsf_init(bsf); 116 if (res < 0) { 117 av_bsf_free(&bsf); 118 return 0; // Failure of av_bsf_init() does not imply that a issue was found 119 } 120 121 pkt = av_packet_alloc(); 122 if (!pkt) 123 error("Failed memory allocation"); 124 125 while (data < end) { 126 // Search for the TAG 127 while (data + sizeof(fuzz_tag) < end) { 128 if (data[0] == (fuzz_tag & 0xFF) && AV_RN64(data) == fuzz_tag) 129 break; 130 data++; 131 } 132 if (data + sizeof(fuzz_tag) > end) 133 data = end; 134 135 res = av_new_packet(pkt, data - last); 136 if (res < 0) 137 error("Failed memory allocation"); 138 memcpy(pkt->data, last, data - last); 139 pkt->flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; 140 keyframes = (keyframes >> 2) + (keyframes<<62); 141 data += sizeof(fuzz_tag); 142 last = data; 143 144 if (!(flushpattern & 7)) 145 av_bsf_flush(bsf); 146 flushpattern = (flushpattern >> 3) + (flushpattern << 61); 147 148 res = av_bsf_send_packet(bsf, pkt); 149 if (res < 0) { 150 av_packet_unref(pkt); 151 continue; 152 } 153 while (av_bsf_receive_packet(bsf, pkt) >= 0) 154 av_packet_unref(pkt); 155 } 156 157 av_bsf_send_packet(bsf, NULL); 158 while (av_bsf_receive_packet(bsf, pkt) >= 0) 159 av_packet_unref(pkt); 160 161 av_packet_free(&pkt); 162 av_bsf_free(&bsf); 163 return 0; 164} 165