Merge commit '5c54fc6195e52c329b88cf5a56d18628f0ee0029' into release/1.1
* commit '5c54fc6195e52c329b88cf5a56d18628f0ee0029': Prepare for 9.8 RELEASE update Changelog smacker: check frame size validity smacker: pad the extradata allocation smacker: check the return value of smacker_decode_tree smacker: fix an off by one in huff.length computation 4xm: do not overread the prestream buffer 4xm: validate the buffer size before parsing it 4xm: reject frames not compatible with the declared version 4xm: drop pointless assert 4xm: forward errors from decode_p_block 4xm: fold last_picture lazy allocation in decode_p_frame 4xm: do not overread while parsing header 4xm: refactor fourxm_read_header 4xm: K&R formatting cosmetics 4xm: use the correct logging context Conflicts: Changelog RELEASE libavcodec/4xm.c libavcodec/smacker.c libavformat/4xm.c libavformat/smacker.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
							
								
								
									
										21
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								Changelog
									
									
									
									
									
								
							@@ -2,6 +2,27 @@ Entries are sorted chronologically from oldest to youngest within each release,
 | 
				
			|||||||
releases are sorted from youngest to oldest.
 | 
					releases are sorted from youngest to oldest.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
version <next>:
 | 
					version <next>:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Most of the following fixes resulted from test samples that the Google
 | 
				
			||||||
 | 
					Security Team has kindly made available to us:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 4xm: fix several programming errors to avoid crashes, etc.
 | 
				
			||||||
 | 
					- apetag: use int64_t for filesize
 | 
				
			||||||
 | 
					- jpegls: Fix invalid writes to memory
 | 
				
			||||||
 | 
					- ljpeg: use the correct number of components in YUV
 | 
				
			||||||
 | 
					- mjpeg: Validate sampling factors
 | 
				
			||||||
 | 
					- mjpegdec: properly report unsupported disabled features
 | 
				
			||||||
 | 
					- mjpegdec: validate parameters in mjpeg_decode_scan_progressive_ac
 | 
				
			||||||
 | 
					- mpegvideo: allocate sufficiently large scratch buffer for interlaced vid
 | 
				
			||||||
 | 
					- pixdesc: mark gray8 as pseudopal
 | 
				
			||||||
 | 
					- smacker: fix several programming errors to avoid crashes, etc.
 | 
				
			||||||
 | 
					- tiff: do not overread the source buffer
 | 
				
			||||||
 | 
					- vmd: drop incomplete chunks and spurious samples
 | 
				
			||||||
 | 
					- vmdav: convert to bytestream2 to avoid invalid reads and writes
 | 
				
			||||||
 | 
					- wavpack: check packet size early
 | 
				
			||||||
 | 
					- wavpack: use bytestream2 in wavpack_decode_block
 | 
				
			||||||
 | 
					- wavpack: validate samples size parsed in wavpack_decode_block
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- aac: check the maximum number of channels to avoid invalid writes
 | 
					- aac: check the maximum number of channels to avoid invalid writes
 | 
				
			||||||
- indeo3: fix off by one in MV validity check
 | 
					- indeo3: fix off by one in MV validity check
 | 
				
			||||||
- id3v2: check for end of file while unescaping tags to avoid invalid
 | 
					- id3v2: check for end of file while unescaping tags to avoid invalid
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										112
									
								
								libavcodec/4xm.c
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								libavcodec/4xm.c
									
									
									
									
									
								
							@@ -328,12 +328,12 @@ static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        av_assert2(0);
 | 
					        av_assert0(0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
 | 
					static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
 | 
				
			||||||
                           int log2w, int log2h, int stride)
 | 
					                          int log2w, int log2h, int stride)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const int index = size2index[log2h][log2w];
 | 
					    const int index = size2index[log2h][log2w];
 | 
				
			||||||
    const int h     = 1 << log2h;
 | 
					    const int h     = 1 << log2h;
 | 
				
			||||||
