Mercurial > libavcodec.hg
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; |