]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vorbisdec.c
ra288: return error if input buffer is too small
[ffmpeg] / libavcodec / vorbisdec.c
index c758a440ed7fd971a10de83fe18492a4a31908c2..52c26520e82bd82cb1c0774d4f9384cdd9f69675 100644 (file)
@@ -1,8 +1,4 @@
-/**
- * @file
- * Vorbis I decoder
- * @author Denes Balatoni  ( dbalatoni programozo hu )
- *
+/*
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/**
+ * @file
+ * Vorbis I decoder
+ * @author Denes Balatoni  ( dbalatoni programozo hu )
+ */
+
+#include <inttypes.h>
 #include <math.h>
 
 #define ALT_BITSTREAM_READER_LE
@@ -370,9 +373,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
                     float last = 0.0;
                     unsigned lookup_offset = i;
 
-#ifdef V_DEBUG
-                    av_log(vc->avccontext, AV_LOG_INFO, "Lookup offset %u ,", i);
-#endif
+                    av_dlog(vc->avccontext, "Lookup offset %u ,", i);
 
                     for (k = 0; k < dim; ++k) {
                         unsigned multiplicand_offset = lookup_offset % codebook_lookup_values;
@@ -383,12 +384,11 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
                     }
                     tmp_vlc_bits[j] = tmp_vlc_bits[i];
 
-#ifdef V_DEBUG
-                    av_log(vc->avccontext, AV_LOG_INFO, "real lookup offset %u, vector: ", j);
+                    av_dlog(vc->avccontext, "real lookup offset %u, vector: ", j);
                     for (k = 0; k < dim; ++k)
-                        av_log(vc->avccontext, AV_LOG_INFO, " %f ", codebook_setup->codevectors[j * dim + k]);
-                    av_log(vc->avccontext, AV_LOG_INFO, "\n");
-#endif
+                        av_dlog(vc->avccontext, " %f ",
+                                codebook_setup->codevectors[j * dim + k]);
+                    av_dlog(vc->avccontext, "\n");
 
                     ++j;
                 }
@@ -608,7 +608,6 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
             if (!floor_setup->data.t0.lsp)
                 return -1;
 
-#ifdef V_DEBUG /* debug output parsed headers */
             /* debug output parsed headers */
             av_dlog(NULL, "floor0 order: %u\n", floor_setup->data.t0.order);
             av_dlog(NULL, "floor0 rate: %u\n", floor_setup->data.t0.rate);
@@ -629,7 +628,6 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
                             floor_setup->data.t0.book_list[idx]);
                 }
             }
-#endif
         } else {
             av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n");
             return -1;
@@ -814,11 +812,9 @@ static void create_map(vorbis_context *vc, unsigned floor_number)
         vf->map_size[blockflag] = n;
     }
 
-#ifdef V_DEBUG
     for (idx = 0; idx <= n; ++idx) {
         av_dlog(NULL, "floor0 map: map at pos %d is %d\n", idx, map[idx]);
     }
-#endif
 }
 
 static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
@@ -966,7 +962,7 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
 
 static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
 {
-    vorbis_context *vc = avccontext->priv_data ;
+    vorbis_context *vc = avccontext->priv_data;
     uint8_t *headers   = avccontext->extradata;
     int headers_len    = avccontext->extradata_size;
     uint8_t *header_start[3];
@@ -991,7 +987,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
         return -1;
     }
 
-    if (ff_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) {
+    if (avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) {
         av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
         return -1;
     }
@@ -1030,7 +1026,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
     avccontext->sample_rate = vc->audio_samplerate;
     avccontext->frame_size  = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;
 
-    return 0 ;
+    return 0;
 }
 
 // Decode audiopackets -------------------------------------------------
@@ -1080,14 +1076,12 @@ static int vorbis_floor0_decode(vorbis_context *vc,
 
             lsp_len += codebook.dimensions;
         }
-#ifdef V_DEBUG
         /* DEBUG: output lsp coeffs */
         {
             int idx;
             for (idx = 0; idx < lsp_len; ++idx)
                 av_dlog(NULL, "floor0 dec: coeff at %d is %f\n", idx, lsp[idx]);
         }
-#endif
 
         /* synthesize floor output vector */
         {
@@ -1098,8 +1092,8 @@ static int vorbis_floor0_decode(vorbis_context *vc,
             for (i = 0; i < order; i++)
                 lsp[i] = 2.0f * cos(lsp[i]);
 
-            AV_DEBUG("floor0 synth: map_size = %d; m = %d; wstep = %f\n",
-                     vf->map_size, order, wstep);
+            av_dlog(NULL, "floor0 synth: map_size = %"PRIu32"; m = %d; wstep = %f\n",
+                    vf->map_size[blockflag], order, wstep);
 
             i = 0;
             while (i < vf->map_size[blockflag]) {
@@ -1610,10 +1604,10 @@ static int vorbis_decode_frame(AVCodecContext *avccontext,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    vorbis_context *vc = avccontext->priv_data ;
+    vorbis_context *vc = avccontext->priv_data;
     GetBitContext *gb = &(vc->gb);
     const float *channel_ptrs[255];
-    int i, len;
+    int i, len, out_size;
 
     if (!buf_size)
         return 0;
@@ -1632,12 +1626,19 @@ static int vorbis_decode_frame(AVCodecContext *avccontext,
     if (!vc->first_frame) {
         vc->first_frame = 1;
         *data_size = 0;
-        return buf_size ;
+        return buf_size;
     }
 
     av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n",
             get_bits_count(gb) / 8, get_bits_count(gb) % 8, len);
 
+    out_size = len * vc->audio_channels *
+               av_get_bytes_per_sample(avccontext->sample_fmt);
+    if (*data_size < out_size) {
+        av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+        return AVERROR(EINVAL);
+    }
+
     if (vc->audio_channels > 8) {
         for (i = 0; i < vc->audio_channels; i++)
             channel_ptrs[i] = vc->channel_floors + i * len;
@@ -1653,10 +1654,9 @@ static int vorbis_decode_frame(AVCodecContext *avccontext,
         vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len,
                                                vc->audio_channels);
 
-    *data_size = len * vc->audio_channels *
-                 (av_get_bits_per_sample_fmt(avccontext->sample_fmt) / 8);
+    *data_size = out_size;
 
-    return buf_size ;
+    return buf_size;
 }
 
 // Close decoder
@@ -1667,18 +1667,17 @@ static av_cold int vorbis_decode_close(AVCodecContext *avccontext)
 
     vorbis_free(vc);
 
-    return 0 ;
+    return 0;
 }
 
 AVCodec ff_vorbis_decoder = {
-    "vorbis",
-    AVMEDIA_TYPE_AUDIO,
-    CODEC_ID_VORBIS,
-    sizeof(vorbis_context),
-    vorbis_decode_init,
-    NULL,
-    vorbis_decode_close,
-    vorbis_decode_frame,
+    .name           = "vorbis",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = CODEC_ID_VORBIS,
+    .priv_data_size = sizeof(vorbis_context),
+    .init           = vorbis_decode_init,
+    .close          = vorbis_decode_close,
+    .decode         = vorbis_decode_frame,
     .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
     .channel_layouts = ff_vorbis_channel_layouts,
     .sample_fmts = (const enum AVSampleFormat[]) {