avformat/icodec: ico probe with unknown data
authorMark Harris <mark.hsj@gmail.com>
Tue, 16 Feb 2016 07:52:12 +0000 (23:52 -0800)
committerMichael Niedermayer <michael@niedermayer.cc>
Sat, 20 Feb 2016 01:56:25 +0000 (02:56 +0100)
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>
libavformat/icodec.c

index 6ddb901..b247cb2 100644 (file)
@@ -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;
 }