PR #23036 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23036
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23036.patch

Modifying the keys of a sorted structure, be that a tree or other
can lead to changes in the ordering and undefined behavior.
It can also lead to collisions with existing keys.

All these cases need to be handled unless there is a bug elsewhere
that would prevent them.

Fixes: out of array access
Fixes: 
504281984/clusterfuzz-testcase-minimized-ffmpeg_BSF_DTS2PTS_fuzzer-6032368162111488

Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <[email protected]>


>From 093e3bd3f7d790520080f881c794ff7e13d10825 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Thu, 7 May 2026 03:03:31 +0200
Subject: [PATCH] avcodec/bsf/dts2pts: fix binary tree invariant violation on
 selective dec_poc

Modifying the keys of a sorted structure, be that a tree or other
can lead to changes in the ordering and undefined behavior.
It can also lead to collisions with existing keys.

All these cases need to be handled unless there is a bug elsewhere
that would prevent them.

Fixes: out of array access
Fixes: 
504281984/clusterfuzz-testcase-minimized-ffmpeg_BSF_DTS2PTS_fuzzer-6032368162111488

Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/bsf/dts2pts.c | 40 ++++++++++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/libavcodec/bsf/dts2pts.c b/libavcodec/bsf/dts2pts.c
index ff03508c18..6e391c291f 100644
--- a/libavcodec/bsf/dts2pts.c
+++ b/libavcodec/bsf/dts2pts.c
@@ -413,11 +413,23 @@ static int hevc_init_nb_frame(AVBSFContext *ctx, int poc)
     return 0;
 }
 
-static int same_gop(void *opaque, void *elem)
+typedef struct DTS2PTSCollect {
+    int gop;
+    DTS2PTSNode **out;
+    int count;
+    int max;
+} DTS2PTSCollect;
+
+static int collect_same_gop(void *opaque, void *elem)
 {
+    DTS2PTSCollect *c = opaque;
     DTS2PTSNode *node = elem;
-    int gop = ((int *)opaque)[1];
-    return FFDIFFSIGN(gop, node->gop);
+    if (node->gop == c->gop) {
+        if (c->count < c->max)
+            c->out[c->count] = node;
+        c->count++;
+    }
+    return 0;
 }
 
 static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool 
*queued)
@@ -441,10 +453,26 @@ static int hevc_queue_frame(AVBSFContext *ctx, AVPacket 
*pkt, int poc, bool *que
     }
 
     if (poc < s->nb_frame && hevc->gop == s->gop) {
-        int tmp[] = {s->nb_frame - poc, s->gop};
+        int dec = s->nb_frame - poc;
+        DTS2PTSNode *nodes[HEVC_MAX_DPB_SIZE * 2];
+        DTS2PTSCollect c = { s->gop, nodes, 0, FF_ARRAY_ELEMS(nodes) };
 
-        s->nb_frame -= tmp[0];
-        av_tree_enumerate(s->root, tmp, same_gop, dec_poc);
+        s->nb_frame -= dec;
+
+        av_tree_enumerate(s->root, &c, NULL, collect_same_gop);
+        av_assert0(c.count <= c.max);
+        for (int i = 0; i < c.count; i++) {
+            struct AVTreeNode *tnode = NULL;
+            DTS2PTSNode *r;
+            av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode);
+            nodes[i]->poc -= dec;
+            r = av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode);
+            if (r && r != nodes[i]) {
+                *r = *nodes[i];
+                av_refstruct_unref(&nodes[i]);
+                av_free(tnode);
+            }
+        }
     }
 
     ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, 1, 
s->gop);
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to