mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
rbcodec: Fix FLAC out of bounds read
Commit 6bcd830490
ported an optimization to decode_subframe_fixed()
from FFmpeg (upstream commit 08965b22e2). This contains an out of
bounds read, which doesn't affect the decoder output, but makes ASAN
complain.
FFmpeg fixed the out of bounds read (upstream commit 0ec7b71de8) but
that appears to increase code size a lot.
Inlining the initialization of a, b, c, d into the switch produces
similar code as the non-bounds-checked version with only a handful
of instructions of overhead (checked on MIPS & ARM).
Change-Id: I053fac4efc4676b133eb7545c80e23f37fb00d86
This commit is contained in:
parent
67cb2e3cdc
commit
56442f6b7f
1 changed files with 12 additions and 7 deletions
|
@ -182,8 +182,8 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps) ICODE_ATTR_FLAC;
|
//static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps) ICODE_ATTR_FLAC;
|
||||||
static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps)
|
int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps)
|
||||||
{
|
{
|
||||||
const int blocksize = s->blocksize;
|
const int blocksize = s->blocksize;
|
||||||
unsigned a, b, c, d;
|
unsigned a, b, c, d;
|
||||||
|
@ -198,28 +198,33 @@ static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_orde
|
||||||
if (decode_residuals(s, decoded, pred_order) < 0)
|
if (decode_residuals(s, decoded, pred_order) < 0)
|
||||||
return -4;
|
return -4;
|
||||||
|
|
||||||
a = decoded[pred_order-1];
|
|
||||||
b = a - decoded[pred_order-2];
|
|
||||||
c = b - decoded[pred_order-2] + decoded[pred_order-3];
|
|
||||||
d = c - decoded[pred_order-2] + 2U*decoded[pred_order-3] - decoded[pred_order-4];
|
|
||||||
|
|
||||||
switch(pred_order)
|
switch(pred_order)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
a = decoded[pred_order-1];
|
||||||
for (i = pred_order; i < blocksize; i++)
|
for (i = pred_order; i < blocksize; i++)
|
||||||
decoded[i] = a += decoded[i];
|
decoded[i] = a += decoded[i];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
a = decoded[pred_order-1];
|
||||||
|
b = a - decoded[pred_order-2];
|
||||||
for (i = pred_order; i < blocksize; i++)
|
for (i = pred_order; i < blocksize; i++)
|
||||||
decoded[i] = a += b += decoded[i];
|
decoded[i] = a += b += decoded[i];
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
a = decoded[pred_order-1];
|
||||||
|
b = a - decoded[pred_order-2];
|
||||||
|
c = b - decoded[pred_order-2] + decoded[pred_order-3];
|
||||||
for (i = pred_order; i < blocksize; i++)
|
for (i = pred_order; i < blocksize; i++)
|
||||||
decoded[i] = a += b += c += decoded[i];
|
decoded[i] = a += b += c += decoded[i];
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
a = decoded[pred_order-1];
|
||||||
|
b = a - decoded[pred_order-2];
|
||||||
|
c = b - decoded[pred_order-2] + decoded[pred_order-3];
|
||||||
|
d = c - decoded[pred_order-2] + 2U*decoded[pred_order-3] - decoded[pred_order-4];
|
||||||
for (i = pred_order; i < blocksize; i++)
|
for (i = pred_order; i < blocksize; i++)
|
||||||
decoded[i] = a += b += c += d += decoded[i];
|
decoded[i] = a += b += c += d += decoded[i];
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue