return res;
}
+static int is_ebml_id_valid(uint32_t id)
+{
+ // Due to endian nonsense in Matroska, the highest byte with any bits set
+ // will contain the leading length bit. This bit in turn identifies the
+ // total byte length of the element by its position within the byte.
+ unsigned int bits = av_log2(id);
+ return id && (bits + 7) / 8 == (8 - bits % 8);
+}
+
/*
* Allocate and return the entry for the level1 element with the given ID. If
* an entry already exists, return the existing entry.
int i;
MatroskaLevel1Element *elem;
+ if (!is_ebml_id_valid(id))
+ return NULL;
+
// Some files link to all clusters; useless.
if (id == MATROSKA_ID_CLUSTER)
return NULL;
if (!track->codec_id)
continue;
+ if (track->audio.samplerate < 0 || track->audio.samplerate > INT_MAX ||
+ isnan(track->audio.samplerate)) {
+ av_log(matroska->ctx, AV_LOG_WARNING,
+ "Invalid sample rate %f, defaulting to 8000 instead.\n",
+ track->audio.samplerate);
+ track->audio.samplerate = 8000;
+ }
+
if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
if (!track->default_duration && track->video.frame_rate > 0)
track->default_duration = 1000000000 / track->video.frame_rate;
NULL, NULL, NULL, NULL);
avio_write(&b, "TTA1", 4);
avio_wl16(&b, 1);
+ if (track->audio.channels > UINT16_MAX ||
+ track->audio.bitdepth > UINT16_MAX) {
+ av_log(matroska->ctx, AV_LOG_WARNING,
+ "Too large audio channel number %"PRIu64
+ " or bitdepth %"PRIu64". Skipping track.\n",
+ track->audio.channels, track->audio.bitdepth);
+ av_freep(&extradata);
+ if (matroska->ctx->error_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ else
+ continue;
+ }
avio_wl16(&b, track->audio.channels);
avio_wl16(&b, track->audio.bitdepth);
if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX)