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