From a6766c94721bc55e8e56fb0d941ecfe2d27c3d17 Mon Sep 17 00:00:00 2001
From: Petter Reinholdtsen <pere@debian.org>
Date: Sun, 9 Mar 2025 08:07:49 +0100
Subject: [PATCH 1/3] Replaced possible bit shifting into signed bit of stride
 values.

Use multiplication instead, allowing the compiler to optimize to
bitshifts if it believe it to be safe.

Partly solves github issue #18.

Backported to 1.1.1 by <wangshuo@kylinos.cn>, fix CVE-2024-56431
https://github.com/xiph/theora/commit/a6766c94721bc55e8e56fb0d941ecfe2d27c3d17
---
 lib/decode.c      | 14 +++++++-------
 lib/state.c       |  4 ++--
 lib/x86/mmxfrag.c |  2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/decode.c b/lib/decode.c
index bde967b..fd03fba 100644
--- a/lib/decode.c
+++ b/lib/decode.c
@@ -1747,13 +1747,13 @@ static void oc_dec_deblock_frag_rows(oc_dec_ctx *_dec,
       flimit=(qstep*3)>>2;
       oc_filter_hedge(dst+x,dst_ystride,src+x-src_ystride,src_ystride,
        qstep,flimit,variance,variance+nhfrags);
-      oc_filter_vedge(dst+x-(dst_ystride<<2)-4,dst_ystride,
+      oc_filter_vedge(dst+x-(dst_ystride*4)-4,dst_ystride,
        qstep,flimit,variance-1);
       variance++;
       dc_qi++;
     }
-    dst+=dst_ystride<<3;
-    src+=src_ystride<<3;
+    dst+=dst_ystride*8;
+    src+=src_ystride*8;
   }
   /*And finally, handle the last row in the frame, if it's in the range.*/
   if(!notdone){
@@ -1769,7 +1769,7 @@ static void oc_dec_deblock_frag_rows(oc_dec_ctx *_dec,
     for(x=8;x<width;x+=8){
       qstep=_dec->pp_dc_scale[*dc_qi++];
       flimit=(qstep*3)>>2;
-      oc_filter_vedge(dst+x-(dst_ystride<<3)-4,dst_ystride,
+      oc_filter_vedge(dst+x-(dst_ystride*8)-4,dst_ystride,
        qstep,flimit,variance++);
     }
   }
@@ -1944,7 +1944,7 @@ static void oc_dec_dering_frag_rows(oc_dec_ctx *_dec,th_img_plane *_img,
       frag++;
       variance++;
     }
-    idata+=ystride<<3;
+    idata+=ystride*8;
   }
 }
 
@@ -2877,10 +2877,10 @@ int th_decode_ycbcr_out(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr){
             u_row[x>>1]=OC_CLAMP255(u);
             v_row[x>>1]=OC_CLAMP255(v);
           }
-          y_row+=_ycbcr[0].stride<<1;
+          y_row+=_ycbcr[0].stride*2;
           u_row+=_ycbcr[1].stride;
           v_row+=_ycbcr[2].stride;
-          rgb_row+=cstride<<1;
+          rgb_row+=cstride*2;
         }
       }break;
       case TH_PF_422:{
diff --git a/lib/state.c b/lib/state.c
index 42ed33a..fe803d6 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -573,7 +573,7 @@ static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){
         frag_buf_offs[fragi]=hpix-ref_frame_data;
         hpix+=8;
       }
-      vpix+=stride<<3;
+      vpix+=stride*8;
     }
   }
   /*Initialize the reference frame indices.*/
@@ -1055,7 +1055,7 @@ void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state,int *_bv,
           loop_filter_h(ref+8,ystride,_bv);
         }
         if(fragi+nhfrags<fragi_bot&&!frags[fragi+nhfrags].coded){
-          loop_filter_v(ref+(ystride<<3),ystride,_bv);
+          loop_filter_v(ref+(ystride*8),ystride,_bv);
         }
       }
       fragi++;
diff --git a/lib/x86/mmxfrag.c b/lib/x86/mmxfrag.c
index 2c73293..6930aaf 100644
--- a/lib/x86/mmxfrag.c
+++ b/lib/x86/mmxfrag.c
@@ -141,7 +141,7 @@ void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride,
     :
     :[residue]"r"(_residue),
      [dst]"r"(_dst),
-     [dst4]"r"(_dst+(_ystride<<2)),
+     [dst4]"r"(_dst+(_ystride*4)),
      [ystride]"r"((ptrdiff_t)_ystride),
      [ystride3]"r"((ptrdiff_t)_ystride*3)
     :"memory"
-- 
2.27.0

From 62b266ae4e2465ab24b5ed4761044e2af3015fee Mon Sep 17 00:00:00 2001
From: Petter Reinholdtsen <pere@debian.org>
Date: Sun, 9 Mar 2025 08:11:17 +0100
Subject: [PATCH 2/3] Made mask unsigned to avoid shifting into sign bit.

