comparison vb.c @ 10963:81033a080136 libavcodec

Check for chunk boundaries when decoding VB codec data
author kostya
date Fri, 22 Jan 2010 19:07:44 +0000
parents c2ba520798a3
children 1c3a10f94570
comparison
equal deleted inserted replaced
10962:c2ba520798a3 10963:81033a080136
56 0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC, 56 0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC,
57 0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63, 57 0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63,
58 0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C 58 0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C
59 }; 59 };
60 60
61 static void vb_decode_palette(VBDecContext *c) 61 static void vb_decode_palette(VBDecContext *c, int data_size)
62 { 62 {
63 int start, size, i; 63 int start, size, i;
64 64
65 start = bytestream_get_byte(&c->stream); 65 start = bytestream_get_byte(&c->stream);
66 size = (bytestream_get_byte(&c->stream) - 1) & 0xFF; 66 size = (bytestream_get_byte(&c->stream) - 1) & 0xFF;
67 if(start + size > 255){ 67 if(start + size > 255){
68 av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n"); 68 av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n");
69 return; 69 return;
70 } 70 }
71 if(size*3+2 > data_size){
72 av_log(c->avctx, AV_LOG_ERROR, "Palette data runs beyond chunk size\n");
73 return;
74 }
71 for(i = start; i <= start + size; i++) 75 for(i = start; i <= start + size; i++)
72 c->pal[i] = bytestream_get_be24(&c->stream); 76 c->pal[i] = bytestream_get_be24(&c->stream);
73 } 77 }
74 78
75 static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end) 79 static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end)
80 static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end) 84 static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end)
81 { 85 {
82 return buf >= start && (buf + 4) <= end; 86 return buf >= start && (buf + 4) <= end;
83 } 87 }
84 88
85 static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int offset) 89 static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_size, int offset)
86 { 90 {
87 uint8_t *prev, *cur; 91 uint8_t *prev, *cur;
92 const uint8_t* data_end = buf + data_size;
88 int blk, blocks, t, blk2; 93 int blk, blocks, t, blk2;
89 int blocktypes = 0; 94 int blocktypes = 0;
90 int x, y, a, b; 95 int x, y, a, b;
91 int pattype, pattern; 96 int pattype, pattern;
92 const int width = c->avctx->width; 97 const int width = c->avctx->width;
97 cur = c->frame; 102 cur = c->frame;
98 103
99 blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2); 104 blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2);
100 blk2 = 0; 105 blk2 = 0;
101 for(blk = 0; blk < blocks; blk++){ 106 for(blk = 0; blk < blocks; blk++){
102 if(!(blk & 3)) 107 if(!(blk & 3)) {
108 if(buf >= data_end){
109 av_log(c->avctx, AV_LOG_ERROR, "Data pointer out of bounds\n");
110 return -1;
111 }
103 blocktypes = bytestream_get_byte(&buf); 112 blocktypes = bytestream_get_byte(&buf);
113 }
104 switch(blocktypes & 0xC0){ 114 switch(blocktypes & 0xC0){
105 case 0x00: //skip 115 case 0x00: //skip
106 for(y = 0; y < 4; y++) 116 for(y = 0; y < 4; y++)
107 if(check_line(prev + y*width, pstart, pend)) 117 if(check_line(prev + y*width, pstart, pend))
108 memcpy(cur + y*width, prev + y*width, 4); 118 memcpy(cur + y*width, prev + y*width, 4);
110 memset(cur + y*width, 0, 4); 120 memset(cur + y*width, 0, 4);
111 break; 121 break;
112 case 0x40: 122 case 0x40:
113 t = bytestream_get_byte(&buf); 123 t = bytestream_get_byte(&buf);
114 if(!t){ //raw block 124 if(!t){ //raw block
125 if(buf + 16 > data_end){
126 av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n");
127 return -1;
128 }
115 for(y = 0; y < 4; y++) 129 for(y = 0; y < 4; y++)
116 memcpy(cur + y*width, buf + y*4, 4); 130 memcpy(cur + y*width, buf + y*4, 4);
117 buf += 16; 131 buf += 16;
118 }else{ // motion compensation 132 }else{ // motion compensation
119 x = ((t & 0xF)^8) - 8; 133 x = ((t & 0xF)^8) - 8;
130 t = bytestream_get_byte(&buf); 144 t = bytestream_get_byte(&buf);
131 for(y = 0; y < 4; y++) 145 for(y = 0; y < 4; y++)
132 memset(cur + y*width, t, 4); 146 memset(cur + y*width, t, 4);
133 break; 147 break;
134 case 0xC0: // pattern fill 148 case 0xC0: // pattern fill
149 if(buf + 2 > data_end){
150 av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n");
151 return -1;
152 }
135 t = bytestream_get_byte(&buf); 153 t = bytestream_get_byte(&buf);
136 pattype = t >> 6; 154 pattype = t >> 6;
137 pattern = vb_patterns[t & 0x3F]; 155 pattern = vb_patterns[t & 0x3F];
138 switch(pattype){ 156 switch(pattype){
139 case 0: 157 case 0:
207 size = bytestream_get_le32(&c->stream); 225 size = bytestream_get_le32(&c->stream);
208 if(size > rest){ 226 if(size > rest){
209 av_log(avctx, AV_LOG_ERROR, "Frame size is too big\n"); 227 av_log(avctx, AV_LOG_ERROR, "Frame size is too big\n");
210 return -1; 228 return -1;
211 } 229 }
212 vb_decode_framedata(c, c->stream, offset); 230 vb_decode_framedata(c, c->stream, size, offset);
213 c->stream += size - 4; 231 c->stream += size - 4;
214 rest -= size; 232 rest -= size;
215 } 233 }
216 if(flags & VB_HAS_PALETTE){ 234 if(flags & VB_HAS_PALETTE){
217 size = bytestream_get_le32(&c->stream); 235 size = bytestream_get_le32(&c->stream);
218 if(size > rest){ 236 if(size > rest){
219 av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n"); 237 av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n");
220 return -1; 238 return -1;
221 } 239 }
222 vb_decode_palette(c); 240 vb_decode_palette(c, size);
223 rest -= size; 241 rest -= size;
224 } 242 }
225 243
226 memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); 244 memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
227 c->pic.palette_has_changed = flags & VB_HAS_PALETTE; 245 c->pic.palette_has_changed = flags & VB_HAS_PALETTE;