]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/cfhd.c
Merge commit '29c2d06d67724e994980045afa055c6c34611b30'
[ffmpeg] / libavcodec / cfhd.c
index 115081c68e99a3f13b75313dd72fc0a6870bbe4d..5c15d9bb0487349852c91331c02eea11922d20bd 100644 (file)
@@ -224,7 +224,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
     GetByteContext gb;
     ThreadFrame frame = { .f = data };
     AVFrame *pic = data;
-    int ret = 0, i, j, plane;
+    int ret = 0, i, j, plane, got_buffer = 0;
     int16_t *coeff_data;
 
     avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
@@ -280,7 +280,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
                 s->level++;
             av_log(avctx, AV_LOG_DEBUG, "Subband number %"PRIu16"\n", data);
             s->subband_num = data;
-            if (s->level > DWT_LEVELS) {
+            if (s->level >= DWT_LEVELS) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid level\n");
                 ret = AVERROR(EINVAL);
                 break;
@@ -312,7 +312,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
             s->plane[s->channel_num].band[0][0].width  = data;
             s->plane[s->channel_num].band[0][0].stride = data;
             av_log(avctx, AV_LOG_DEBUG, "Lowpass width %"PRIu16"\n", data);
-            if (data < 2 || (data & 1) || data > s->plane[s->channel_num].band[0][0].a_width) {
+            if (data < 2 || data > s->plane[s->channel_num].band[0][0].a_width) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid lowpass width\n");
                 ret = AVERROR(EINVAL);
                 break;
@@ -344,6 +344,11 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
             break;
         } else if (tag == 2) {
             av_log(avctx, AV_LOG_DEBUG, "tag=2 header - skipping %i tag/value pairs\n", data);
+            if (data > bytestream2_get_bytes_left(&gb) / 4) {
+                av_log(avctx, AV_LOG_ERROR, "too many tag/value pairs (%d)\n", data);
+                ret = AVERROR_INVALIDDATA;
+                break;
+            }
             for (i = 0; i < data; i++) {
                 uint16_t tag2 = bytestream2_get_be16(&gb);
                 uint16_t val2 = bytestream2_get_be16(&gb);
@@ -353,7 +358,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
             s->plane[s->channel_num].band[s->level][s->subband_num].width  = data;
             s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8);
             av_log(avctx, AV_LOG_DEBUG, "Highpass width %i channel %i level %i subband %i\n", data, s->channel_num, s->level, s->subband_num);
-            if (data < 2 || (data & 1)) {
+            if (data < 2) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid highpass width\n");
                 ret = AVERROR(EINVAL);
                 break;
@@ -370,7 +375,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
             s->plane[s->channel_num].band[s->level][s->subband_num].width  = data;
             s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8);
             av_log(avctx, AV_LOG_DEBUG, "Highpass width2 %i\n", data);
-            if (data < 2 || (data & 1)) {
+            if (data < 2) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid highpass width2\n");
                 ret = AVERROR(EINVAL);
                 break;
@@ -426,6 +431,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
 
             s->coded_width = 0;
             s->coded_height = 0;
+            got_buffer = 1;
         }
         coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual];
 
@@ -557,6 +563,12 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
         goto end;
     }
 
+    if (!got_buffer) {
+        av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n");
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
     for (plane = 0; plane < 3 && !ret; plane++) {
         /* level 1 */
         int lowpass_height  = s->plane[plane].band[0][0].height;