ffmpeg | branch: master | James Almer <[email protected]> | Tue Oct 17 15:27:43 2017 -0300| [552d2cb6f75170621ac37abac249dfdac893bcb6] | committer: James Almer
Merge commit '0f8512c4a87b89b4694053d8ffda48066ee1da62' * commit '0f8512c4a87b89b4694053d8ffda48066ee1da62': mov: Validate spherical metadata version Merged-by: James Almer <[email protected]> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=552d2cb6f75170621ac37abac249dfdac893bcb6 --- libavformat/mov.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 07d57037db..b22a116140 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4823,7 +4823,7 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; MOVStreamContext *sc; - int size, layout; + int size, version, layout; int32_t yaw, pitch, roll; uint32_t l = 0, t = 0, r = 0, b = 0; uint32_t tag, padding = 0; @@ -4849,7 +4849,13 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n"); return 0; } - avio_skip(pb, 4); /* version + flags */ + version = avio_r8(pb); + if (version != 0) { + av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n", + version); + return 0; + } + avio_skip(pb, 3); /* flags */ avio_skip(pb, size - 12); /* metadata_source */ size = avio_rb32(pb); @@ -4871,7 +4877,13 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n"); return 0; } - avio_skip(pb, 4); /* version + flags */ + version = avio_r8(pb); + if (version != 0) { + av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n", + version); + return 0; + } + avio_skip(pb, 3); /* flags */ /* 16.16 fixed point */ yaw = avio_rb32(pb); @@ -4883,7 +4895,13 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_INVALIDDATA; tag = avio_rl32(pb); - avio_skip(pb, 4); /* version + flags */ + version = avio_r8(pb); + if (version != 0) { + av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n", + version); + return 0; + } + avio_skip(pb, 3); /* flags */ switch (tag) { case MKTAG('c','b','m','p'): layout = avio_rb32(pb); ====================================================================== diff --cc libavformat/mov.c index 07d57037db,f406831457..b22a116140 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@@ -4721,149 -3267,20 +4721,155 @@@ static int mov_read_smdm(MOVContext *c return 0; } avio_skip(pb, 3); /* flags */ - avio_skip(pb, size - 12); /* metadata_source */ - size = avio_rb32(pb); - if (size > atom.size) - return AVERROR_INVALIDDATA; + sc->mastering = av_mastering_display_metadata_alloc(); + if (!sc->mastering) + return AVERROR(ENOMEM); - tag = avio_rl32(pb); - if (tag != MKTAG('p','r','o','j')) { - av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n"); - return 0; - } + for (i = 0; i < 3; i++) + for (j = 0; j < 2; j++) + sc->mastering->display_primaries[i][j] = + av_make_q(lrint(((double)avio_rb16(pb) / (1 << 16)) * chroma_den), chroma_den); + for (i = 0; i < 2; i++) + sc->mastering->white_point[i] = + av_make_q(lrint(((double)avio_rb16(pb) / (1 << 16)) * chroma_den), chroma_den); + sc->mastering->max_luminance = + av_make_q(lrint(((double)avio_rb32(pb) / (1 << 8)) * luma_den), luma_den); + sc->mastering->min_luminance = + av_make_q(lrint(((double)avio_rb32(pb) / (1 << 14)) * luma_den), luma_den); + + sc->mastering->has_primaries = 1; + sc->mastering->has_luminance = 1; - size = avio_rb32(pb); - if (size > atom.size) + return 0; +} + +static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + MOVStreamContext *sc; + int version; + + if (c->fc->nb_streams < 1) + return AVERROR_INVALIDDATA; + + sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data; + + if (atom.size < 5) { + av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n"); + return AVERROR_INVALIDDATA; + } + + version = avio_r8(pb); + if (version) { + av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version); + return 0; + } + avio_skip(pb, 3); /* flags */ + + sc->coll = av_content_light_metadata_alloc(&sc->coll_size); + if (!sc->coll) + return AVERROR(ENOMEM); + + sc->coll->MaxCLL = avio_rb16(pb); + sc->coll->MaxFALL = avio_rb16(pb); + + return 0; +} + +static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + AVStream *st; + MOVStreamContext *sc; + enum AVStereo3DType type; + int mode; + + if (c->fc->nb_streams < 1) + return 0; + + st = c->fc->streams[c->fc->nb_streams - 1]; + sc = st->priv_data; + + if (atom.size < 5) { + av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n"); + return AVERROR_INVALIDDATA; + } + avio_skip(pb, 4); /* version + flags */ + + mode = avio_r8(pb); + switch (mode) { + case 0: + type = AV_STEREO3D_2D; + break; + case 1: + type = AV_STEREO3D_TOPBOTTOM; + break; + case 2: + type = AV_STEREO3D_SIDEBYSIDE; + break; + default: + av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode); + return 0; + } + + sc->stereo3d = av_stereo3d_alloc(); + if (!sc->stereo3d) + return AVERROR(ENOMEM); + + sc->stereo3d->type = type; + return 0; +} + +static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + AVStream *st; + MOVStreamContext *sc; - int size, layout; ++ int size, version, layout; + int32_t yaw, pitch, roll; + uint32_t l = 0, t = 0, r = 0, b = 0; + uint32_t tag, padding = 0; + enum AVSphericalProjection projection; + + if (c->fc->nb_streams < 1) + return 0; + + st = c->fc->streams[c->fc->nb_streams - 1]; + sc = st->priv_data; + + if (atom.size < 8) { + av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n"); + return AVERROR_INVALIDDATA; + } + + size = avio_rb32(pb); + if (size <= 12 || size > atom.size) + return AVERROR_INVALIDDATA; + + tag = avio_rl32(pb); + if (tag != MKTAG('s','v','h','d')) { + av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n"); + return 0; + } - avio_skip(pb, 4); /* version + flags */ ++ version = avio_r8(pb); ++ if (version != 0) { ++ av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n", ++ version); ++ return 0; ++ } ++ avio_skip(pb, 3); /* flags */ + avio_skip(pb, size - 12); /* metadata_source */ + + size = avio_rb32(pb); + if (size > atom.size) + return AVERROR_INVALIDDATA; + + tag = avio_rl32(pb); + if (tag != MKTAG('p','r','o','j')) { + av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n"); + return 0; + } + + size = avio_rb32(pb); + if (size > atom.size) return AVERROR_INVALIDDATA; tag = avio_rl32(pb); @@@ -4883,35 -3306,19 +4895,41 @@@ return AVERROR_INVALIDDATA; tag = avio_rl32(pb); - avio_skip(pb, 4); /* version + flags */ + version = avio_r8(pb); + if (version != 0) { + av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n", + version); + return 0; + } + avio_skip(pb, 3); /* flags */ switch (tag) { case MKTAG('c','b','m','p'): + layout = avio_rb32(pb); + if (layout) { + av_log(c->fc, AV_LOG_WARNING, + "Unsupported cubemap layout %d\n", layout); + return 0; + } projection = AV_SPHERICAL_CUBEMAP; + padding = avio_rb32(pb); break; case MKTAG('e','q','u','i'): - projection = AV_SPHERICAL_EQUIRECTANGULAR; + t = avio_rb32(pb); + b = avio_rb32(pb); + l = avio_rb32(pb); + r = avio_rb32(pb); + + if (b >= UINT_MAX - t || r >= UINT_MAX - l) { + av_log(c->fc, AV_LOG_ERROR, + "Invalid bounding rectangle coordinates " + "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b); + return AVERROR_INVALIDDATA; + } + + if (l || t || r || b) + projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE; + else + projection = AV_SPHERICAL_EQUIRECTANGULAR; break; default: av_log(c->fc, AV_LOG_ERROR, "Unknown projection type\n"); _______________________________________________ ffmpeg-cvslog mailing list [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
