#include "config.h"
#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/bytestream.h"
c->filesize = FFMIN(c->pos, c->filesize);
return AVERROR_EOF;
}
+ if (c->pos > INT64_MAX - size)
+ return AVERROR(EIO);
memcpy(buf, c->fuzz, size);
c->fuzz += size;
if (offset > INT64_MAX - c->filesize)
return -1;
offset += c->filesize;
+ } else if (whence == AVSEEK_SIZE) {
+ return c->filesize;
}
if (offset < 0 || offset > c->filesize)
return -1;
+ if (IO_FLAT) {
+ c->fuzz += offset - c->pos;
+ c->fuzz_size -= offset - c->pos;
+ }
c->pos = offset;
return 0;
}
// Ensure we don't loop forever
const uint32_t maxiteration = 8096;
+const int maxblocks= 50000;
static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL;
static int c;
int seekable = 0;
int ret;
+ AVInputFormat *fmt = NULL;
+#ifdef FFMPEG_DEMUXER
+#define DEMUXER_SYMBOL0(DEMUXER) ff_##DEMUXER##_demuxer
+#define DEMUXER_SYMBOL(DEMUXER) DEMUXER_SYMBOL0(DEMUXER)
+ extern AVInputFormat DEMUXER_SYMBOL(FFMPEG_DEMUXER);
+ fmt = &DEMUXER_SYMBOL(FFMPEG_DEMUXER);
+#endif
if (!c) {
- av_register_all();
- avcodec_register_all();
av_log_set_level(AV_LOG_PANIC);
c=1;
}
if (!avfmt)
error("Failed avformat_alloc_context()");
- if (size > 2048) {
+ if (IO_FLAT) {
+ seekable = 1;
+ io_buffer_size = size;
+ } else if (size > 2048) {
+ int flags;
+ char extension[64];
+
GetByteContext gbc;
memcpy (filename, data + size - 1024, 1024);
bytestream2_init(&gbc, data + size - 2048, 1024);
size -= 2048;
io_buffer_size = bytestream2_get_le32(&gbc) & 0xFFFFFFF;
- seekable = bytestream2_get_byte(&gbc) & 1;
+ flags = bytestream2_get_byte(&gbc);
+ seekable = flags & 1;
filesize = bytestream2_get_le64(&gbc) & 0x7FFFFFFFFFFFFFFF;
+
+ if ((flags & 2) && strlen(filename) < sizeof(filename) / 2) {
+ const AVInputFormat *avif = NULL;
+ void *avif_iter = NULL;
+ int avif_count = 0;
+ while ((avif = av_demuxer_iterate(&avif_iter))) {
+ if (avif->extensions)
+ avif_count ++;
+ }
+ avif_count = bytestream2_get_le32(&gbc) % avif_count;
+
+ avif_iter = NULL;
+ while ((avif = av_demuxer_iterate(&avif_iter))) {
+ if (avif->extensions)
+ if (!avif_count--)
+ break;
+ }
+ av_strlcpy(extension, avif->extensions, sizeof(extension));
+ if (strchr(extension, ','))
+ *strchr(extension, ',') = 0;
+ av_strlcatf(filename, sizeof(filename), ".%s", extension);
+ }
}
+
+ if (!io_buffer_size || size / io_buffer_size > maxblocks)
+ io_buffer_size = size;
+
io_buffer = av_malloc(io_buffer_size);
if (!io_buffer)
error("Failed to allocate io_buffer");
avfmt->pb = fuzzed_pb;
- ret = avformat_open_input(&avfmt, filename, NULL, NULL);
+ ret = avformat_open_input(&avfmt, filename, fmt, NULL);
if (ret < 0) {
av_freep(&fuzzed_pb->buffer);
av_freep(&fuzzed_pb);
break;
av_packet_unref(&pkt);
}
-end:
+
av_freep(&fuzzed_pb->buffer);
- av_freep(&fuzzed_pb);
+ avio_context_free(&fuzzed_pb);
avformat_close_input(&avfmt);
return 0;