comparison vmdav.c @ 2829:9ff4c2733422 libavcodec

tinfoil patch: be more diligent about checking array boundaries before writing to them
author melanson
date Sat, 13 Aug 2005 18:39:21 +0000
parents 4bdd4927d2fc
children ef2149182f1c
comparison
equal deleted inserted replaced
2828:2aae25679885 2829:9ff4c2733422
64 unsigned char *buf; 64 unsigned char *buf;
65 int size; 65 int size;
66 66
67 unsigned char palette[PALETTE_COUNT * 4]; 67 unsigned char palette[PALETTE_COUNT * 4];
68 unsigned char *unpack_buffer; 68 unsigned char *unpack_buffer;
69 int unpack_buffer_size;
69 70
70 } VmdVideoContext; 71 } VmdVideoContext;
71 72
72 #define QUEUE_SIZE 0x1000 73 #define QUEUE_SIZE 0x1000
73 #define QUEUE_MASK 0x0FFF 74 #define QUEUE_MASK 0x0FFF
74 75
75 static void lz_unpack(unsigned char *src, unsigned char *dest) 76 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
76 { 77 {
77 unsigned char *s; 78 unsigned char *s;
78 unsigned char *d; 79 unsigned char *d;
80 unsigned char *d_end;
79 unsigned char queue[QUEUE_SIZE]; 81 unsigned char queue[QUEUE_SIZE];
80 unsigned int qpos; 82 unsigned int qpos;
81 unsigned int dataleft; 83 unsigned int dataleft;
82 unsigned int chainofs; 84 unsigned int chainofs;
83 unsigned int chainlen; 85 unsigned int chainlen;
85 unsigned char tag; 87 unsigned char tag;
86 unsigned int i, j; 88 unsigned int i, j;
87 89
88 s = src; 90 s = src;
89 d = dest; 91 d = dest;
92 d_end = d + dest_len;
90 dataleft = LE_32(s); 93 dataleft = LE_32(s);
91 s += 4; 94 s += 4;
92 memset(queue, QUEUE_SIZE, 0x20); 95 memset(queue, QUEUE_SIZE, 0x20);
93 if (LE_32(s) == 0x56781234) { 96 if (LE_32(s) == 0x56781234) {
94 s += 4; 97 s += 4;
100 } 103 }
101 104
102 while (dataleft > 0) { 105 while (dataleft > 0) {
103 tag = *s++; 106 tag = *s++;
104 if ((tag == 0xFF) && (dataleft > 8)) { 107 if ((tag == 0xFF) && (dataleft > 8)) {
108 if (d + 8 > d_end)
109 return;
105 for (i = 0; i < 8; i++) { 110 for (i = 0; i < 8; i++) {
106 queue[qpos++] = *d++ = *s++; 111 queue[qpos++] = *d++ = *s++;
107 qpos &= QUEUE_MASK; 112 qpos &= QUEUE_MASK;
108 } 113 }
109 dataleft -= 8; 114 dataleft -= 8;
110 } else { 115 } else {
111 for (i = 0; i < 8; i++) { 116 for (i = 0; i < 8; i++) {
112 if (dataleft == 0) 117 if (dataleft == 0)
113 break; 118 break;
114 if (tag & 0x01) { 119 if (tag & 0x01) {
120 if (d + 1 > d_end)
121 return;
115 queue[qpos++] = *d++ = *s++; 122 queue[qpos++] = *d++ = *s++;
116 qpos &= QUEUE_MASK; 123 qpos &= QUEUE_MASK;
117 dataleft--; 124 dataleft--;
118 } else { 125 } else {
119 chainofs = *s++; 126 chainofs = *s++;
120 chainofs |= ((*s & 0xF0) << 4); 127 chainofs |= ((*s & 0xF0) << 4);
121 chainlen = (*s++ & 0x0F) + 3; 128 chainlen = (*s++ & 0x0F) + 3;
122 if (chainlen == speclen) 129 if (chainlen == speclen)
123 chainlen = *s++ + 0xF + 3; 130 chainlen = *s++ + 0xF + 3;
131 if (d + chainlen > d_end)
132 return;
124 for (j = 0; j < chainlen; j++) { 133 for (j = 0; j < chainlen; j++) {
125 *d = queue[chainofs++ & QUEUE_MASK]; 134 *d = queue[chainofs++ & QUEUE_MASK];
126 queue[qpos++] = *d++; 135 queue[qpos++] = *d++;
127 qpos &= QUEUE_MASK; 136 qpos &= QUEUE_MASK;
128 } 137 }
132 } 141 }
133 } 142 }
134 } 143 }
135 } 144 }
136 145
137 static int rle_unpack(unsigned char *src, unsigned char *dest, int len) 146 static int rle_unpack(unsigned char *src, unsigned char *dest,
147 int src_len, int dest_len)
138 { 148 {
139 unsigned char *ps; 149 unsigned char *ps;
140 unsigned char *pd; 150 unsigned char *pd;
141 int i, l; 151 int i, l;
152 unsigned char *dest_end = dest + dest_len;
142 153
143 ps = src; 154 ps = src;
144 pd = dest; 155 pd = dest;
145 if (len & 1) 156 if (src_len & 1)
146 *pd++ = *ps++; 157 *pd++ = *ps++;
147 158
148 len >>= 1; 159 src_len >>= 1;
149 i = 0; 160 i = 0;
150 do { 161 do {
151 l = *ps++; 162 l = *ps++;
152 if (l & 0x80) { 163 if (l & 0x80) {
153 l = (l & 0x7F) * 2; 164 l = (l & 0x7F) * 2;
165 if (pd + l > dest_end)
166 return (ps - src);
154 memcpy(pd, ps, l); 167 memcpy(pd, ps, l);
155 ps += l; 168 ps += l;
156 pd += l; 169 pd += l;
157 } else { 170 } else {
171 if (pd + i > dest_end)
172 return (ps - src);
158 for (i = 0; i < l; i++) { 173 for (i = 0; i < l; i++) {
159 *pd++ = ps[0]; 174 *pd++ = ps[0];
160 *pd++ = ps[1]; 175 *pd++ = ps[1];
161 } 176 }
162 ps += 2; 177 ps += 2;
163 } 178 }
164 i += l; 179 i += l;
165 } while (i < len); 180 } while (i < src_len);
166 181
167 return (ps - src); 182 return (ps - src);
168 } 183 }
169 184
170 static void vmd_decode(VmdVideoContext *s) 185 static void vmd_decode(VmdVideoContext *s)
183 unsigned char len; 198 unsigned char len;
184 int ofs; 199 int ofs;
185 200
186 int frame_x, frame_y; 201 int frame_x, frame_y;
187 int frame_width, frame_height; 202 int frame_width, frame_height;
203 int dp_size;
188 204
189 frame_x = LE_16(&s->buf[6]); 205 frame_x = LE_16(&s->buf[6]);
190 frame_y = LE_16(&s->buf[8]); 206 frame_y = LE_16(&s->buf[8]);
191 frame_width = LE_16(&s->buf[10]) - frame_x + 1; 207 frame_width = LE_16(&s->buf[10]) - frame_x + 1;
192 frame_height = LE_16(&s->buf[12]) - frame_y + 1; 208 frame_height = LE_16(&s->buf[12]) - frame_y + 1;
215 if (s->size >= 0) { 231 if (s->size >= 0) {
216 /* originally UnpackFrame in VAG's code */ 232 /* originally UnpackFrame in VAG's code */
217 pb = p; 233 pb = p;
218 meth = *pb++; 234 meth = *pb++;
219 if (meth & 0x80) { 235 if (meth & 0x80) {
220 lz_unpack(pb, s->unpack_buffer); 236 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
221 meth &= 0x7F; 237 meth &= 0x7F;
222 pb = s->unpack_buffer; 238 pb = s->unpack_buffer;
223 } 239 }
224 240
225 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; 241 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
242 dp_size = s->frame.linesize[0] * s->avctx->height;
226 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; 243 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
227 switch (meth) { 244 switch (meth) {
228 case 1: 245 case 1:
229 for (i = 0; i < frame_height; i++) { 246 for (i = 0; i < frame_height; i++) {
230 ofs = 0; 247 ofs = 0;
231 do { 248 do {
232 len = *pb++; 249 len = *pb++;
233 if (len & 0x80) { 250 if (len & 0x80) {
234 len = (len & 0x7F) + 1; 251 len = (len & 0x7F) + 1;
252 if (ofs + len > frame_width)
253 return;
235 memcpy(&dp[ofs], pb, len); 254 memcpy(&dp[ofs], pb, len);
236 pb += len; 255 pb += len;
237 ofs += len; 256 ofs += len;
238 } else { 257 } else {
239 /* interframe pixel copy */ 258 /* interframe pixel copy */
259 if (ofs + len + 1 > frame_width)
260 return;
240 memcpy(&dp[ofs], &pp[ofs], len + 1); 261 memcpy(&dp[ofs], &pp[ofs], len + 1);
241 ofs += len + 1; 262 ofs += len + 1;
242 } 263 }
243 } while (ofs < frame_width); 264 } while (ofs < frame_width);
244 if (ofs > frame_width) { 265 if (ofs > frame_width) {
266 do { 287 do {
267 len = *pb++; 288 len = *pb++;
268 if (len & 0x80) { 289 if (len & 0x80) {
269 len = (len & 0x7F) + 1; 290 len = (len & 0x7F) + 1;
270 if (*pb++ == 0xFF) 291 if (*pb++ == 0xFF)
271 len = rle_unpack(pb, &dp[ofs], len); 292 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
272 else 293 else
273 memcpy(&dp[ofs], pb, len); 294 memcpy(&dp[ofs], pb, len);
274 pb += len; 295 pb += len;
275 ofs += len; 296 ofs += len;
276 } else { 297 } else {
277 /* interframe pixel copy */ 298 /* interframe pixel copy */
299 if (ofs + len + 1 > frame_width)
300 return;
278 memcpy(&dp[ofs], &pp[ofs], len + 1); 301 memcpy(&dp[ofs], &pp[ofs], len + 1);
279 ofs += len + 1; 302 ofs += len + 1;
280 } 303 }
281 } while (ofs < frame_width); 304 } while (ofs < frame_width);
282 if (ofs > frame_width) { 305 if (ofs > frame_width) {
312 VMD_HEADER_SIZE); 335 VMD_HEADER_SIZE);
313 return -1; 336 return -1;
314 } 337 }
315 vmd_header = (unsigned char *)avctx->extradata; 338 vmd_header = (unsigned char *)avctx->extradata;
316 339
317 s->unpack_buffer = av_malloc(LE_32(&vmd_header[800])); 340 s->unpack_buffer_size = LE_32(&vmd_header[800]);
341 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
318 if (!s->unpack_buffer) 342 if (!s->unpack_buffer)
319 return -1; 343 return -1;
320 344
321 /* load up the initial palette */ 345 /* load up the initial palette */
322 raw_palette = &vmd_header[28]; 346 raw_palette = &vmd_header[28];