This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit a38ce70f0e178e8d8944a8fe4f65da035bc66f15
Author:     Kacper Michajłow <[email protected]>
AuthorDate: Wed Sep 23 00:20:45 2026 +0200
Commit:     Kacper Michajłow <[email protected]>
CommitDate: Tue Oct 13 15:21:48 2026 +0000

    avformat/img2dec: do not let a complete PNG outscore what follows it
    
    png_probe returns AVPROBE_SCORE_MAX - 1 on the signature alone, so a
    1x1 PNG prepended to an MPEG-TS segment wins the first probe iteration
    whenever mpegts cannot reach AVPROBE_SCORE_MAX, and the probe loop never
    looks any further. Some CDNs serve HLS segments this way to pass image
    only content filters, and once the leading packet is damaged mpegts
    only scores 49 in the first 2048 bytes.
    
    png_pipe demuxes a sequence of images, so once a whole image is inside
    the probe buffer it has to be followed by another signature or by the
    end of the input. Walk the chunks and return AVPROBE_SCORE_RETRY when
    IEND is followed by anything else.
    
    Fixes: https://github.com/mpv-player/mpv/issues/11365
    Signed-off-by: Kacper Michajłow <[email protected]>
---
 libavformat/img2dec.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index e51b3437bd..ccfea62d15 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -43,6 +43,7 @@
 #include "os_support.h"
 #include "libavcodec/jpegxl_parse.h"
 #include "libavcodec/mjpeg.h"
+#include "libavcodec/png.h"
 #include "libavcodec/vbn.h"
 #include "libavcodec/xwd.h"
 #include "subtitles.h"
@@ -892,10 +893,33 @@ static int pictor_probe(const AVProbeData *p)
 static int png_probe(const AVProbeData *p)
 {
     const uint8_t *b = p->buf;
+    int size = p->buf_size;
+    int pos = 8;
 
-    if (AV_RB64(b) == 0x89504e470d0a1a0a)
-        return AVPROBE_SCORE_MAX - 1;
-    return 0;
+    if (AV_RB64(b) != PNGSIG)
+        return 0;
+
+    /* png_pipe demuxes a sequence of images, so the bytes after a whole
+     * image in the buffer have to match another signature as far as the
+     * buffer goes. Anything else is an unrelated payload behind a PNG,
+     * like the 1x1 image some CDNs prepend to MPEG-TS segments, and the
+     * signature alone must not outscore the demuxer of that payload. */
+    while (size - pos >= 12) {
+        uint32_t len = AV_RB32(b + pos);
+        uint32_t tag = AV_RB32(b + pos + 4);
+
+        if (len > size - pos - 12)
+            break;
+        pos += 12 + len;
+        if (tag == MKBETAG('I', 'E', 'N', 'D')) {
+            int n = FFMIN(size - pos, 8);
+            if (n && (AV_RB64(b + pos) ^ PNGSIG) >> (64 - 8 * n))
+                return AVPROBE_SCORE_RETRY;
+            pos += n;
+        }
+    }
+
+    return AVPROBE_SCORE_MAX - 1;
 }
 
 static int psd_probe(const AVProbeData *p)

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to