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;
--
⑨