comparison vmnc.c @ 3685:dd2da6e09d32 libavcodec

Tests for overreading input data
author kostya
date Thu, 07 Sep 2006 04:05:04 +0000
parents 9f77f4f577b4
children 5fc587a5feea
comparison
equal deleted inserted replaced
3684:9f77f4f577b4 3685:dd2da6e09d32
221 } 221 }
222 dst += stride; 222 dst += stride;
223 } 223 }
224 } 224 }
225 225
226 static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int w, int h, int stride) 226 static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int ssize, int w, int h, int stride)
227 { 227 {
228 int i, j, k; 228 int i, j, k;
229 int bg = 0, fg = 0, rects, color, flags, xy, wh; 229 int bg = 0, fg = 0, rects, color, flags, xy, wh;
230 const int bpp = c->bpp2; 230 const int bpp = c->bpp2;
231 uint8_t *dst2; 231 uint8_t *dst2;
235 for(j = 0; j < h; j += 16) { 235 for(j = 0; j < h; j += 16) {
236 dst2 = dst; 236 dst2 = dst;
237 bw = 16; 237 bw = 16;
238 if(j + 16 > h) bh = h - j; 238 if(j + 16 > h) bh = h - j;
239 for(i = 0; i < w; i += 16, dst2 += 16 * bpp) { 239 for(i = 0; i < w; i += 16, dst2 += 16 * bpp) {
240 if(src - ssrc >= ssize) {
241 av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
242 return -1;
243 }
240 if(i + 16 > w) bw = w - i; 244 if(i + 16 > w) bw = w - i;
241 flags = *src++; 245 flags = *src++;
242 if(flags & HT_RAW) { 246 if(flags & HT_RAW) {
247 if(src - ssrc > ssize - bw * bh * bpp) {
248 av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
249 return -1;
250 }
243 paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride); 251 paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride);
244 src += bw * bh * bpp; 252 src += bw * bh * bpp;
245 } else { 253 } else {
246 if(flags & HT_BKG) { 254 if(flags & HT_BKG) {
247 bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; 255 bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
250 fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; 258 fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
251 } 259 }
252 rects = 0; 260 rects = 0;
253 if(flags & HT_SUB) 261 if(flags & HT_SUB)
254 rects = *src++; 262 rects = *src++;
255 color = (flags & HT_CLR); 263 color = !!(flags & HT_CLR);
256 264
257 paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride); 265 paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
258 266
267 if(src - ssrc > ssize - rects * (color * bpp + 2)) {
268 av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
269 return -1;
270 }
259 for(k = 0; k < rects; k++) { 271 for(k = 0; k < rects; k++) {
260 if(color) { 272 if(color) {
261 fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; 273 fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
262 } 274 }
263 xy = *src++; 275 xy = *src++;
274 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) 286 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
275 { 287 {
276 VmncContext * const c = (VmncContext *)avctx->priv_data; 288 VmncContext * const c = (VmncContext *)avctx->priv_data;
277 uint8_t *outptr; 289 uint8_t *outptr;
278 uint8_t *src = buf; 290 uint8_t *src = buf;
279 int dx, dy, w, h, depth, enc, chunks, res; 291 int dx, dy, w, h, depth, enc, chunks, res, size_left;
280 292
281 c->pic.reference = 1; 293 c->pic.reference = 1;
282 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 294 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
283 if(avctx->reget_buffer(avctx, &c->pic) < 0){ 295 if(avctx->reget_buffer(avctx, &c->pic) < 0){
284 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 296 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
320 dy = BE_16(src); src += 2; 332 dy = BE_16(src); src += 2;
321 w = BE_16(src); src += 2; 333 w = BE_16(src); src += 2;
322 h = BE_16(src); src += 2; 334 h = BE_16(src); src += 2;
323 enc = BE_32(src); src += 4; 335 enc = BE_32(src); src += 4;
324 outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; 336 outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
337 size_left = buf_size - (src - buf);
325 switch(enc) { 338 switch(enc) {
326 case MAGIC_WMVd: // cursor 339 case MAGIC_WMVd: // cursor
340 if(size_left < 2 + w * h * c->bpp2 * 2) {
341 av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left);
342 return -1;
343 }
327 src += 2; 344 src += 2;
328 c->cur_w = w; 345 c->cur_w = w;
329 c->cur_h = h; 346 c->cur_h = h;
330 c->cur_hx = dx; 347 c->cur_hx = dx;
331 c->cur_hy = dy; 348 c->cur_hy = dy;
365 case 0x00000000: // raw rectangle data 382 case 0x00000000: // raw rectangle data
366 if((dx + w > c->width) || (dy + h > c->height)) { 383 if((dx + w > c->width) || (dy + h > c->height)) {
367 av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); 384 av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
368 return -1; 385 return -1;
369 } 386 }
387 if(size_left < w * h * c->bpp2) {
388 av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left);
389 return -1;
390 }
370 paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]); 391 paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]);
371 src += w * h * c->bpp2; 392 src += w * h * c->bpp2;
372 break; 393 break;
373 case 0x00000005: // HexTile encoded rectangle 394 case 0x00000005: // HexTile encoded rectangle
374 if((dx + w > c->width) || (dy + h > c->height)) { 395 if((dx + w > c->width) || (dy + h > c->height)) {
375 av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); 396 av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
376 return -1; 397 return -1;
377 } 398 }
378 res = decode_hextile(c, outptr, src, w, h, c->pic.linesize[0]); 399 res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);
379 if(res < 0) 400 if(res < 0)
380 return -1; 401 return -1;
381 src += res; 402 src += res;
382 break; 403 break;
383 default: 404 default: