shithub: opus

Download patch

ref: 62ea8ea120e3cee6e43eeec3a980b367b374e339
parent: d8d7763369e2d5af79925c61bf4b4e7adccb38fa
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Wed Apr 16 06:58:26 EDT 2025

Don't limit multi-frame packets to 1276 bytes

--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -1042,8 +1042,34 @@
       st->end = end = IMAX(1, mode->effEBands-2*(data0>>5));
       LM = (data0>>3)&0x3;
       C = 1 + ((data0>>2)&0x1);
-      data++;
-      len--;
+      if ((data[0] & 0x03) == 0x03) {
+         data++;
+         len--;
+         if (len<=0)
+            return OPUS_INVALID_PACKET;
+         if (data[0] & 0x40) {
+            int p;
+            int padding=0;
+            data++;
+            len--;
+            do {
+               int tmp;
+               if (len<=0)
+                  return OPUS_INVALID_PACKET;
+               p = *data++;
+               len--;
+               tmp = p==255 ? 254: p;
+               len -= tmp;
+               padding += tmp;
+            } while (p==255);
+            padding--;
+            if (len <= 0 || padding<0) return OPUS_INVALID_PACKET;
+         }
+      } else
+      {
+         data++;
+         len--;
+      }
       if (LM>mode->maxLM)
          return OPUS_INVALID_PACKET;
       if (frame_size < mode->shortMdctSize<<LM)
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -1151,7 +1151,8 @@
 #endif
     ALLOC_STACK;
 
-    max_data_bytes = IMIN(1276, out_data_bytes);
+    /* Just avoid insane packet sizes here, but the real bounds are applied later on. */
+    max_data_bytes = IMIN(1276*6, out_data_bytes);
 
     st->rangeFinal = 0;
     if (frame_size <= 0 || max_data_bytes <= 0)
@@ -1265,7 +1266,7 @@
     st->bitrate_bps -= dred_bitrate_bps;
 #endif
     if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
-       || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
+       || (frame_rate<50 && (max_data_bytes*(opus_int32)frame_rate<300 || st->bitrate_bps < 2400)))
     {
        /*If the space is too low to do something useful, emit 'PLC' frames.*/
        int tocmode = st->mode;
@@ -1761,7 +1762,7 @@
 }
 
 static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm, int frame_size,
-                unsigned char *data, opus_int32 max_data_bytes,
+                unsigned char *data, opus_int32 orig_max_data_bytes,
                 int float_api, int first_frame,
 #ifdef ENABLE_DRED
                 opus_int32 dred_bitrate_bps,
@@ -1777,6 +1778,7 @@
     const CELTMode *celt_mode;
     int i;
     int ret=0;
+    int max_data_bytes;
     opus_int32 nBytes;
     ec_enc enc;
     int bytes_target;
@@ -1797,6 +1799,7 @@
     VARDECL(opus_res, tmp_prefill);
     SAVE_STACK;
 
+    max_data_bytes = IMIN(orig_max_data_bytes, 1276);
     st->rangeFinal = 0;
     silk_enc = (char*)st+st->silk_enc_offset;
     celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
@@ -2497,12 +2500,12 @@
 #endif
     if (apply_padding)
     {
-       if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)
+       if (opus_packet_pad(data, ret, orig_max_data_bytes) != OPUS_OK)
        {
           RESTORE_STACK;
           return OPUS_INTERNAL_ERROR;
        }
-       ret = max_data_bytes;
+       ret = orig_max_data_bytes;
     }
     RESTORE_STACK;
     return ret;
--