If the packet starts with an END tag, no elemets are decoded and a frame
is never allocated, so we should not return the frame to the user.
---
This updated patch is safer in the rare corner case where there is an
error before getting the frame buffer and there are no bits left in
the bitstream reader.

 libavcodec/alac.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index f972531..1a746a6 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -248,7 +248,7 @@ static void append_extra_bits(int32_t *buffer[2], int32_t 
*extra_bits_buffer[2],
 }
 
 static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
-                          int channels)
+                          int channels, int *got_buffer)
 {
     ALACContext *alac = avctx->priv_data;
     int has_size, bps, is_compressed, decorr_shift, decorr_left_weight, ret;
@@ -287,6 +287,7 @@ static int decode_element(AVCodecContext *avctx, AVFrame 
*frame, int ch_index,
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
+        *got_buffer = 1;
     } else if (output_samples != alac->nb_samples) {
         av_log(avctx, AV_LOG_ERROR, "sample count mismatch: %u != %d\n",
                output_samples, alac->nb_samples);
@@ -402,11 +403,11 @@ static int alac_decode_frame(AVCodecContext *avctx, void 
*data,
     AVFrame *frame    = data;
     enum AlacRawDataBlockType element;
     int channels;
-    int ch, ret, got_end;
+    int ch, ret, got_end, got_buffer, got_element;
 
     init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8);
 
-    got_end = 0;
+    got_end = got_buffer = got_element = 0;
     alac->nb_samples = 0;
     ch = 0;
     while (get_bits_left(&alac->gb) >= 3) {
@@ -429,9 +430,11 @@ static int alac_decode_frame(AVCodecContext *avctx, void 
*data,
 
         ret = decode_element(avctx, frame,
                              ff_alac_channel_layout_offsets[alac->channels - 
1][ch],
-                             channels);
+                             channels, &got_buffer);
         if (ret < 0 && get_bits_left(&alac->gb))
             return ret;
+        if (!ret && got_buffer)
+            got_element = 1;
 
         ch += channels;
     }
@@ -439,6 +442,10 @@ static int alac_decode_frame(AVCodecContext *avctx, void 
*data,
         av_log(avctx, AV_LOG_ERROR, "no end tag found. incomplete packet.\n");
         return AVERROR_INVALIDDATA;
     }
+    if (!got_element) {
+        av_log(avctx, AV_LOG_ERROR, "no audio elements found in packet.\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     if (avpkt->size * 8 - get_bits_count(&alac->gb) > 8) {
         av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n",
-- 
1.8.1.2

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to