comparison lcl.c @ 2418:82af834636c2 libavcodec

Check pointers before writing to memory, fix possible integer overflows Force alignement for mszh and zlib decoders
author rtognimp
date Sun, 09 Jan 2005 23:39:32 +0000
parents 582e635cfa08
children 4b350cc506a7
comparison
equal deleted inserted replaced
2417:991f39305057 2418:82af834636c2
143 return fix((yq << 20) + rq * 1470103); 143 return fix((yq << 20) + rq * 1470103);
144 } 144 }
145 145
146 146
147 147
148 static int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr) 148 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
149 { 149 {
150 unsigned char *destptr_bak = destptr; 150 unsigned char *destptr_bak = destptr;
151 unsigned char *destptr_end = destptr + destsize;
151 unsigned char mask = 0; 152 unsigned char mask = 0;
152 unsigned char maskbit = 0; 153 unsigned char maskbit = 0;
153 unsigned int ofs, cnt; 154 unsigned int ofs, cnt;
154 155
155 while (srclen > 0) { 156 while ((srclen > 0) && (destptr < destptr_end)) {
156 if (maskbit == 0) { 157 if (maskbit == 0) {
157 mask = *(srcptr++); 158 mask = *(srcptr++);
158 maskbit = 8; 159 maskbit = 8;
159 srclen--; 160 srclen--;
160 continue; 161 continue;
161 } 162 }
162 if ((mask & (1 << (--maskbit))) == 0) { 163 if ((mask & (1 << (--maskbit))) == 0) {
164 if (destptr + 4 > destptr_end)
165 break;
163 *(int*)destptr = *(int*)srcptr; 166 *(int*)destptr = *(int*)srcptr;
164 srclen -= 4; 167 srclen -= 4;
165 destptr += 4; 168 destptr += 4;
166 srcptr += 4; 169 srcptr += 4;
167 } else { 170 } else {
170 ofs += cnt * 256;; 173 ofs += cnt * 256;;
171 cnt = ((cnt >> 3) & 0x1f) + 1; 174 cnt = ((cnt >> 3) & 0x1f) + 1;
172 ofs &= 0x7ff; 175 ofs &= 0x7ff;
173 srclen -= 2; 176 srclen -= 2;
174 cnt *= 4; 177 cnt *= 4;
178 if (destptr + cnt > destptr_end) {
179 cnt = destptr_end - destptr;
180 }
175 for (; cnt > 0; cnt--) { 181 for (; cnt > 0; cnt--) {
176 *(destptr) = *(destptr - ofs); 182 *(destptr) = *(destptr - ofs);
177 destptr++; 183 destptr++;
178 } 184 }
179 } 185 }
192 */ 198 */
193 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) 199 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
194 { 200 {
195 LclContext * const c = (LclContext *)avctx->priv_data; 201 LclContext * const c = (LclContext *)avctx->priv_data;
196 unsigned char *encoded = (unsigned char *)buf; 202 unsigned char *encoded = (unsigned char *)buf;
197 int pixel_ptr; 203 unsigned int pixel_ptr;
198 int row, col; 204 int row, col;
199 unsigned char *outptr; 205 unsigned char *outptr;
200 unsigned int width = avctx->width; // Real image width 206 unsigned int width = avctx->width; // Real image width
201 unsigned int height = avctx->height; // Real image height 207 unsigned int height = avctx->height; // Real image height
202 unsigned int mszh_dlen; 208 unsigned int mszh_dlen;
204 int uqvq; 210 int uqvq;
205 unsigned int mthread_inlen, mthread_outlen; 211 unsigned int mthread_inlen, mthread_outlen;
206 #ifdef CONFIG_ZLIB 212 #ifdef CONFIG_ZLIB
207 int zret; // Zlib return code 213 int zret; // Zlib return code
208 #endif 214 #endif
209 int len = buf_size; 215 unsigned int len = buf_size;
210 216
211 /* no supplementary picture */ 217 /* no supplementary picture */
212 if (buf_size == 0) 218 if (buf_size == 0)
213 return 0; 219 return 0;
214 220
230 switch (c->compression) { 236 switch (c->compression) {
231 case COMP_MSZH: 237 case COMP_MSZH:
232 if (c->flags & FLAG_MULTITHREAD) { 238 if (c->flags & FLAG_MULTITHREAD) {
233 mthread_inlen = *((unsigned int*)encoded); 239 mthread_inlen = *((unsigned int*)encoded);
234 mthread_outlen = *((unsigned int*)(encoded+4)); 240 mthread_outlen = *((unsigned int*)(encoded+4));
235 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf); 241 if (mthread_outlen > c->decomp_size) // this should not happen
242 mthread_outlen = c->decomp_size;
243 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
236 if (mthread_outlen != mszh_dlen) { 244 if (mthread_outlen != mszh_dlen) {
237 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", 245 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
238 mthread_outlen, mszh_dlen); 246 mthread_outlen, mszh_dlen);
247 return -1;
239 } 248 }
240 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, 249 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen,
241 c->decomp_buf + mthread_outlen); 250 c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
242 if ((c->decomp_size - mthread_outlen) != mszh_dlen) { 251 if (mthread_outlen != mszh_dlen) {
243 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", 252 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
244 c->decomp_size - mthread_outlen, mszh_dlen); 253 mthread_outlen, mszh_dlen);
254 return -1;
245 } 255 }
246 encoded = c->decomp_buf; 256 encoded = c->decomp_buf;
247 len = c->decomp_size; 257 len = c->decomp_size;
248 } else { 258 } else {
249 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf); 259 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size);
250 if (c->decomp_size != mszh_dlen) { 260 if (c->decomp_size != mszh_dlen) {
251 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", 261 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
252 c->decomp_size, mszh_dlen); 262 c->decomp_size, mszh_dlen);
263 return -1;
253 } 264 }
254 encoded = c->decomp_buf; 265 encoded = c->decomp_buf;
255 len = mszh_dlen; 266 len = mszh_dlen;
256 } 267 }
257 break; 268 break;
276 return -1; 287 return -1;
277 } 288 }
278 if (c->flags & FLAG_MULTITHREAD) { 289 if (c->flags & FLAG_MULTITHREAD) {
279 mthread_inlen = *((unsigned int*)encoded); 290 mthread_inlen = *((unsigned int*)encoded);
280 mthread_outlen = *((unsigned int*)(encoded+4)); 291 mthread_outlen = *((unsigned int*)(encoded+4));
292 if (mthread_outlen > c->decomp_size)
293 mthread_outlen = c->decomp_size;
281 c->zstream.next_in = encoded + 8; 294 c->zstream.next_in = encoded + 8;
282 c->zstream.avail_in = mthread_inlen; 295 c->zstream.avail_in = mthread_inlen;
283 c->zstream.next_out = c->decomp_buf; 296 c->zstream.next_out = c->decomp_buf;
284 c->zstream.avail_out = mthread_outlen; 297 c->zstream.avail_out = c->decomp_size;
285 zret = inflate(&(c->zstream), Z_FINISH); 298 zret = inflate(&(c->zstream), Z_FINISH);
286 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { 299 if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
287 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); 300 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret);
288 return -1; 301 return -1;
289 } 302 }
290 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { 303 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) {
291 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", 304 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n",
292 mthread_outlen, c->zstream.total_out); 305 mthread_outlen, c->zstream.total_out);
306 return -1;
293 } 307 }
294 zret = inflateReset(&(c->zstream)); 308 zret = inflateReset(&(c->zstream));
295 if (zret != Z_OK) { 309 if (zret != Z_OK) {
296 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); 310 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret);
297 return -1; 311 return -1;
298 } 312 }
299 c->zstream.next_in = encoded + 8 + mthread_inlen; 313 c->zstream.next_in = encoded + 8 + mthread_inlen;
300 c->zstream.avail_in = len - mthread_inlen; 314 c->zstream.avail_in = len - mthread_inlen;
301 c->zstream.next_out = c->decomp_buf + mthread_outlen; 315 c->zstream.next_out = c->decomp_buf + mthread_outlen;
302 c->zstream.avail_out = mthread_outlen; 316 c->zstream.avail_out = c->decomp_size - mthread_outlen;
303 zret = inflate(&(c->zstream), Z_FINISH); 317 zret = inflate(&(c->zstream), Z_FINISH);
304 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { 318 if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
305 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); 319 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret);
306 return -1; 320 return -1;
307 } 321 }
308 if ((c->decomp_size - mthread_outlen) != (unsigned int)(c->zstream.total_out)) { 322 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) {
309 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", 323 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n",
310 c->decomp_size - mthread_outlen, c->zstream.total_out); 324 mthread_outlen, c->zstream.total_out);
325 return -1;
311 } 326 }
312 } else { 327 } else {
313 c->zstream.next_in = encoded; 328 c->zstream.next_in = encoded;
314 c->zstream.avail_in = len; 329 c->zstream.avail_in = len;
315 c->zstream.next_out = c->decomp_buf; 330 c->zstream.next_out = c->decomp_buf;
320 return -1; 335 return -1;
321 } 336 }
322 if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { 337 if (c->decomp_size != (unsigned int)(c->zstream.total_out)) {
323 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", 338 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
324 c->decomp_size, c->zstream.total_out); 339 c->decomp_size, c->zstream.total_out);
340 return -1;
325 } 341 }
326 } 342 }
327 encoded = c->decomp_buf; 343 encoded = c->decomp_buf;
328 len = c->decomp_size;; 344 len = c->decomp_size;;
329 #else 345 #else
602 * 618 *
603 */ 619 */
604 static int decode_init(AVCodecContext *avctx) 620 static int decode_init(AVCodecContext *avctx)
605 { 621 {
606 LclContext * const c = (LclContext *)avctx->priv_data; 622 LclContext * const c = (LclContext *)avctx->priv_data;
607 int basesize = avctx->width * avctx->height; 623 unsigned int basesize = avctx->width * avctx->height;
624 unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3);
625 unsigned int max_decomp_size;
608 int zret; // Zlib return code 626 int zret; // Zlib return code
609 627
610 c->avctx = avctx; 628 c->avctx = avctx;
611 avctx->has_b_frames = 0; 629 avctx->has_b_frames = 0;
612 630
617 memset(&(c->zstream), 0, sizeof(z_stream)); 635 memset(&(c->zstream), 0, sizeof(z_stream));
618 #endif 636 #endif
619 637
620 if (avctx->extradata_size < 8) { 638 if (avctx->extradata_size < 8) {
621 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); 639 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
640 return 1;
641 }
642
643 // FIXME: find a better way to prevent integer overflow
644 if (((unsigned int)avctx->width > 32000) || ((unsigned int)avctx->height > 32000)) {
645 av_log(avctx, AV_LOG_ERROR, "Bad image size (w = %d, h = %d).\n", avctx->width, avctx->height);
622 return 1; 646 return 1;
623 } 647 }
624 648
625 /* Check codec type */ 649 /* Check codec type */
626 if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || 650 if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) ||
630 654
631 /* Detect image type */ 655 /* Detect image type */
632 switch (c->imgtype = *((char *)avctx->extradata + 4)) { 656 switch (c->imgtype = *((char *)avctx->extradata + 4)) {
633 case IMGTYPE_YUV111: 657 case IMGTYPE_YUV111:
634 c->decomp_size = basesize * 3; 658 c->decomp_size = basesize * 3;
659 max_decomp_size = max_basesize * 3;
635 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); 660 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n");
636 break; 661 break;
637 case IMGTYPE_YUV422: 662 case IMGTYPE_YUV422:
638 c->decomp_size = basesize * 2; 663 c->decomp_size = basesize * 2;
664 max_decomp_size = max_basesize * 2;
639 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); 665 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n");
640 break; 666 break;
641 case IMGTYPE_RGB24: 667 case IMGTYPE_RGB24:
642 c->decomp_size = basesize * 3; 668 c->decomp_size = basesize * 3;
669 max_decomp_size = max_basesize * 3;
643 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); 670 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n");
644 break; 671 break;
645 case IMGTYPE_YUV411: 672 case IMGTYPE_YUV411:
646 c->decomp_size = basesize / 2 * 3; 673 c->decomp_size = basesize / 2 * 3;
674 max_decomp_size = max_basesize / 2 * 3;
647 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); 675 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n");
648 break; 676 break;
649 case IMGTYPE_YUV211: 677 case IMGTYPE_YUV211:
650 c->decomp_size = basesize * 2; 678 c->decomp_size = basesize * 2;
679 max_decomp_size = max_basesize * 2;
651 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); 680 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n");
652 break; 681 break;
653 case IMGTYPE_YUV420: 682 case IMGTYPE_YUV420:
654 c->decomp_size = basesize / 2 * 3; 683 c->decomp_size = basesize / 2 * 3;
684 max_decomp_size = max_basesize / 2 * 3;
655 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); 685 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n");
656 break; 686 break;
657 default: 687 default:
658 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); 688 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
659 return 1; 689 return 1;
704 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); 734 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
705 return 1; 735 return 1;
706 } 736 }
707 737
708 /* Allocate decompression buffer */ 738 /* Allocate decompression buffer */
709 /* 4*8 max overflow space for mszh decomp algorithm */
710 if (c->decomp_size) { 739 if (c->decomp_size) {
711 if ((c->decomp_buf = av_malloc(c->decomp_size+4*8)) == NULL) { 740 if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) {
712 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); 741 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
713 return 1; 742 return 1;
714 } 743 }
715 } 744 }
716 745