The last iteration of the loop execute 1<<63, which would push the
result into the signed bit of a signed 64 bit type, and this
move into currently undefined behaviour with C99.  Avoid the
issue by making the operation work on unsigned 64 bit type instead.

This require libogg version to 1.3.4, raise autotools dependency check
to look for this.

Partly solves github issue #18.

Backported to 1.1.1 by <wangshuo@kylinos.cn>, fix CVE-2024-56431
https://github.com/xiph/theora/commit/62b266ae4e2465ab24b5ed4761044e2af3015fee
---
 configure.ac | 4 ++--
 lib/state.c  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8260bdf..078ec13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -268,7 +268,7 @@ dnl check for pkg-config itself so we don't try the m4 macro without pkg-config
 AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes)
 if test "x$HAVE_PKG_CONFIG" = "xyes"
 then
-  PKG_CHECK_MODULES(OGG, ogg >= 1.1, HAVE_OGG=yes, HAVE_OGG=no)
+  PKG_CHECK_MODULES(OGG, ogg >= 1.3.4, HAVE_OGG=yes, HAVE_OGG=no)
 fi
 if test "x$HAVE_OGG" = "xno"
 then
@@ -283,7 +283,7 @@ then
   CFLAGS="$CFLAGS $OGG_CFLAGS"
   LIBS="$LIBS $OGG_LIBS"
   AC_CHECK_FUNC(oggpackB_read, , [
-    AC_MSG_ERROR([newer libogg version (1.1 or later) required])
+    AC_MSG_ERROR([newer libogg version (1.3.4 or later) required])
   ])
   CFLAGS=$cflags_save
   LIBS=$libs_save
diff --git a/lib/state.c b/lib/state.c
index fe803d6..1deb4b0 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -316,7 +316,7 @@ static void oc_state_border_init(oc_theora_state *_state){
         /*Otherwise, check to see if it straddles the border.*/
         else if(x<crop_x0&&crop_x0<x+8||x<crop_xf&&crop_xf<x+8||
          y<crop_y0&&crop_y0<y+8||y<crop_yf&&crop_yf<y+8){
-          ogg_int64_t mask;
+          ogg_uint64_t mask;
           int         npixels;
           int         i;
           mask=npixels=0;
@@ -324,7 +324,7 @@ static void oc_state_border_init(oc_theora_state *_state){
             int j;
             for(j=0;j<8;j++){
               if(x+j>=crop_x0&&x+j<crop_xf&&y+i>=crop_y0&&y+i<crop_yf){
-                mask|=(ogg_int64_t)1<<(i<<3|j);
+                mask|=(ogg_uint64_t)1<<(i<<3|j);
                 npixels++;
               }
             }
-- 
2.27.0

From ec642ecf6d94f11d5eb05ab1fb7a9728c9a89cae Mon Sep 17 00:00:00 2001
From: Petter Reinholdtsen <pere@debian.org>
Date: Sun, 9 Mar 2025 22:53:57 +0100
Subject: [PATCH 3/3] Replaced more possible bit shifting into signed bit of
 stride values.

Leftover changes from a6766c94721bc55e8e56fb0d941ecfe2d27c3d17.

Use multiplication instead, allowing the compiler to optimize to
bitshifts if it believe it to be safe.

Partly solves github issue #18.

Backported to 1.1.1 by <wangshuo@kylinos.cn>, fix CVE-2024-56431
https://github.com/xiph/theora/commit/ec642ecf6d94f11d5eb05ab1fb7a9728c9a89cae
---
 lib/x86/mmxstate.c    | 2 +-
 lib/x86_vc/mmxstate.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/x86/mmxstate.c b/lib/x86/mmxstate.c
index 808b0a7..dd428d6 100644
--- a/lib/x86/mmxstate.c
+++ b/lib/x86/mmxstate.c
@@ -176,7 +176,7 @@ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state,
           OC_LOOP_FILTER_H_MMX(ref+8,ystride,ll);
         }
         if(fragi+nhfrags<fragi_bot&&!frags[fragi+nhfrags].coded){
-          OC_LOOP_FILTER_V_MMX(ref+(ystride<<3),ystride,ll);
+          OC_LOOP_FILTER_V_MMX(ref+(ystride*8),ystride,ll);
         }
       }
       fragi++;
diff --git a/lib/x86_vc/mmxstate.c b/lib/x86_vc/mmxstate.c
index 73bd198..8a00909 100644
--- a/lib/x86_vc/mmxstate.c
+++ b/lib/x86_vc/mmxstate.c
@@ -193,7 +193,7 @@ void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state,
           OC_LOOP_FILTER_H_MMX(ref+8,ystride,ll);
         }
         if(fragi+nhfrags<fragi_bot&&!frags[fragi+nhfrags].coded){
-          OC_LOOP_FILTER_V_MMX(ref+(ystride<<3),ystride,ll);
+          OC_LOOP_FILTER_V_MMX(ref+(ystride*8),ystride,ll);
         }
 #undef PIX
 #undef YSTRIDE3
-- 
2.27.0


