To avoid crash caused by an unbound LPC decoding when predictor order is
larger than blocksize, the sanity check needs to be moved to the subframe
decoding functions.
---
 src/libFLAC/stream_decoder.c | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c
index d13b23b..211b4db 100644
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -1281,9 +1281,6 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, 
unsigned size, unsigne
        unsigned i;
        FLAC__int32 *tmp;
 
-       /* Make sure size is some sensible minimum value. Plumb through 
predictor_order maybe? */
-       size = size < FLAC__MAX_LPC_ORDER ? FLAC__MAX_LPC_ORDER : size ;
-
        if(size <= decoder->private_->output_capacity && channels <= 
decoder->private_->output_channels)
                return true;
 
@@ -2594,6 +2591,11 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder 
*decoder, unsigned channel,
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
                        
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, 
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
                                return false; /* read_callback_ sets the state 
for us */
+                       if(decoder->private_->frame.header.blocksize >> u32 < 
order) {
+                               send_error_to_client_(decoder, 
FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
+                               decoder->protected_->state = 
FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+                               return true;
+                       }
                        
subframe->entropy_coding_method.data.partitioned_rice.order = u32;
                        
subframe->entropy_coding_method.data.partitioned_rice.contents = 
&decoder->private_->partitioned_rice_contents[channel];
                        break;
@@ -2673,6 +2675,11 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder 
*decoder, unsigned channel, un
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
                        
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, 
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
                                return false; /* read_callback_ sets the state 
for us */
+                       if(decoder->private_->frame.header.blocksize >> u32 < 
order) {
+                               send_error_to_client_(decoder, 
FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
+                               decoder->protected_->state = 
FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+                               return true;
+                       }
                        
subframe->entropy_coding_method.data.partitioned_rice.order = u32;
                        
subframe->entropy_coding_method.data.partitioned_rice.contents = 
&decoder->private_->partitioned_rice_contents[channel];
                        break;
@@ -2744,21 +2751,8 @@ FLAC__bool 
read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
        const unsigned plen = is_extended? 
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : 
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
        const unsigned pesc = is_extended? 
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : 
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
 
-       /* sanity checks */
-       if(partition_order == 0) {
-               if(decoder->private_->frame.header.blocksize < predictor_order) 
{
-                       send_error_to_client_(decoder, 
FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
-                       decoder->protected_->state = 
FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
-                       return true;
-               }
-       }
-       else {
-               if(partition_samples < predictor_order) {
-                       send_error_to_client_(decoder, 
FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
-                       decoder->protected_->state = 
FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
-                       return true;
-               }
-       }
+       /* invalid predictor and partition orders mush be handled in the 
callers */
+       FLAC__ASSERT(partition_order > 0? partition_samples >= predictor_order 
: decoder->private_->frame.header.blocksize >= predictor_order);
 
        
if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents,
 flac_max(6u, partition_order))) {
                decoder->protected_->state = 
FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
-- 
1.9.3

_______________________________________________
flac-dev mailing list
flac-dev@xiph.org
http://lists.xiph.org/mailman/listinfo/flac-dev

Reply via email to