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