comparison apedec.c @ 6443:e3adb7e96812 libavcodec

Detect and prevent reading over the end of counts_*. We pass the error through a context variable as this is simpler and i think also faster, but the return value of functions could be used instead of course. The code also ensures as a side effect that the AC decoder state does not become invalid. This fixes all known crashes. And outputs nothing in case of an error instead of random noise.
author michael
date Tue, 04 Mar 2008 21:58:34 +0000
parents 28e45bf84973
children 3572cc5bc8ff
comparison
equal deleted inserted replaced
6442:28e45bf84973 6443:e3adb7e96812
154 154
155 uint8_t *data; ///< current frame data 155 uint8_t *data; ///< current frame data
156 uint8_t *data_end; ///< frame data end 156 uint8_t *data_end; ///< frame data end
157 const uint8_t *ptr; ///< current position in frame data 157 const uint8_t *ptr; ///< current position in frame data
158 const uint8_t *last_ptr; ///< position where last 4608-sample block ended 158 const uint8_t *last_ptr; ///< position where last 4608-sample block ended
159
160 int error;
159 } APEContext; 161 } APEContext;
160 162
161 // TODO: dsputilize 163 // TODO: dsputilize
162 static inline void vector_add(int16_t * v1, int16_t * v2, int order) 164 static inline void vector_add(int16_t * v1, int16_t * v2, int order)
163 { 165 {
380 { 382 {
381 int symbol, cf; 383 int symbol, cf;
382 384
383 cf = range_decode_culshift(ctx, 16); 385 cf = range_decode_culshift(ctx, 16);
384 386
387 if(cf > 65492){
388 symbol= cf - 65535 + 63;
389 range_decode_update(ctx, 1, cf);
390 if(cf > 65535)
391 ctx->error=1;
392 return symbol;
393 }
385 /* figure out the symbol inefficiently; a binary search would be much better */ 394 /* figure out the symbol inefficiently; a binary search would be much better */
386 for (symbol = 0; counts[symbol + 1] <= cf; symbol++); 395 for (symbol = 0; counts[symbol + 1] <= cf; symbol++);
387 396
388 range_decode_update(ctx, counts_diff[symbol], counts[symbol]); 397 range_decode_update(ctx, counts_diff[symbol], counts[symbol]);
389 398
892 } 901 }
893 902
894 nblocks = s->samples; 903 nblocks = s->samples;
895 blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks); 904 blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);
896 905
906 s->error=0;
907
897 if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) 908 if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO))
898 ape_unpack_mono(s, blockstodecode); 909 ape_unpack_mono(s, blockstodecode);
899 else 910 else
900 ape_unpack_stereo(s, blockstodecode); 911 ape_unpack_stereo(s, blockstodecode);
912
913 if(s->error || s->ptr > s->data_end){
914 s->samples=0;
915 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
916 return -1;
917 }
901 918
902 for (i = 0; i < blockstodecode; i++) { 919 for (i = 0; i < blockstodecode; i++) {
903 *samples++ = s->decoded0[i]; 920 *samples++ = s->decoded0[i];
904 if(s->channels == 2) 921 if(s->channels == 2)
905 *samples++ = s->decoded1[i]; 922 *samples++ = s->decoded1[i];