comparison indeo3.c @ 8986:4d5d7e08f1d3 libavcodec

Some buffer checks for indeo3
author alexc
date Thu, 19 Feb 2009 22:56:35 +0000
parents 7e7acb5d1da8
children 48c89edff557
comparison
equal deleted inserted replaced
8985:028c9cf95b95 8986:4d5d7e08f1d3
973 iv_free_func(s); 973 iv_free_func(s);
974 974
975 return ret; 975 return ret;
976 } 976 }
977 977
978 static unsigned long iv_decode_frame(Indeo3DecodeContext *s, 978 static int iv_decode_frame(Indeo3DecodeContext *s,
979 const uint8_t *buf, int buf_size) 979 const uint8_t *buf, int buf_size)
980 { 980 {
981 unsigned int image_width, image_height, 981 unsigned int image_width, image_height,
982 chroma_width, chroma_height; 982 chroma_width, chroma_height;
983 unsigned long flags, cb_offset, data_size, 983 unsigned long flags, cb_offset, data_size,
1004 u_offset = bytestream_get_le32(&buf_pos); 1004 u_offset = bytestream_get_le32(&buf_pos);
1005 buf_pos += 4; /* reserved */ 1005 buf_pos += 4; /* reserved */
1006 hdr_pos = buf_pos; 1006 hdr_pos = buf_pos;
1007 if(data_size == 0x80) return 4; 1007 if(data_size == 0x80) return 4;
1008 1008
1009 if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) {
1010 av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n");
1011 return -1;
1012 }
1013
1009 if(flags & 0x200) { 1014 if(flags & 0x200) {
1010 s->cur_frame = s->iv_frame + 1; 1015 s->cur_frame = s->iv_frame + 1;
1011 s->ref_frame = s->iv_frame; 1016 s->ref_frame = s->iv_frame;
1012 } else { 1017 } else {
1013 s->cur_frame = s->iv_frame; 1018 s->cur_frame = s->iv_frame;
1014 s->ref_frame = s->iv_frame + 1; 1019 s->ref_frame = s->iv_frame + 1;
1015 } 1020 }
1016 1021
1017 buf_pos = buf + 16 + y_offset; 1022 buf_pos = buf + 16 + y_offset;
1018 mc_vector_count = bytestream_get_le32(&buf_pos); 1023 mc_vector_count = bytestream_get_le32(&buf_pos);
1024 if(2LL*mc_vector_count >= buf_size-16-y_offset) {
1025 av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
1026 return -1;
1027 }
1019 1028
1020 iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width, 1029 iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width,
1021 image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, 1030 image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1022 FFMIN(image_width, 160)); 1031 FFMIN(image_width, 160));
1023 1032
1024 if (!(s->avctx->flags & CODEC_FLAG_GRAY)) 1033 if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1025 { 1034 {
1026 1035
1027 buf_pos = buf + 16 + v_offset; 1036 buf_pos = buf + 16 + v_offset;
1028 mc_vector_count = bytestream_get_le32(&buf_pos); 1037 mc_vector_count = bytestream_get_le32(&buf_pos);
1038 if(2LL*mc_vector_count >= buf_size-16-v_offset) {
1039 av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
1040 return -1;
1041 }
1029 1042
1030 iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, 1043 iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,
1031 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, 1044 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1032 FFMIN(chroma_width, 40)); 1045 FFMIN(chroma_width, 40));
1033 1046
1034 buf_pos = buf + 16 + u_offset; 1047 buf_pos = buf + 16 + u_offset;
1035 mc_vector_count = bytestream_get_le32(&buf_pos); 1048 mc_vector_count = bytestream_get_le32(&buf_pos);
1049 if(2LL*mc_vector_count >= buf_size-16-u_offset) {
1050 av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
1051 return -1;
1052 }
1036 1053
1037 iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, 1054 iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,
1038 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, 1055 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1039 FFMIN(chroma_width, 40)); 1056 FFMIN(chroma_width, 40));
1040 1057
1049 { 1066 {
1050 Indeo3DecodeContext *s=avctx->priv_data; 1067 Indeo3DecodeContext *s=avctx->priv_data;
1051 uint8_t *src, *dest; 1068 uint8_t *src, *dest;
1052 int y; 1069 int y;
1053 1070
1054 iv_decode_frame(s, buf, buf_size); 1071 if (iv_decode_frame(s, buf, buf_size) < 0)
1072 return -1;
1055 1073
1056 if(s->frame.data[0]) 1074 if(s->frame.data[0])
1057 avctx->release_buffer(avctx, &s->frame); 1075 avctx->release_buffer(avctx, &s->frame);
1058 1076
1059 s->frame.reference = 0; 1077 s->frame.reference = 0;