@@ -342,57 +342,64 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
 | 
				
			|||||||
                               BLOCK_TYPE_VLC_BITS, 1);
 | 
					                               BLOCK_TYPE_VLC_BITS, 1);
 | 
				
			||||||
    uint16_t *start = (uint16_t *)f->last_picture.data[0];
 | 
					    uint16_t *start = (uint16_t *)f->last_picture.data[0];
 | 
				
			||||||
    uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
 | 
					    uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    av_assert2(code >= 0 && code <= 6);
 | 
					    av_assert0(code >= 0 && code <= 6 && log2w >= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (code == 0) {
 | 
					    if (code == 0) {
 | 
				
			||||||
        if (bytestream2_get_bytes_left(&f->g) < 1) {
 | 
					        if (bytestream2_get_bytes_left(&f->g) < 1) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        src += f->mv[bytestream2_get_byteu(&f->g)];
 | 
					        src += f->mv[bytestream2_get_byteu(&f->g)];
 | 
				
			||||||
        if (start > src || src > end) {
 | 
					        if (start > src || src > end) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mcdc(dst, src, log2w, h, stride, 1, 0);
 | 
					        mcdc(dst, src, log2w, h, stride, 1, 0);
 | 
				
			||||||
    } else if (code == 1) {
 | 
					    } else if (code == 1) {
 | 
				
			||||||
        log2h--;
 | 
					        log2h--;
 | 
				
			||||||
        decode_p_block(f, dst, src, log2w, log2h, stride);
 | 
					        if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
 | 
				
			||||||
        decode_p_block(f, dst + (stride << log2h),
 | 
					            return ret;
 | 
				
			||||||
                          src + (stride << log2h), log2w, log2h, stride);
 | 
					        if ((ret = decode_p_block(f, dst + (stride << log2h),
 | 
				
			||||||
 | 
					                                  src + (stride << log2h),
 | 
				
			||||||
 | 
					                                  log2w, log2h, stride)) < 0)
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
    } else if (code == 2) {
 | 
					    } else if (code == 2) {
 | 
				
			||||||
        log2w--;
 | 
					        log2w--;
 | 
				
			||||||
        decode_p_block(f, dst , src, log2w, log2h, stride);
 | 
					        if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
 | 
				
			||||||
        decode_p_block(f, dst + (1 << log2w),
 | 
					            return ret;
 | 
				
			||||||
                          src + (1 << log2w), log2w, log2h, stride);
 | 
					        if ((ret = decode_p_block(f, dst + (1 << log2w),
 | 
				
			||||||
 | 
					                                  src + (1 << log2w),
 | 
				
			||||||
 | 
					                                  log2w, log2h, stride)) < 0)
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
    } else if (code == 3 && f->version < 2) {
 | 
					    } else if (code == 3 && f->version < 2) {
 | 
				
			||||||
        mcdc(dst, src, log2w, h, stride, 1, 0);
 | 
					        mcdc(dst, src, log2w, h, stride, 1, 0);
 | 
				
			||||||
    } else if (code == 4) {
 | 
					    } else if (code == 4) {
 | 
				
			||||||
        if (bytestream2_get_bytes_left(&f->g) < 1) {
 | 
					        if (bytestream2_get_bytes_left(&f->g) < 1) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        src += f->mv[bytestream2_get_byteu(&f->g)];
 | 
					        src += f->mv[bytestream2_get_byteu(&f->g)];
 | 
				
			||||||
        if (start > src || src > end) {
 | 
					        if (start > src || src > end) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (bytestream2_get_bytes_left(&f->g2) < 2){
 | 
					        if (bytestream2_get_bytes_left(&f->g2) < 2){
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
 | 
					        mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
 | 
				
			||||||
    } else if (code == 5) {
 | 
					    } else if (code == 5) {
 | 
				
			||||||
        if (bytestream2_get_bytes_left(&f->g2) < 2) {
 | 
					        if (bytestream2_get_bytes_left(&f->g2) < 2) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
 | 
					        mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
 | 
				
			||||||
    } else if (code == 6) {
 | 
					    } else if (code == 6) {
 | 
				
			||||||
        if (bytestream2_get_bytes_left(&f->g2) < 4) {
 | 
					        if (bytestream2_get_bytes_left(&f->g2) < 4) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
 | 
				
			||||||
            return;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (log2w) {
 | 
					        if (log2w) {
 | 
				
			||||||
            dst[0]      = bytestream2_get_le16u(&f->g2);
 | 
					            dst[0]      = bytestream2_get_le16u(&f->g2);
 | 
				
			||||||
@@ -402,6 +409,7 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
 | 
				
			|||||||
            dst[stride] = bytestream2_get_le16u(&f->g2);
 | 
					            dst[stride] = bytestream2_get_le16u(&f->g2);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
 | 
					static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
 | 
				
			||||||
@@ -414,8 +422,20 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
 | 
				
			|||||||
    const int stride =             f->current_picture.linesize[0] >> 1;
 | 
					    const int stride =             f->current_picture.linesize[0] >> 1;
 | 
				
			||||||
    unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
 | 
					    unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
 | 
				
			||||||
                 bytestream_offset, wordstream_offset;
 | 
					                 bytestream_offset, wordstream_offset;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!f->last_picture.data[0]) {
 | 
				
			||||||
 | 
					        if ((ret = ff_get_buffer(f->avctx, &f->last_picture)) < 0) {
 | 
				
			||||||
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (y=0; y<f->avctx->height; y++)
 | 
				
			||||||
 | 
					            memset(f->last_picture.data[0] + y*f->last_picture.linesize[0], 0, 2*f->avctx->width);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (f->version > 1) {
 | 
					    if (f->version > 1) {
 | 
				
			||||||
 | 
					        if (length < 20)
 | 
				
			||||||
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        extra           = 20;
 | 
					        extra           = 20;
 | 
				
			||||||
        if (length < extra)
 | 
					        if (length < extra)
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
@@ -459,7 +479,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for (y = 0; y < height; y += 8) {
 | 
					    for (y = 0; y < height; y += 8) {
 | 
				
			||||||
        for (x = 0; x < width; x += 8)
 | 
					        for (x = 0; x < width; x += 8)
 | 
				
			||||||
            decode_p_block(f, dst + x, src + x, 3, 3, stride);
 | 
					            if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0)
 | 
				
			||||||
 | 
					                return ret;
 | 
				
			||||||
        src += 8 * stride;
 | 
					        src += 8 * stride;
 | 
				
			||||||
        dst += 8 * stride;
 | 
					        dst += 8 * stride;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -579,7 +600,8 @@ static int decode_i_mb(FourXContext *f)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const uint8_t *read_huffman_tables(FourXContext *f,
 | 
					static const uint8_t *read_huffman_tables(FourXContext *f,
 | 
				
			||||||
                                          const uint8_t * const buf, int buf_size)
 | 
					                                          const uint8_t * const buf,
 | 
				
			||||||
 | 
					                                          int buf_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int frequency[512] = { 0 };
 | 
					    int frequency[512] = { 0 };
 | 
				
			||||||
    uint8_t flag[512];
 | 
					    uint8_t flag[512];
 | 
				
			||||||
@@ -598,8 +620,11 @@ static const uint8_t *read_huffman_tables(FourXContext *f,
 | 
				
			|||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
        int i;
 | 
					        int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (start <= end && ptr_end - ptr < end - start + 1 + 1)
 | 
					        if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) {
 | 
				
			||||||
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n");
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = start; i <= end; i++)
 | 
					        for (i = start; i <= end; i++)
 | 
				
			||||||
            frequency[i] = *ptr++;
 | 
					            frequency[i] = *ptr++;
 | 
				
			||||||
        start = *ptr++;
 | 
					        start = *ptr++;
 | 
				
			||||||
@@ -701,9 +726,9 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
 | 
				
			|||||||
            color[1] = bytestream2_get_le16u(&g3);
 | 
					            color[1] = bytestream2_get_le16u(&g3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (color[0] & 0x8000)
 | 
					            if (color[0] & 0x8000)
 | 
				
			||||||
                av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
 | 
					                av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
 | 
				
			||||||
            if (color[1] & 0x8000)
 | 
					            if (color[1] & 0x8000)
 | 
				
			||||||
                av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
 | 
					                av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            color[2] = mix(color[0], color[1]);
 | 
					            color[2] = mix(color[0], color[1]);
 | 
				
			||||||
            color[3] = mix(color[1], color[0]);
 | 
					            color[3] = mix(color[1], color[0]);
 | 
				
			||||||
@@ -748,7 +773,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
 | 
				
			|||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prestream = read_huffman_tables(f, prestream, buf + length - prestream);
 | 
					    prestream = read_huffman_tables(f, prestream, prestream_size);
 | 
				
			||||||
    if (!prestream) {
 | 
					    if (!prestream) {
 | 
				
			||||||
        av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
 | 
					        av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
 | 
				
			||||||
        return AVERROR_INVALIDDATA;
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
@@ -795,30 +820,38 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 | 
				
			|||||||
    AVFrame *p, temp;
 | 
					    AVFrame *p, temp;
 | 
				
			||||||
    int i, frame_4cc, frame_size;
 | 
					    int i, frame_4cc, frame_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (buf_size < 12)
 | 
					    if (buf_size < 20)
 | 
				
			||||||
        return AVERROR_INVALIDDATA;
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
    frame_4cc = AV_RL32(buf);
 | 
					
 | 
				
			||||||
    if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20)
 | 
					    av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (buf_size < AV_RL32(buf + 4) + 8) {
 | 
				
			||||||
        av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
 | 
					        av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
 | 
				
			||||||
               buf_size, AV_RL32(buf + 4));
 | 
					               buf_size, AV_RL32(buf + 4));
 | 
				
			||||||
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    frame_4cc = AV_RL32(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (frame_4cc == AV_RL32("cfrm")) {
 | 
					    if (frame_4cc == AV_RL32("cfrm")) {
 | 
				
			||||||
        int free_index       = -1;
 | 
					        int free_index       = -1;
 | 
				
			||||||
 | 
					        int id, whole_size;
 | 
				
			||||||
        const int data_size  = buf_size - 20;
 | 
					        const int data_size  = buf_size - 20;
 | 
				
			||||||
        const int id         = AV_RL32(buf + 12);
 | 
					 | 
				
			||||||
        const int whole_size = AV_RL32(buf + 16);
 | 
					 | 
				
			||||||
        CFrameBuffer *cfrm;
 | 
					        CFrameBuffer *cfrm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (data_size < 0 || whole_size < 0) {
 | 
					 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
 | 
					 | 
				
			||||||
            return AVERROR_INVALIDDATA;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (f->version <= 1) {
 | 
					        if (f->version <= 1) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
 | 
				
			||||||
            return AVERROR_INVALIDDATA;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        id         = AV_RL32(buf + 12);
 | 
				
			||||||
 | 
					        whole_size = AV_RL32(buf + 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (data_size < 0 || whole_size < 0) {
 | 
				
			||||||
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
 | 
				
			||||||
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
 | 
					        for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
 | 
				
			||||||
            if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
 | 
					            if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
 | 
				
			||||||
                av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
 | 
					                av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
 | 
				
			||||||
@@ -859,6 +892,9 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 | 
				
			|||||||
                av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
 | 
					                av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
 | 
				
			||||||
                       id, avctx->frame_number);
 | 
					                       id, avctx->frame_number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (f->version <= 1)
 | 
				
			||||||
 | 
					                return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cfrm->size = cfrm->id = 0;
 | 
					            cfrm->size = cfrm->id = 0;
 | 
				
			||||||
            frame_4cc  = AV_RL32("pfrm");
 | 
					            frame_4cc  = AV_RL32("pfrm");
 | 
				
			||||||
        } else
 | 
					        } else
 | 
				
			||||||
@@ -897,16 +933,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 | 
				
			|||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
 | 
					    } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
 | 
				
			||||||
        if (!f->last_picture.data[0]) {
 | 
					 | 
				
			||||||
            f->last_picture.reference = 3;
 | 
					 | 
				
			||||||
            if (ff_get_buffer(avctx, &f->last_picture) < 0) {
 | 
					 | 
				
			||||||
                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 | 
					 | 
				
			||||||
                return -1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            for (i=0; i<avctx->height; i++)
 | 
					 | 
				
			||||||
                memset(f->last_picture.data[0] + i*f->last_picture.linesize[0], 0, 2*avctx->width);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        p->pict_type = AV_PICTURE_TYPE_P;
 | 
					        p->pict_type = AV_PICTURE_TYPE_P;
 | 
				
			||||||
        if (decode_p_frame(f, buf, frame_size) < 0) {
 | 
					        if (decode_p_frame(f, buf, frame_size) < 0) {
 | 
				
			||||||
            av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
 | 
					            av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -257,7 +257,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
 | 
				
			|||||||
    ctx.recode2 = tmp2.values;
 | 
					    ctx.recode2 = tmp2.values;
 | 
				
			||||||
    ctx.last = last;
 | 
					    ctx.last = last;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    huff.length = ((size + 3) >> 2) + 3;
 | 
					    huff.length = ((size + 3) >> 2) + 4;
 | 
				
			||||||
    huff.maxlength = 0;
 | 
					    huff.maxlength = 0;
 | 
				
			||||||
    huff.current = 0;
 | 
					    huff.current = 0;
 | 
				
			||||||
    huff.values = av_mallocz(huff.length * sizeof(int));
 | 
					    huff.values = av_mallocz(huff.length * sizeof(int));
 | 
				
			||||||
@@ -661,9 +661,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
 | 
				
			|||||||
        h[i].lengths = av_mallocz(256 * sizeof(int));
 | 
					        h[i].lengths = av_mallocz(256 * sizeof(int));
 | 
				
			||||||
        h[i].values = av_mallocz(256 * sizeof(int));
 | 
					        h[i].values = av_mallocz(256 * sizeof(int));
 | 
				
			||||||
        skip_bits1(&gb);
 | 
					        skip_bits1(&gb);
 | 
				
			||||||
        res = smacker_decode_tree(&gb, &h[i], 0, 0);
 | 
					        if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) {
 | 
				
			||||||
        if (res < 0)
 | 
					            for (; i >= 0; i--) {
 | 
				
			||||||
            return res;
 | 
					                if (vlc[i].table)
 | 
				
			||||||
 | 
					                    ff_free_vlc(&vlc[i]);
 | 
				
			||||||
 | 
					                av_free(h[i].bits);
 | 
				
			||||||
 | 
					                av_free(h[i].lengths);
 | 
				
			||||||
 | 
					                av_free(h[i].values);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        skip_bits1(&gb);
 | 
					        skip_bits1(&gb);
 | 
				
			||||||
        if(h[i].current > 1) {
 | 
					        if(h[i].current > 1) {
 | 
				
			||||||
            res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,
 | 
					            res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,7 +57,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define GET_LIST_HEADER() \
 | 
					#define GET_LIST_HEADER() \
 | 
				
			||||||
    fourcc_tag = avio_rl32(pb); \
 | 
					    fourcc_tag = avio_rl32(pb); \
 | 
				
			||||||
    size = avio_rl32(pb); \
 | 
					    size       = avio_rl32(pb); \
 | 
				
			||||||
    if (fourcc_tag != LIST_TAG) \
 | 
					    if (fourcc_tag != LIST_TAG) \
 | 
				
			||||||
        return AVERROR_INVALIDDATA; \
 | 
					        return AVERROR_INVALIDDATA; \
 | 
				
			||||||
    fourcc_tag = avio_rl32(pb);
 | 
					    fourcc_tag = avio_rl32(pb);
 | 
				
			||||||
@@ -72,8 +72,6 @@ typedef struct AudioTrack {
 | 
				
			|||||||
} AudioTrack;
 | 
					} AudioTrack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct FourxmDemuxContext {
 | 
					typedef struct FourxmDemuxContext {
 | 
				
			||||||
    int width;
 | 
					 | 
				
			||||||
    int height;
 | 
					 | 
				
			||||||
    int video_stream_index;
 | 
					    int video_stream_index;
 | 
				
			||||||
    int track_count;
 | 
					    int track_count;
 | 
				
			||||||
    AudioTrack *tracks;
 | 
					    AudioTrack *tracks;
 | 
				
			||||||
@@ -91,6 +89,108 @@ static int fourxm_probe(AVProbeData *p)
 | 
				
			|||||||
    return AVPROBE_SCORE_MAX;
 | 
					    return AVPROBE_SCORE_MAX;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int parse_vtrk(AVFormatContext *s,
 | 
				
			||||||
 | 
					                      FourxmDemuxContext *fourxm, uint8_t *buf, int size,
 | 
				
			||||||
 | 
					                      int left)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    AVStream *st;
 | 
				
			||||||
 | 
					    /* check that there is enough data */
 | 
				
			||||||
 | 
					    if (size != vtrk_SIZE || left < size + 8) {
 | 
				
			||||||
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* allocate a new AVStream */
 | 
				
			||||||
 | 
					    st = avformat_new_stream(s, NULL);
 | 
				
			||||||
 | 
					    if (!st)
 | 
				
			||||||
 | 
					        return AVERROR(ENOMEM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    avpriv_set_pts_info(st, 60, 1, fourxm->fps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fourxm->video_stream_index = st->index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    st->codec->codec_type     = AVMEDIA_TYPE_VIDEO;
 | 
				
			||||||
 | 
					    st->codec->codec_id       = AV_CODEC_ID_4XM;
 | 
				
			||||||
 | 
					    st->codec->extradata_size = 4;
 | 
				
			||||||
 | 
					    st->codec->extradata      = av_malloc(4);
 | 
				
			||||||
 | 
					    AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
 | 
				
			||||||
 | 
					    st->codec->width  = AV_RL32(buf + 36);
 | 
				
			||||||
 | 
					    st->codec->height = AV_RL32(buf + 40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int parse_strk(AVFormatContext *s,
 | 
				
			||||||
 | 
					                      FourxmDemuxContext *fourxm, uint8_t *buf, int size,
 | 
				
			||||||
 | 
					                      int left)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    AVStream *st;
 | 
				
			||||||
 | 
					    int track;
 | 
				
			||||||
 | 
					    /* check that there is enough data */
 | 
				
			||||||
 | 
					    if (size != strk_SIZE || left < size + 8)
 | 
				
			||||||
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    track = AV_RL32(buf + 8);
 | 
				
			||||||
 | 
					    if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
 | 
				
			||||||
 | 
					        av_log(s, AV_LOG_ERROR, "current_track too large\n");
 | 
				
			||||||
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (track + 1 > fourxm->track_count) {
 | 
				
			||||||
 | 
					        fourxm->tracks = av_realloc_f(fourxm->tracks, track + 1, sizeof(AudioTrack));
 | 
				
			||||||
 | 
					        if (!fourxm->tracks)
 | 
				
			||||||
 | 
					            return AVERROR(ENOMEM);
 | 
				
			||||||
 | 
					        memset(&fourxm->tracks[fourxm->track_count], 0,
 | 
				
			||||||
 | 
					               sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
 | 
				
			||||||
 | 
					        fourxm->track_count = track + 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fourxm->tracks[track].adpcm       = AV_RL32(buf + 12);
 | 
				
			||||||
 | 
					    fourxm->tracks[track].channels    = AV_RL32(buf + 36);
 | 
				
			||||||
 | 
					    fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
 | 
				
			||||||
 | 
					    fourxm->tracks[track].bits        = AV_RL32(buf + 44);
 | 
				
			||||||
 | 
					    fourxm->tracks[track].audio_pts   = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (fourxm->tracks[track].channels    <= 0 ||
 | 
				
			||||||
 | 
					        fourxm->tracks[track].sample_rate <= 0 ||
 | 
				
			||||||
 | 
					        fourxm->tracks[track].bits        < 0) {
 | 
				
			||||||
 | 
					        av_log(s, AV_LOG_ERROR, "audio header invalid\n");
 | 
				
			||||||
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {
 | 
				
			||||||
 | 
					        av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
 | 
				
			||||||
 | 
					        return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* allocate a new AVStream */
 | 
				
			||||||
 | 
					    st = avformat_new_stream(s, NULL);
 | 
				
			||||||
 | 
					    if (!st)
 | 
				
			||||||
 | 
					        return AVERROR(ENOMEM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    st->id = track;
 | 
				
			||||||
 | 
					    avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fourxm->tracks[track].stream_index = st->index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
 | 
				
			||||||
 | 
					    st->codec->codec_tag             = 0;
 | 
				
			||||||
 | 
					    st->codec->channels              = fourxm->tracks[track].channels;
 | 
				
			||||||
 | 
					    st->codec->sample_rate           = fourxm->tracks[track].sample_rate;
 | 
				
			||||||
 | 
					    st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
 | 
				
			||||||
 | 
					    st->codec->bit_rate              = st->codec->channels *
 | 
				
			||||||
 | 
					                                       st->codec->sample_rate *
 | 
				
			||||||
 | 
					                                       st->codec->bits_per_coded_sample;
 | 
				
			||||||
 | 
					    st->codec->block_align           = st->codec->channels *
 | 
				
			||||||
 | 
					                                       st->codec->bits_per_coded_sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (fourxm->tracks[track].adpcm){
 | 
				
			||||||
 | 
					        st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
 | 
				
			||||||
 | 
					    } else if (st->codec->bits_per_coded_sample == 8) {
 | 
				
			||||||
 | 
					        st->codec->codec_id = AV_CODEC_ID_PCM_U8;
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					        st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fourxm_read_header(AVFormatContext *s)
 | 
					static int fourxm_read_header(AVFormatContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AVIOContext *pb = s->pb;
 | 
					    AVIOContext *pb = s->pb;
 | 
				
			||||||
@@ -100,11 +200,10 @@ static int fourxm_read_header(AVFormatContext *s)
 | 
				
			|||||||
    FourxmDemuxContext *fourxm = s->priv_data;
 | 
					    FourxmDemuxContext *fourxm = s->priv_data;
 | 
				
			||||||
    unsigned char *header;
 | 
					    unsigned char *header;
 | 
				
			||||||
    int i, ret;
 | 
					    int i, ret;
 | 
				
			||||||
    AVStream *st;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fourxm->track_count = 0;
 | 
					    fourxm->track_count = 0;
 | 
				
			||||||
    fourxm->tracks = NULL;
 | 
					    fourxm->tracks      = NULL;
 | 
				
			||||||
    fourxm->fps = 1.0;
 | 
					    fourxm->fps         = 1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* skip the first 3 32-bit numbers */
 | 
					    /* skip the first 3 32-bit numbers */
 | 
				
			||||||
    avio_skip(pb, 12);
 | 
					    avio_skip(pb, 12);
 | 
				
			||||||
@@ -119,7 +218,7 @@ static int fourxm_read_header(AVFormatContext *s)
 | 
				
			|||||||
    header = av_malloc(header_size);
 | 
					    header = av_malloc(header_size);
 | 
				
			||||||
    if (!header)
 | 
					    if (!header)
 | 
				
			||||||
        return AVERROR(ENOMEM);
 | 
					        return AVERROR(ENOMEM);
 | 
				
			||||||
    if (avio_read(pb, header, header_size) != header_size){
 | 
					    if (avio_read(pb, header, header_size) != header_size) {
 | 
				
			||||||
        av_free(header);
 | 
					        av_free(header);
 | 
				
			||||||
        return AVERROR(EIO);
 | 
					        return AVERROR(EIO);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -127,123 +226,38 @@ static int fourxm_read_header(AVFormatContext *s)
 | 
				
			|||||||
    /* take the lazy approach and search for any and all vtrk and strk chunks */
 | 
					    /* take the lazy approach and search for any and all vtrk and strk chunks */
 | 
				
			||||||
    for (i = 0; i < header_size - 8; i++) {
 | 
					    for (i = 0; i < header_size - 8; i++) {
 | 
				
			||||||
        fourcc_tag = AV_RL32(&header[i]);
 | 
					        fourcc_tag = AV_RL32(&header[i]);
 | 
				
			||||||
        size = AV_RL32(&header[i + 4]);
 | 
					        size       = AV_RL32(&header[i + 4]);
 | 
				
			||||||
        if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
 | 
					        if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
 | 
				
			||||||
            av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
 | 
					            av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
 | 
				
			||||||
            return AVERROR_INVALIDDATA;
 | 
					            return AVERROR_INVALIDDATA;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (fourcc_tag == std__TAG) {
 | 
					        if (fourcc_tag == std__TAG) {
 | 
				
			||||||
            if (header_size < i + 16) {
 | 
					            if (header_size - i < 16) {
 | 
				
			||||||
                av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
 | 
					                av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
 | 
				
			||||||
                return AVERROR_INVALIDDATA;
 | 
					                ret = AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					                goto fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
 | 
					            fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
 | 
				
			||||||
        } else if (fourcc_tag == vtrk_TAG) {
 | 
					        } else if (fourcc_tag == vtrk_TAG) {
 | 
				
			||||||
            /* check that there is enough data */
 | 
					            if ((ret = parse_vtrk(s, fourxm, header + i, size,
 | 
				
			||||||
            if (size != vtrk_SIZE) {
 | 
					                                  header_size - i)) < 0)
 | 
				
			||||||
                ret= AVERROR_INVALIDDATA;
 | 
					 | 
				
			||||||
                goto fail;
 | 
					                goto fail;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            fourxm->width  = AV_RL32(&header[i + 36]);
 | 
					 | 
				
			||||||
            fourxm->height = AV_RL32(&header[i + 40]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* allocate a new AVStream */
 | 
					 | 
				
			||||||
            st = avformat_new_stream(s, NULL);
 | 
					 | 
				
			||||||
            if (!st){
 | 
					 | 
				
			||||||
                ret= AVERROR(ENOMEM);
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            avpriv_set_pts_info(st, 60, 1, fourxm->fps);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            fourxm->video_stream_index = st->index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
 | 
					 | 
				
			||||||
            st->codec->codec_id = AV_CODEC_ID_4XM;
 | 
					 | 
				
			||||||
            st->codec->extradata_size = 4;
 | 
					 | 
				
			||||||
            st->codec->extradata = av_malloc(4);
 | 
					 | 
				
			||||||
            AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
 | 
					 | 
				
			||||||
            st->codec->width  = fourxm->width;
 | 
					 | 
				
			||||||
            st->codec->height = fourxm->height;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            i += 8 + size;
 | 
					            i += 8 + size;
 | 
				
			||||||
        } else if (fourcc_tag == strk_TAG) {
 | 
					        } else if (fourcc_tag == strk_TAG) {
 | 
				
			||||||
            int current_track;
 | 
					            if ((ret = parse_strk(s, fourxm, header + i, size,
 | 
				
			||||||
            /* check that there is enough data */
 | 
					                                  header_size - i)) < 0)
 | 
				
			||||||
            if (size != strk_SIZE) {
 | 
					 | 
				
			||||||
                ret= AVERROR_INVALIDDATA;
 | 
					 | 
				
			||||||
                goto fail;
 | 
					                goto fail;
 | 
				
			||||||
            }
 | 
					
 | 
				
			||||||
            current_track = AV_RL32(&header[i + 8]);
 | 
					 | 
				
			||||||
            if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
 | 
					 | 
				
			||||||
                av_log(s, AV_LOG_ERROR, "current_track too large\n");
 | 
					 | 
				
			||||||
                ret = AVERROR_INVALIDDATA;
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (current_track + 1 > fourxm->track_count) {
 | 
					 | 
				
			||||||
                fourxm->tracks = av_realloc_f(fourxm->tracks,
 | 
					 | 
				
			||||||
                                              sizeof(AudioTrack),
 | 
					 | 
				
			||||||
                                              current_track + 1);
 | 
					 | 
				
			||||||
                if (!fourxm->tracks) {
 | 
					 | 
				
			||||||
                    ret = AVERROR(ENOMEM);
 | 
					 | 
				
			||||||
                    goto fail;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                memset(&fourxm->tracks[fourxm->track_count], 0,
 | 
					 | 
				
			||||||
                       sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
 | 
					 | 
				
			||||||
                fourxm->track_count = current_track + 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            fourxm->tracks[current_track].adpcm       = AV_RL32(&header[i + 12]);
 | 
					 | 
				
			||||||
            fourxm->tracks[current_track].channels    = AV_RL32(&header[i + 36]);
 | 
					 | 
				
			||||||
            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
 | 
					 | 
				
			||||||
            fourxm->tracks[current_track].bits        = AV_RL32(&header[i + 44]);
 | 
					 | 
				
			||||||
            fourxm->tracks[current_track].audio_pts   = 0;
 | 
					 | 
				
			||||||
            if(   fourxm->tracks[current_track].channels    <= 0
 | 
					 | 
				
			||||||
               || fourxm->tracks[current_track].sample_rate <= 0
 | 
					 | 
				
			||||||
               || fourxm->tracks[current_track].bits        <  0){
 | 
					 | 
				
			||||||
                av_log(s, AV_LOG_ERROR, "audio header invalid\n");
 | 
					 | 
				
			||||||
                ret = AVERROR_INVALIDDATA;
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
 | 
					 | 
				
			||||||
                av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
 | 
					 | 
				
			||||||
                ret = AVERROR_INVALIDDATA;
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            i += 8 + size;
 | 
					            i += 8 + size;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* allocate a new AVStream */
 | 
					 | 
				
			||||||
            st = avformat_new_stream(s, NULL);
 | 
					 | 
				
			||||||
            if (!st){
 | 
					 | 
				
			||||||
                ret= AVERROR(ENOMEM);
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            st->id = current_track;
 | 
					 | 
				
			||||||
            avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            fourxm->tracks[current_track].stream_index = st->index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
 | 
					 | 
				
			||||||
            st->codec->codec_tag = 0;
 | 
					 | 
				
			||||||
            st->codec->channels              = fourxm->tracks[current_track].channels;
 | 
					 | 
				
			||||||
            st->codec->sample_rate           = fourxm->tracks[current_track].sample_rate;
 | 
					 | 
				
			||||||
            st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
 | 
					 | 
				
			||||||
            st->codec->bit_rate              = st->codec->channels * st->codec->sample_rate *
 | 
					 | 
				
			||||||
                st->codec->bits_per_coded_sample;
 | 
					 | 
				
			||||||
            st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
 | 
					 | 
				
			||||||
            if (fourxm->tracks[current_track].adpcm){
 | 
					 | 
				
			||||||
                st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
 | 
					 | 
				
			||||||
            }else if (st->codec->bits_per_coded_sample == 8){
 | 
					 | 
				
			||||||
                st->codec->codec_id = AV_CODEC_ID_PCM_U8;
 | 
					 | 
				
			||||||
            }else
 | 
					 | 
				
			||||||
                st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* skip over the LIST-MOVI chunk (which is where the stream should be */
 | 
					    /* skip over the LIST-MOVI chunk (which is where the stream should be */
 | 
				
			||||||
    GET_LIST_HEADER();
 | 
					    GET_LIST_HEADER();
 | 
				
			||||||
    if (fourcc_tag != MOVI_TAG){
 | 
					    if (fourcc_tag != MOVI_TAG) {
 | 
				
			||||||
        ret= AVERROR_INVALIDDATA;
 | 
					        ret = AVERROR_INVALIDDATA;
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -262,7 +276,7 @@ static int fourxm_read_packet(AVFormatContext *s,
 | 
				
			|||||||
                              AVPacket *pkt)
 | 
					                              AVPacket *pkt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FourxmDemuxContext *fourxm = s->priv_data;
 | 
					    FourxmDemuxContext *fourxm = s->priv_data;
 | 
				
			||||||
    AVIOContext *pb = s->pb;
 | 
					    AVIOContext *pb            = s->pb;
 | 
				
			||||||
    unsigned int fourcc_tag;
 | 
					    unsigned int fourcc_tag;
 | 
				
			||||||
    unsigned int size;
 | 
					    unsigned int size;
 | 
				
			||||||
    int ret = 0;
 | 
					    int ret = 0;
 | 
				
			||||||
@@ -272,18 +286,16 @@ static int fourxm_read_packet(AVFormatContext *s,
 | 
				
			|||||||
    int audio_frame_count;
 | 
					    int audio_frame_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (!packet_read) {
 | 
					    while (!packet_read) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ((ret = avio_read(s->pb, header, 8)) < 0)
 | 
					        if ((ret = avio_read(s->pb, header, 8)) < 0)
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
        fourcc_tag = AV_RL32(&header[0]);
 | 
					        fourcc_tag = AV_RL32(&header[0]);
 | 
				
			||||||
        size = AV_RL32(&header[4]);
 | 
					        size       = AV_RL32(&header[4]);
 | 
				
			||||||
        if (url_feof(pb))
 | 
					        if (url_feof(pb))
 | 
				
			||||||
            return AVERROR(EIO);
 | 
					            return AVERROR(EIO);
 | 
				
			||||||
        switch (fourcc_tag) {
 | 
					        switch (fourcc_tag) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        case LIST_TAG:
 | 
					        case LIST_TAG:
 | 
				
			||||||
            /* this is a good time to bump the video pts */
 | 
					            /* this is a good time to bump the video pts */
 | 
				
			||||||
            fourxm->video_pts ++;
 | 
					            fourxm->video_pts++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* skip the LIST-* tag and move on to the next fourcc */
 | 
					            /* skip the LIST-* tag and move on to the next fourcc */
 | 
				
			||||||
            avio_rl32(pb);
 | 
					            avio_rl32(pb);
 | 
				
			||||||
@@ -300,45 +312,43 @@ static int fourxm_read_packet(AVFormatContext *s,
 | 
				
			|||||||
            if (size + 8 < size || av_new_packet(pkt, size + 8))
 | 
					            if (size + 8 < size || av_new_packet(pkt, size + 8))
 | 
				
			||||||
                return AVERROR(EIO);
 | 
					                return AVERROR(EIO);
 | 
				
			||||||
            pkt->stream_index = fourxm->video_stream_index;
 | 
					            pkt->stream_index = fourxm->video_stream_index;
 | 
				
			||||||
            pkt->pts = fourxm->video_pts;
 | 
					            pkt->pts          = fourxm->video_pts;
 | 
				
			||||||
            pkt->pos = avio_tell(s->pb);
 | 
					            pkt->pos          = avio_tell(s->pb);
 | 
				
			||||||
            memcpy(pkt->data, header, 8);
 | 
					            memcpy(pkt->data, header, 8);
 | 
				
			||||||
            ret = avio_read(s->pb, &pkt->data[8], size);
 | 
					            ret = avio_read(s->pb, &pkt->data[8], size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (ret < 0){
 | 
					            if (ret < 0) {
 | 
				
			||||||
                av_free_packet(pkt);
 | 
					                av_free_packet(pkt);
 | 
				
			||||||
            }else
 | 
					            } else
 | 
				
			||||||
                packet_read = 1;
 | 
					                packet_read = 1;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case snd__TAG:
 | 
					        case snd__TAG:
 | 
				
			||||||
            track_number = avio_rl32(pb);
 | 
					            track_number = avio_rl32(pb);
 | 
				
			||||||
            avio_skip(pb, 4);
 | 
					            avio_skip(pb, 4);
 | 
				
			||||||
            size-=8;
 | 
					            size -= 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
 | 
					            if (track_number < fourxm->track_count &&
 | 
				
			||||||
                ret= av_get_packet(s->pb, pkt, size);
 | 
					                fourxm->tracks[track_number].channels > 0) {
 | 
				
			||||||
                if(ret<0)
 | 
					                ret = av_get_packet(s->pb, pkt, size);
 | 
				
			||||||
 | 
					                if (ret < 0)
 | 
				
			||||||
                    return AVERROR(EIO);
 | 
					                    return AVERROR(EIO);
 | 
				
			||||||
                pkt->stream_index =
 | 
					                pkt->stream_index =
 | 
				
			||||||
                    fourxm->tracks[track_number].stream_index;
 | 
					                    fourxm->tracks[track_number].stream_index;
 | 
				
			||||||
                pkt->pts = fourxm->tracks[track_number].audio_pts;
 | 
					                pkt->pts    = fourxm->tracks[track_number].audio_pts;
 | 
				
			||||||
                packet_read = 1;
 | 
					                packet_read = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /* pts accounting */
 | 
					                /* pts accounting */
 | 
				
			||||||
                audio_frame_count = size;
 | 
					                audio_frame_count = size;
 | 
				
			||||||
                if (fourxm->tracks[track_number].adpcm)
 | 
					                if (fourxm->tracks[track_number].adpcm)
 | 
				
			||||||
                    audio_frame_count -=
 | 
					                    audio_frame_count -= 2 * (fourxm->tracks[track_number].channels);
 | 
				
			||||||
                        2 * (fourxm->tracks[track_number].channels);
 | 
					                audio_frame_count /= fourxm->tracks[track_number].channels;
 | 
				
			||||||
                audio_frame_count /=
 | 
					                if (fourxm->tracks[track_number].adpcm) {
 | 
				
			||||||
                      fourxm->tracks[track_number].channels;
 | 
					 | 
				
			||||||
                if (fourxm->tracks[track_number].adpcm){
 | 
					 | 
				
			||||||
                    audio_frame_count *= 2;
 | 
					                    audio_frame_count *= 2;
 | 
				
			||||||
                }else
 | 
					                } else
 | 
				
			||||||
                    audio_frame_count /=
 | 
					                    audio_frame_count /=
 | 
				
			||||||
                    (fourxm->tracks[track_number].bits / 8);
 | 
					                        (fourxm->tracks[track_number].bits / 8);
 | 
				
			||||||
                fourxm->tracks[track_number].audio_pts += audio_frame_count;
 | 
					                fourxm->tracks[track_number].audio_pts += audio_frame_count;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                avio_skip(pb, size);
 | 
					                avio_skip(pb, size);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -210,7 +210,8 @@ static int smacker_read_header(AVFormatContext *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* load trees to extradata, they will be unpacked by decoder */
 | 
					    /* load trees to extradata, they will be unpacked by decoder */
 | 
				
			||||||
    st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE);
 | 
					    st->codec->extradata = av_mallocz(smk->treesize + 16 +
 | 
				
			||||||
 | 
					                                      FF_INPUT_BUFFER_PADDING_SIZE);
 | 
				
			||||||
    st->codec->extradata_size = smk->treesize + 16;
 | 
					    st->codec->extradata_size = smk->treesize + 16;
 | 
				
			||||||
    if(!st->codec->extradata){
 | 
					    if(!st->codec->extradata){
 | 
				
			||||||
        av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
 | 
					        av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
 | 
				
			||||||
@@ -305,12 +306,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
 | 
				
			|||||||
        /* if audio chunks are present, put them to stack and retrieve later */
 | 
					        /* if audio chunks are present, put them to stack and retrieve later */
 | 
				
			||||||
        for(i = 0; i < 7; i++) {
 | 
					        for(i = 0; i < 7; i++) {
 | 
				
			||||||
            if(flags & 1) {
 | 
					            if(flags & 1) {
 | 
				
			||||||
                unsigned int size;
 | 
					                uint32_t size;
 | 
				
			||||||
                uint8_t *tmpbuf;
 | 
					                uint8_t *tmpbuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                size = avio_rl32(s->pb) - 4;
 | 
					                size = avio_rl32(s->pb) - 4;
 | 
				
			||||||
                if(size + 4L > frame_size)
 | 
					                if (!size || size + 4L > frame_size) {
 | 
				
			||||||
 | 
					                    av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
 | 
				
			||||||
                    return AVERROR_INVALIDDATA;
 | 
					                    return AVERROR_INVALIDDATA;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                frame_size -= size;
 | 
					                frame_size -= size;
 | 
				
			||||||
                frame_size -= 4;
 | 
					                frame_size -= 4;
 | 
				
			||||||
                smk->curstream++;
 | 
					                smk->curstream++;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user