]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dcadec.c
lavf: move TLS-related ifdeffery to library specific files
[ffmpeg] / libavcodec / dcadec.c
index bd534261b7ab40eb7f903e5ee40486ae800f613e..3ea1bcfc9ded283be5e937fc8d9149e296e2ed0c 100644 (file)
@@ -229,6 +229,14 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel,
     }
 
     nchans = get_bits(&s->gb, 3) + 1;
+    if (xxch && nchans >= 3) {
+        av_log(s->avctx, AV_LOG_ERROR, "nchans %d is too large\n", nchans);
+        return AVERROR_INVALIDDATA;
+    } else if (nchans + base_channel > DCA_PRIM_CHANNELS_MAX) {
+        av_log(s->avctx, AV_LOG_ERROR, "channel sum %d + %d is too large\n", nchans, base_channel);
+        return AVERROR_INVALIDDATA;
+    }
+
     s->total_channels = nchans + base_channel;
     s->prim_channels  = s->total_channels;
 
@@ -429,6 +437,10 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index)
 
     if (!base_channel) {
         s->subsubframes[s->current_subframe]    = get_bits(&s->gb, 2) + 1;
+        if (block_index + s->subsubframes[s->current_subframe] > s->sample_blocks/8) {
+            s->subsubframes[s->current_subframe] = 1;
+            return AVERROR_INVALIDDATA;
+        }
         s->partial_samples[s->current_subframe] = get_bits(&s->gb, 3);
     }
 
@@ -1230,8 +1242,13 @@ int ff_dca_xbr_parse_frame(DCAContext *s)
     for(i = 0; i < num_chsets; i++) {
         n_xbr_ch[i] = get_bits(&s->gb, 3) + 1;
         k = get_bits(&s->gb, 2) + 5;
-        for(j = 0; j < n_xbr_ch[i]; j++)
+        for(j = 0; j < n_xbr_ch[i]; j++) {
             active_bands[i][j] = get_bits(&s->gb, k) + 1;
+            if (active_bands[i][j] > DCA_SUBBANDS) {
+                av_log(s->avctx, AV_LOG_ERROR, "too many active subbands (%d)\n", active_bands[i][j]);
+                return AVERROR_INVALIDDATA;
+            }
+        }
     }
 
     /* skip to the end of the header */
@@ -1273,23 +1290,34 @@ int ff_dca_xbr_parse_frame(DCAContext *s)
                 for(i = 0; i < n_xbr_ch[chset]; i++) {
                     const uint32_t *scale_table;
                     int nbits;
+                    int scale_table_size;
 
                     if (s->scalefactor_huffman[chan_base+i] == 6) {
                         scale_table = ff_dca_scale_factor_quant7;
+                        scale_table_size = FF_ARRAY_ELEMS(ff_dca_scale_factor_quant7);
                     } else {
                         scale_table = ff_dca_scale_factor_quant6;
+                        scale_table_size = FF_ARRAY_ELEMS(ff_dca_scale_factor_quant6);
                     }
 
                     nbits = anctemp[i];
 
                     for(j = 0; j < active_bands[chset][i]; j++) {
                         if(abits_high[i][j] > 0) {
-                            scale_table_high[i][j][0] =
-                                scale_table[get_bits(&s->gb, nbits)];
+                            int index = get_bits(&s->gb, nbits);
+                            if (index >= scale_table_size) {
+                                av_log(s->avctx, AV_LOG_ERROR, "scale table index %d invalid\n", index);
+                                return AVERROR_INVALIDDATA;
+                            }
+                            scale_table_high[i][j][0] = scale_table[index];
 
                             if(xbr_tmode && s->transition_mode[i][j]) {
-                                scale_table_high[i][j][1] =
-                                    scale_table[get_bits(&s->gb, nbits)];
+                                int index = get_bits(&s->gb, nbits);
+                                if (index >= scale_table_size) {
+                                    av_log(s->avctx, AV_LOG_ERROR, "scale table index %d invalid\n", index);
+                                    return AVERROR_INVALIDDATA;
+                                }
+                                scale_table_high[i][j][1] = scale_table[index];
                             }
                         }
                     }
@@ -1459,8 +1487,11 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     s->exss_ext_mask = 0;
     s->xch_present   = 0;
 
-    s->dca_buffer_size = avpriv_dca_convert_bitstream(buf, buf_size, s->dca_buffer,
-                                                  DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
+    s->dca_buffer_size = AVERROR_INVALIDDATA;
+    for (i = 0; i < buf_size - 3 && s->dca_buffer_size == AVERROR_INVALIDDATA; i++)
+        s->dca_buffer_size = avpriv_dca_convert_bitstream(buf + i, buf_size - i, s->dca_buffer,
+                                                          DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
+
     if (s->dca_buffer_size == AVERROR_INVALIDDATA) {
         av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");
         return AVERROR_INVALIDDATA;