diff options
author | Mark Harris <mark.hsj@gmail.com> | 2016-02-15 23:52:12 -0800 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-02-20 02:56:25 +0100 |
commit | 1b4fbf808082eaa6945e5fc2cda487573691e8e6 (patch) | |
tree | ff09b3357f28eb954bfe3ddc0f59122fddc8c1f4 /libavformat/icodec.c | |
parent | e6cbe3ffef8b456eb70a5f8e03559dbd776dff68 (diff) | |
download | ffmpeg-1b4fbf808082eaa6945e5fc2cda487573691e8e6.tar.gz |
avformat/icodec: ico probe with unknown data
Fix cases where unknown data (data beyond p->buf_size) could produce a
higher ico probe score than if the unknown data was known and valid.
For example:
Header: OK, 2 frames
Frame 0: Unknown (offset points beyond end of probe buffer)
Frame 1: Invalid
Previously this example had a score of 25, even though the score would
be 1 if the unknown frame was known to be valid or 0 if it was known
to be invalid. For this example the score is now 1.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/icodec.c')
-rw-r--r-- | libavformat/icodec.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/libavformat/icodec.c b/libavformat/icodec.c index 6ddb901b7e..b247cb2567 100644 --- a/libavformat/icodec.c +++ b/libavformat/icodec.c @@ -45,11 +45,14 @@ typedef struct { static int probe(AVProbeData *p) { - unsigned i, frames = AV_RL16(p->buf + 4); + unsigned i, frames, checked = 0; - if (AV_RL16(p->buf) || AV_RL16(p->buf + 2) != 1 || !frames) + if (p->buf_size < 22 || AV_RL16(p->buf) || AV_RL16(p->buf + 2) != 1) return 0; - for (i = 0; i < frames; i++) { + frames = AV_RL16(p->buf + 4); + if (!frames) + return 0; + for (i = 0; i < frames && i * 16 + 22 <= p->buf_size; i++) { unsigned offset; if (AV_RL16(p->buf + 10 + i * 16) & ~1) return FFMIN(i, AVPROBE_SCORE_MAX / 4); @@ -61,13 +64,14 @@ static int probe(AVProbeData *p) if (offset < 22) return FFMIN(i, AVPROBE_SCORE_MAX / 4); if (offset + 8 > p->buf_size) - return AVPROBE_SCORE_MAX / 4 + FFMIN(i, 1); + continue; if (p->buf[offset] != 40 && AV_RB64(p->buf + offset) != PNGSIG) return FFMIN(i, AVPROBE_SCORE_MAX / 4); - if (i * 16 + 6 > p->buf_size) - return AVPROBE_SCORE_MAX / 4 + FFMIN(i, 1); + checked++; } + if (checked < frames) + return AVPROBE_SCORE_MAX / 4 + FFMIN(checked, 1); return AVPROBE_SCORE_MAX / 2 + 1; } |