Commit 568b3c5e31 for ffmpeg

commit 568b3c5e31c2af9e15ad9a926a7656036491178c
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Mon Nov 2 19:44:59 2026 +0100

    avcodec/flashsvenc: use the previous frame's own linesize

    Fixes: HXFS7VRNHzgr
    Fixes: out of array read
    Out of array read Replicated through UnModified FFmpeg with ASAN, using
    -noautoscale

    Found during triage/review of the security report AISLE-2026-R0043

diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index bd4c8651e2..0e12428ad9 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -62,6 +62,7 @@
 typedef struct FlashSVContext {
     AVCodecContext *avctx;
     const uint8_t  *previous_frame;
+    int             previous_linesize;
     AVBufferRef    *prev_frame_buf;
     int             image_width, image_height;
     unsigned        packet_size;
@@ -71,14 +72,15 @@ typedef struct FlashSVContext {
 } FlashSVContext;

 static int copy_region_enc(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
-                           int h, int w, int stride, const uint8_t *pfptr)
+                           int h, int w, int stride, const uint8_t *pfptr,
+                           int pstride)
 {
     int i, j;
     int diff = 0;

     for (i = dx + h; i > dx; i--) {
         const uint8_t *nsptr = sptr + i * stride + dy * 3;
-        const uint8_t *npfptr = pfptr + i * stride + dy * 3;
+        const uint8_t *npfptr = pfptr + i * pstride + dy * 3;
         for (j = 0; j < w * 3; j++) {
             diff    |= npfptr[j] ^ nsptr[j];
             dptr[j]  = nsptr[j];
@@ -132,7 +134,8 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx)

 static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf,
                             int buf_size, int block_width, int block_height,
-                            const uint8_t *previous_frame, int *I_frame)
+                            const uint8_t *previous_frame,
+                            int previous_linesize, int *I_frame)
 {

     PutBitContext pb;
@@ -172,7 +175,8 @@ static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf,
             res = copy_region_enc(p->data[0], s->tmpblock,
                                   s->image_height - (y_pos + cur_blk_height + 1),
                                   x_pos, cur_blk_height, cur_blk_width,
-                                  p->linesize[0], previous_frame);
+                                  p->linesize[0], previous_frame,
+                                  previous_linesize);

             if (res || *I_frame) {
                 unsigned long zsize = 3 * block_width * block_height + 12;
@@ -209,6 +213,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 {
     FlashSVContext * const s = avctx->priv_data;
     const uint8_t *prev_frame = s->previous_frame;
+    int prev_linesize = s->previous_linesize;
     int res;
     int I_frame = 0;
     int opt_w = 4, opt_h = 4;
@@ -216,6 +221,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     /* First frame needs to be a keyframe */
     if (!s->previous_frame) {
         prev_frame = pict->data[0];
+        prev_linesize = pict->linesize[0];
         I_frame = 1;
     }

@@ -231,7 +237,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

     pkt->size = encode_bitstream(s, pict, pkt->data, pkt->size,
                                  opt_w * 16, opt_h * 16,
-                                 prev_frame, &I_frame);
+                                 prev_frame, prev_linesize, &I_frame);

     //mark the frame type so the muxer can mux it correctly
     if (I_frame) {
@@ -248,6 +254,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if (res < 0)
         return res;
     s->previous_frame = pict->data[0];
+    s->previous_linesize = pict->linesize[0];

     return 0;
 }