aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2024-02-20 14:23:59 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2024-02-20 14:23:59 -0500
commitd9d0e7292f9024b94d88f5d7b29b8bec4441fe0b (patch)
treecded7047c04d633d411b4d8909e9d7c556434a3f
parentecc10d835d4e2c2e7a21c91e980828c30728763a (diff)
downloadlibopus-d9d0e7292f9024b94d88f5d7b29b8bec4441fe0b.tar.gz
Fixes an aliasing bug in opus_packet_pad()
Trying to add padding in-place breaks when we have extensions, which causes a memcpy() with overlapping data. Just doing a copy instead.
-rw-r--r--src/repacketizer.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/repacketizer.c b/src/repacketizer.c
index 86d92c8b..6a7a8b3d 100644
--- a/src/repacketizer.c
+++ b/src/repacketizer.c
@@ -121,7 +121,7 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
int ext_begin=0, ext_len=0;
int ext_count, total_ext_count;
VARDECL(opus_extension_data, all_extensions);
- ALLOC_STACK;
+ SAVE_STACK;
if (begin<0 || begin>=end || end>rp->nb_frames)
{
@@ -312,6 +312,7 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
while (ptr<data+maxlen)
*ptr++=0;
}
+ RESTORE_STACK;
return tot_size;
}
@@ -329,24 +330,32 @@ opus_int32 opus_packet_pad_impl(unsigned char *data, opus_int32 len, opus_int32
{
OpusRepacketizer rp;
opus_int32 ret;
+ VARDECL(unsigned char, copy);
+ SAVE_STACK;
if (len < 1)
return OPUS_BAD_ARG;
if (len==new_len)
return OPUS_OK;
else if (len > new_len)
return OPUS_BAD_ARG;
+ ALLOC(copy, len, unsigned char);
opus_repacketizer_init(&rp);
/* Moving payload to the end of the packet so we can do in-place padding */
- OPUS_MOVE(data+new_len-len, data, len);
- ret = opus_repacketizer_cat(&rp, data+new_len-len, len);
+ OPUS_COPY(copy, data, len);
+ ret = opus_repacketizer_cat(&rp, copy, len);
if (ret != OPUS_OK)
return ret;
- return opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, pad, extensions, nb_extensions);
+ ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, pad, extensions, nb_extensions);
+ RESTORE_STACK;
+ return ret;
}
int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
{
- opus_int32 ret = opus_packet_pad_impl(data, len, new_len, 1, NULL, 0);
+ opus_int32 ret;
+ ALLOC_STACK;
+ ret = opus_packet_pad_impl(data, len, new_len, 1, NULL, 0);
+ RESTORE_STACK;
if (ret > 0)
return OPUS_OK;
else