comparison flicvideo.c @ 12526:55339937018e libavcodec

Fix several security issues in flicvideo.c This fixes CVE-2010-3429
author michael
date Mon, 27 Sep 2010 15:16:16 +0000
parents 7dd2a45249a9
children
comparison
equal deleted inserted replaced
12525:7c0dbd8eb53a 12526:55339937018e
157 int y_ptr; 157 int y_ptr;
158 int byte_run; 158 int byte_run;
159 int pixel_skip; 159 int pixel_skip;
160 int pixel_countdown; 160 int pixel_countdown;
161 unsigned char *pixels; 161 unsigned char *pixels;
162 int pixel_limit; 162 unsigned int pixel_limit;
163 163
164 s->frame.reference = 1; 164 s->frame.reference = 1;
165 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 165 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
166 if (avctx->reget_buffer(avctx, &s->frame) < 0) { 166 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
167 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 167 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
251 y_ptr += line_packets * s->frame.linesize[0]; 251 y_ptr += line_packets * s->frame.linesize[0];
252 } else if ((line_packets & 0xC000) == 0x4000) { 252 } else if ((line_packets & 0xC000) == 0x4000) {
253 av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); 253 av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
254 } else if ((line_packets & 0xC000) == 0x8000) { 254 } else if ((line_packets & 0xC000) == 0x8000) {
255 // "last byte" opcode 255 // "last byte" opcode
256 pixels[y_ptr + s->frame.linesize[0] - 1] = line_packets & 0xff; 256 pixel_ptr= y_ptr + s->frame.linesize[0] - 1;
257 CHECK_PIXEL_PTR(0);
258 pixels[pixel_ptr] = line_packets & 0xff;
257 } else { 259 } else {
258 compressed_lines--; 260 compressed_lines--;
259 pixel_ptr = y_ptr; 261 pixel_ptr = y_ptr;
262 CHECK_PIXEL_PTR(0);
260 pixel_countdown = s->avctx->width; 263 pixel_countdown = s->avctx->width;
261 for (i = 0; i < line_packets; i++) { 264 for (i = 0; i < line_packets; i++) {
262 /* account for the skip bytes */ 265 /* account for the skip bytes */
263 pixel_skip = buf[stream_ptr++]; 266 pixel_skip = buf[stream_ptr++];
264 pixel_ptr += pixel_skip; 267 pixel_ptr += pixel_skip;
266 byte_run = (signed char)(buf[stream_ptr++]); 269 byte_run = (signed char)(buf[stream_ptr++]);
267 if (byte_run < 0) { 270 if (byte_run < 0) {
268 byte_run = -byte_run; 271 byte_run = -byte_run;
269 palette_idx1 = buf[stream_ptr++]; 272 palette_idx1 = buf[stream_ptr++];
270 palette_idx2 = buf[stream_ptr++]; 273 palette_idx2 = buf[stream_ptr++];
271 CHECK_PIXEL_PTR(byte_run); 274 CHECK_PIXEL_PTR(byte_run * 2);
272 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { 275 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
273 pixels[pixel_ptr++] = palette_idx1; 276 pixels[pixel_ptr++] = palette_idx1;
274 pixels[pixel_ptr++] = palette_idx2; 277 pixels[pixel_ptr++] = palette_idx2;
275 } 278 }
276 } else { 279 } else {
296 299
297 compressed_lines = AV_RL16(&buf[stream_ptr]); 300 compressed_lines = AV_RL16(&buf[stream_ptr]);
298 stream_ptr += 2; 301 stream_ptr += 2;
299 while (compressed_lines > 0) { 302 while (compressed_lines > 0) {
300 pixel_ptr = y_ptr; 303 pixel_ptr = y_ptr;
304 CHECK_PIXEL_PTR(0);
301 pixel_countdown = s->avctx->width; 305 pixel_countdown = s->avctx->width;
302 line_packets = buf[stream_ptr++]; 306 line_packets = buf[stream_ptr++];
303 if (line_packets > 0) { 307 if (line_packets > 0) {
304 for (i = 0; i < line_packets; i++) { 308 for (i = 0; i < line_packets; i++) {
305 /* account for the skip bytes */ 309 /* account for the skip bytes */
451 int byte_run; 455 int byte_run;
452 int pixel_skip; 456 int pixel_skip;
453 int pixel_countdown; 457 int pixel_countdown;
454 unsigned char *pixels; 458 unsigned char *pixels;
455 int pixel; 459 int pixel;
456 int pixel_limit; 460 unsigned int pixel_limit;
457 461
458 s->frame.reference = 1; 462 s->frame.reference = 1;
459 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 463 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
460 if (avctx->reget_buffer(avctx, &s->frame) < 0) { 464 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
461 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 465 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
501 line_packets = -line_packets; 505 line_packets = -line_packets;
502 y_ptr += line_packets * s->frame.linesize[0]; 506 y_ptr += line_packets * s->frame.linesize[0];
503 } else { 507 } else {
504 compressed_lines--; 508 compressed_lines--;
505 pixel_ptr = y_ptr; 509 pixel_ptr = y_ptr;
510 CHECK_PIXEL_PTR(0);
506 pixel_countdown = s->avctx->width; 511 pixel_countdown = s->avctx->width;
507 for (i = 0; i < line_packets; i++) { 512 for (i = 0; i < line_packets; i++) {
508 /* account for the skip bytes */ 513 /* account for the skip bytes */
509 pixel_skip = buf[stream_ptr++]; 514 pixel_skip = buf[stream_ptr++];
510 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ 515 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
512 byte_run = (signed char)(buf[stream_ptr++]); 517 byte_run = (signed char)(buf[stream_ptr++]);
513 if (byte_run < 0) { 518 if (byte_run < 0) {
514 byte_run = -byte_run; 519 byte_run = -byte_run;
515 pixel = AV_RL16(&buf[stream_ptr]); 520 pixel = AV_RL16(&buf[stream_ptr]);
516 stream_ptr += 2; 521 stream_ptr += 2;
517 CHECK_PIXEL_PTR(byte_run); 522 CHECK_PIXEL_PTR(2 * byte_run);
518 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { 523 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
519 *((signed short*)(&pixels[pixel_ptr])) = pixel; 524 *((signed short*)(&pixels[pixel_ptr])) = pixel;
520 pixel_ptr += 2; 525 pixel_ptr += 2;
521 } 526 }
522 } else { 527 } else {
523 CHECK_PIXEL_PTR(byte_run); 528 CHECK_PIXEL_PTR(2 * byte_run);
524 for (j = 0; j < byte_run; j++, pixel_countdown--) { 529 for (j = 0; j < byte_run; j++, pixel_countdown--) {
525 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]); 530 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
526 stream_ptr += 2; 531 stream_ptr += 2;
527 pixel_ptr += 2; 532 pixel_ptr += 2;
528 } 533 }
609 while (pixel_countdown > 0) { 614 while (pixel_countdown > 0) {
610 byte_run = (signed char)(buf[stream_ptr++]); 615 byte_run = (signed char)(buf[stream_ptr++]);
611 if (byte_run > 0) { 616 if (byte_run > 0) {
612 pixel = AV_RL16(&buf[stream_ptr]); 617 pixel = AV_RL16(&buf[stream_ptr]);
613 stream_ptr += 2; 618 stream_ptr += 2;
614 CHECK_PIXEL_PTR(byte_run); 619 CHECK_PIXEL_PTR(2 * byte_run);
615 for (j = 0; j < byte_run; j++) { 620 for (j = 0; j < byte_run; j++) {
616 *((signed short*)(&pixels[pixel_ptr])) = pixel; 621 *((signed short*)(&pixels[pixel_ptr])) = pixel;
617 pixel_ptr += 2; 622 pixel_ptr += 2;
618 pixel_countdown--; 623 pixel_countdown--;
619 if (pixel_countdown < 0) 624 if (pixel_countdown < 0)
620 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", 625 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
621 pixel_countdown); 626 pixel_countdown);
622 } 627 }
623 } else { /* copy pixels if byte_run < 0 */ 628 } else { /* copy pixels if byte_run < 0 */
624 byte_run = -byte_run; 629 byte_run = -byte_run;
625 CHECK_PIXEL_PTR(byte_run); 630 CHECK_PIXEL_PTR(2 * byte_run);
626 for (j = 0; j < byte_run; j++) { 631 for (j = 0; j < byte_run; j++) {
627 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]); 632 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
628 stream_ptr += 2; 633 stream_ptr += 2;
629 pixel_ptr += 2; 634 pixel_ptr += 2;
630 pixel_countdown--; 635 pixel_countdown--;