alac: check for truncated packets
authorJustin Ruggles <justin.ruggles@gmail.com>
Fri, 20 Jul 2012 00:04:40 +0000 (20:04 -0400)
committerJustin Ruggles <justin.ruggles@gmail.com>
Fri, 27 Jul 2012 17:52:20 +0000 (13:52 -0400)
This will give a clearer error message when the error is caused by a
truncated packet.

libavcodec/alac.c

index 1756cdf..61d2e70 100644 (file)
@@ -432,16 +432,19 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
     ALACContext *alac = avctx->priv_data;
     enum RawDataBlockType element;
     int channels;
-    int ch, ret;
+    int ch, ret, got_end;
 
     init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8);
 
+    got_end = 0;
     alac->nb_samples = 0;
     ch = 0;
-    while (get_bits_left(&alac->gb)) {
+    while (get_bits_left(&alac->gb) >= 3) {
         element = get_bits(&alac->gb, 3);
-        if (element == TYPE_END)
+        if (element == TYPE_END) {
+            got_end = 1;
             break;
+        }
         if (element > TYPE_CPE && element != TYPE_LFE) {
             av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d", element);
             return AVERROR_PATCHWELCOME;
@@ -456,11 +459,15 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
         ret = decode_element(avctx, data,
                              alac_channel_layout_offsets[alac->channels - 1][ch],
                              channels);
-        if (ret < 0)
+        if (ret < 0 && get_bits_left(&alac->gb))
             return ret;
 
         ch += channels;
     }
+    if (!got_end) {
+        av_log(avctx, AV_LOG_ERROR, "no end tag found. incomplete 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",