static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
{
char language[4] = { 0 };
- char buf[100];
+ char buf[200], place[100];
uint16_t langcode = 0;
double longitude, latitude;
const char *key = "location";
ff_mov_lang_to_iso639(langcode, language);
len -= 6;
- len -= avio_get_str(pb, len, buf, sizeof(buf)); // place name
+ len -= avio_get_str(pb, len, place, sizeof(place));
if (len < 1) {
av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
return AVERROR_INVALIDDATA;
latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
// Try to output in the same format as the ?xyz field
- snprintf(buf, sizeof(buf), "%+08.4f%+09.4f/", latitude, longitude);
+ snprintf(buf, sizeof(buf), "%+08.4f%+09.4f/%s", latitude, longitude, place);
if (*language && strcmp(language, "und")) {
char key2[16];
snprintf(key2, sizeof(key2), "%s-%s", key, language);
if ((atom.size -= 9+str_len) < 0)
return 0;
- avio_read(pb, str, str_len);
+ if (avio_read(pb, str, str_len) != str_len)
+ return AVERROR_INVALIDDATA;
str[str_len] = 0;
avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
}
volume_len = avio_r8(pb);
volume_len = FFMIN(volume_len, 27);
- avio_read(pb, dref->volume, 27);
+ if (avio_read(pb, dref->volume, 27) != 27)
+ return AVERROR_INVALIDDATA;
dref->volume[volume_len] = 0;
av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
len = avio_r8(pb);
len = FFMIN(len, 63);
- avio_read(pb, dref->filename, 63);
+ if (avio_read(pb, dref->filename, 63) != 63)
+ return AVERROR_INVALIDDATA;
dref->filename[len] = 0;
av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
dref->path = av_mallocz(len+1);
if (!dref->path)
return AVERROR(ENOMEM);
- avio_read(pb, dref->path, len);
+ if (avio_read(pb, dref->path, len) != len) {
+ av_freep(&dref->path);
+ return AVERROR_INVALIDDATA;
+ }
if (type == 18) // no additional processing needed
continue;
if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
dref->dir = av_malloc(len+1);
if (!dref->dir)
return AVERROR(ENOMEM);
- if (avio_read(pb, dref->dir, len) != len)
+ if (avio_read(pb, dref->dir, len) != len) {
+ av_freep(&dref->dir);
return AVERROR_INVALIDDATA;
+ }
dref->dir[len] = 0;
for (j = 0; j < len; j++)
if (dref->dir[j] == ':')
title_str = av_malloc(title_size + 1); /* Add null terminator */
if (!title_str)
return AVERROR(ENOMEM);
- avio_read(pb, title_str, title_size);
+ if (avio_read(pb, title_str, title_size) != title_size) {
+ av_freep(&title_str);
+ return AVERROR_INVALIDDATA;
+ }
title_str[title_size] = 0;
if (title_str[0]) {
int off = (!c->isom && title_str[0] == title_size - 1);
char* comp_brands_str;
uint8_t type[5] = {0};
- avio_read(pb, type, 4);
+ if (avio_read(pb, type, 4) != 4)
+ return AVERROR_INVALIDDATA;
if (strcmp(type, "qt "))
c->isom = 1;
av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
if (!comp_brands_str)
return AVERROR(ENOMEM);
- avio_read(pb, comp_brands_str, comp_brand_size);
+ if (avio_read(pb, comp_brands_str, comp_brand_size) != comp_brand_size) {
+ av_freep(&comp_brands_str);
+ return AVERROR_INVALIDDATA;
+ }
comp_brands_str[comp_brand_size] = 0;
av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
av_freep(&comp_brands_str);
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- avio_read(pb, color_parameter_type, 4);
+ if (avio_read(pb, color_parameter_type, 4) != 4)
+ return AVERROR_INVALIDDATA;
if (strncmp(color_parameter_type, "nclx", 4) &&
strncmp(color_parameter_type, "nclc", 4)) {
av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
cr = (ycbcr >> 8) & 0xFF;
cb = ycbcr & 0xFF;
- b = av_clip_uint8(1.164 * (y - 16) + 2.018 * (cb - 128));
- g = av_clip_uint8(1.164 * (y - 16) - 0.813 * (cr - 128) - 0.391 * (cb - 128));
- r = av_clip_uint8(1.164 * (y - 16) + 1.596 * (cr - 128));
+ b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
+ g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
+ r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
return (r << 16) | (g << 8) | b;
}
sc->sample_count = i;
+ av_free(buf);
+
if (pb->eof_reached)
return AVERROR_EOF;
- av_free(buf);
return 0;
}
sample_count=avio_rb32(pb);
sample_duration = avio_rb32(pb);
- /* sample_duration < 0 is invalid based on the spec */
- if (sample_duration < 0) {
- av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta %d in STTS, at %d st:%d\n",
- sample_duration, i, c->fc->nb_streams-1);
- sample_duration = 1;
- }
if (sample_count < 0) {
av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count);
return AVERROR_INVALIDDATA;
return 0;
if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
return AVERROR_INVALIDDATA;
+ av_freep(&sc->ctts_data);
sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
if (!sc->ctts_data)
return AVERROR(ENOMEM);
unsigned int distance = 0;
unsigned int rap_group_index = 0;
unsigned int rap_group_sample = 0;
+ int64_t last_dts = 0;
+ int64_t dts_correction = 0;
int rap_group_present = sc->rap_group_count && sc->rap_group;
int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
current_dts -= sc->dts_shift;
+ last_dts = current_dts;
if (!sc->sample_count || st->nb_index_entries)
return;
current_offset += sample_size;
stream_size += sample_size;
+
+ /* A negative sample duration is invalid based on the spec,
+ * but some samples need it to correct the DTS. */
+ if (sc->stts_data[stts_index].duration < 0) {
+ av_log(mov->fc, AV_LOG_WARNING,
+ "Invalid SampleDelta %d in STTS, at %d st:%d\n",
+ sc->stts_data[stts_index].duration, stts_index,
+ st->index);
+ dts_correction += sc->stts_data[stts_index].duration - 1;
+ sc->stts_data[stts_index].duration = 1;
+ }
current_dts += sc->stts_data[stts_index].duration;
+ if (!dts_correction || current_dts + dts_correction > last_dts) {
+ current_dts += dts_correction;
+ dts_correction = 0;
+ } else {
+ /* Avoid creating non-monotonous DTS */
+ dts_correction += current_dts - last_dts - 1;
+ current_dts = last_dts + 1;
+ }
+ last_dts = current_dts;
distance++;
stts_sample++;
current_sample++;
AVIndexEntry *e;
unsigned size, samples;
+ if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
+ avpriv_request_sample(mov->fc,
+ "Zero bytes per frame, but %d samples per frame",
+ sc->samples_per_frame);
+ return;
+ }
+
if (sc->samples_per_frame >= 160) { // gsm
samples = sc->samples_per_frame;
size = sc->bytes_per_frame;
} else if (c->fc->open_cb) {
if (!open_func(c->fc, pb, ref->path, AVIO_FLAG_READ, int_cb, NULL))
return 0;
+ } else {
+ av_log(c->fc, AV_LOG_ERROR,
+ "Absolute path %s not tried for security reasons, "
+ "set demuxer option use_absolute_path to allow absolute paths\n",
+ ref->path);
}
return AVERROR(ENOENT);
*p = av_malloc(len + 1);
if (!*p)
break;
- avio_read(pb, *p, len);
+ if (avio_read(pb, *p, len) != len) {
+ av_freep(p);
+ return AVERROR_INVALIDDATA;
+ }
(*p)[len] = 0;
}
av_free(cmov_data);
return AVERROR(ENOMEM);
}
- avio_read(pb, cmov_data, cmov_len);
+ if (avio_read(pb, cmov_data, cmov_len) != cmov_len) {
+ av_freep(&cmov_data);
+ av_freep(&moov_data);
+ return AVERROR_INVALIDDATA;
+ }
if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
goto free_and_return;
if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
goto free_and_return;
+ ctx.seekable = AVIO_SEEKABLE_NORMAL;
atom.type = MKTAG('m','o','o','v');
atom.size = moov_len;
ret = mov_read_default(c, &ctx, atom);
c->moov_retry) {
uint8_t buf[8];
uint32_t *type = (uint32_t *)buf + 1;
- avio_read(pb, buf, 8);
+ if (avio_read(pb, buf, 8) != 8)
+ return AVERROR_INVALIDDATA;
avio_seek(pb, -8, SEEK_CUR);
if (*type == MKTAG('m','v','h','d') ||
*type == MKTAG('c','m','o','v')) {
mov->found_mdat = 0;
if (!mov->next_root_atom)
return AVERROR_EOF;
- avio_seek(s->pb, mov->next_root_atom, SEEK_SET);
+ if (avio_seek(s->pb, mov->next_root_atom, SEEK_SET) != mov->next_root_atom) {
+ av_log(mov->fc, AV_LOG_ERROR, "next root atom offset 0x%"PRIx64": partial file\n", mov->next_root_atom);
+ return AVERROR_INVALIDDATA;
+ }
mov->next_root_atom = 0;
if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
avio_feof(s->pb))