OLD | NEW |
1 | 1 |
2 /* pngrutil.c - utilities to read a PNG file | 2 /* pngrutil.c - utilities to read a PNG file |
3 * | 3 * |
4 * Last changed in libpng 1.2.45 [July 7, 2011] | 4 * Last changed in libpng 1.2.51 [February 6, 2014] |
5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson | 5 * Copyright (c) 1998-2014 Glenn Randers-Pehrson |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) | 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) | 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
8 * | 8 * |
9 * This code is released under the libpng license. | 9 * This code is released under the libpng license. |
10 * For conditions of distribution and use, see the disclaimer | 10 * For conditions of distribution and use, see the disclaimer |
11 * and license in png.h | 11 * and license in png.h |
12 * | 12 * |
13 * This file contains routines that are only called from within | 13 * This file contains routines that are only called from within |
14 * libpng itself during the course of reading an image. | 14 * libpng itself during the course of reading an image. |
15 */ | 15 */ |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 else if (comp_type == PNG_COMPRESSION_TYPE_BASE) | 332 else if (comp_type == PNG_COMPRESSION_TYPE_BASE) |
333 { | 333 { |
334 png_size_t expanded_size = png_inflate(png_ptr, | 334 png_size_t expanded_size = png_inflate(png_ptr, |
335 (png_bytep)(png_ptr->chunkdata + prefix_size), | 335 (png_bytep)(png_ptr->chunkdata + prefix_size), |
336 chunklength - prefix_size, | 336 chunklength - prefix_size, |
337 0/*output*/, 0/*output size*/); | 337 0/*output*/, 0/*output size*/); |
338 | 338 |
339 /* Now check the limits on this chunk - if the limit fails the | 339 /* Now check the limits on this chunk - if the limit fails the |
340 * compressed data will be removed, the prefix will remain. | 340 * compressed data will be removed, the prefix will remain. |
341 */ | 341 */ |
342 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED | 342 if (prefix_size >= (~(png_size_t)0) - 1 || |
343 if (png_ptr->user_chunk_malloc_max && | 343 expanded_size >= (~(png_size_t)0) - 1 - prefix_size |
344 (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) | 344 #ifdef PNG_USER_CHUNK_MALLOC_MAX |
345 #else | 345 || ((PNG_USER_CHUNK_MALLOC_MAX > 0) && |
346 # ifdef PNG_USER_CHUNK_MALLOC_MAX | |
347 if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && | |
348 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) | 346 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) |
349 # endif | |
350 #endif | 347 #endif |
| 348 ) |
351 png_warning(png_ptr, "Exceeded size limit while expanding chunk"); | 349 png_warning(png_ptr, "Exceeded size limit while expanding chunk"); |
352 | 350 |
353 /* If the size is zero either there was an error and a message | 351 /* If the size is zero either there was an error and a message |
354 * has already been output (warning) or the size really is zero | 352 * has already been output (warning) or the size really is zero |
355 * and we have nothing to do - the code will exit through the | 353 * and we have nothing to do - the code will exit through the |
356 * error case below. | 354 * error case below. |
357 */ | 355 */ |
358 #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ | 356 else if (expanded_size > 0) |
359 defined(PNG_USER_CHUNK_MALLOC_MAX) | |
360 else | |
361 #endif | |
362 if (expanded_size > 0) | |
363 { | 357 { |
364 /* Success (maybe) - really uncompress the chunk. */ | 358 /* Success (maybe) - really uncompress the chunk. */ |
365 png_size_t new_size = 0; | 359 png_size_t new_size = 0; |
366 png_charp text = NULL; | 360 |
367 /* Need to check for both truncation (64-bit platforms) and integer | 361 png_charp text = png_malloc_warn(png_ptr, |
368 * overflow. | 362 prefix_size + expanded_size + 1); |
369 */ | |
370 if (prefix_size + expanded_size > prefix_size && | |
371 prefix_size + expanded_size < 0xffffffffU) | |
372 { | |
373 text = png_malloc_warn(png_ptr, prefix_size + expanded_size + 1); | |
374 } | |
375 | 363 |
376 if (text != NULL) | 364 if (text != NULL) |
377 { | 365 { |
378 png_memcpy(text, png_ptr->chunkdata, prefix_size); | 366 png_memcpy(text, png_ptr->chunkdata, prefix_size); |
379 new_size = png_inflate(png_ptr, | 367 new_size = png_inflate(png_ptr, |
380 (png_bytep)(png_ptr->chunkdata + prefix_size), | 368 (png_bytep)(png_ptr->chunkdata + prefix_size), |
381 chunklength - prefix_size, | 369 chunklength - prefix_size, |
382 (png_bytep)(text + prefix_size), expanded_size); | 370 (png_bytep)(text + prefix_size), expanded_size); |
383 text[prefix_size + expanded_size] = 0; /* just in case */ | 371 text[prefix_size + expanded_size] = 0; /* just in case */ |
384 | 372 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 } | 652 } |
665 | 653 |
666 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); | 654 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); |
667 | 655 |
668 if (length != 0) | 656 if (length != 0) |
669 { | 657 { |
670 png_warning(png_ptr, "Incorrect IEND chunk length"); | 658 png_warning(png_ptr, "Incorrect IEND chunk length"); |
671 } | 659 } |
672 png_crc_finish(png_ptr, length); | 660 png_crc_finish(png_ptr, length); |
673 | 661 |
674 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ | 662 PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ |
675 } | 663 } |
676 | 664 |
677 #ifdef PNG_READ_gAMA_SUPPORTED | 665 #ifdef PNG_READ_gAMA_SUPPORTED |
678 void /* PRIVATE */ | 666 void /* PRIVATE */ |
679 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) | 667 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
680 { | 668 { |
681 png_fixed_point igamma; | 669 png_fixed_point igamma; |
682 #ifdef PNG_FLOATING_POINT_SUPPORTED | 670 #ifdef PNG_FLOATING_POINT_SUPPORTED |
683 float file_gamma; | 671 float file_gamma; |
684 #endif | 672 #endif |
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 png_crc_finish(png_ptr, length); | 1523 png_crc_finish(png_ptr, length); |
1536 return; | 1524 return; |
1537 } | 1525 } |
1538 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) | 1526 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) |
1539 { | 1527 { |
1540 png_warning(png_ptr, "Duplicate hIST chunk"); | 1528 png_warning(png_ptr, "Duplicate hIST chunk"); |
1541 png_crc_finish(png_ptr, length); | 1529 png_crc_finish(png_ptr, length); |
1542 return; | 1530 return; |
1543 } | 1531 } |
1544 | 1532 |
1545 num = length / 2 ; | 1533 if (length > 2*PNG_MAX_PALETTE_LENGTH || |
1546 if (num != (unsigned int) png_ptr->num_palette || num > | 1534 length != (unsigned int) (2*png_ptr->num_palette)) |
1547 (unsigned int) PNG_MAX_PALETTE_LENGTH) | |
1548 { | 1535 { |
1549 png_warning(png_ptr, "Incorrect hIST chunk length"); | 1536 png_warning(png_ptr, "Incorrect hIST chunk length"); |
1550 png_crc_finish(png_ptr, length); | 1537 png_crc_finish(png_ptr, length); |
1551 return; | 1538 return; |
1552 } | 1539 } |
1553 | 1540 |
| 1541 num = length / 2 ; |
| 1542 |
1554 for (i = 0; i < num; i++) | 1543 for (i = 0; i < num; i++) |
1555 { | 1544 { |
1556 png_byte buf[2]; | 1545 png_byte buf[2]; |
1557 | 1546 |
1558 png_crc_read(png_ptr, buf, 2); | 1547 png_crc_read(png_ptr, buf, 2); |
1559 readbuf[i] = png_get_uint_16(buf); | 1548 readbuf[i] = png_get_uint_16(buf); |
1560 } | 1549 } |
1561 | 1550 |
1562 if (png_crc_finish(png_ptr, 0)) | 1551 if (png_crc_finish(png_ptr, 0)) |
1563 return; | 1552 return; |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 #else | 1851 #else |
1863 #ifdef PNG_FIXED_POINT_SUPPORTED | 1852 #ifdef PNG_FIXED_POINT_SUPPORTED |
1864 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); | 1853 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); |
1865 if (swidth == NULL) | 1854 if (swidth == NULL) |
1866 { | 1855 { |
1867 png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); | 1856 png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); |
1868 png_free(png_ptr, png_ptr->chunkdata); | 1857 png_free(png_ptr, png_ptr->chunkdata); |
1869 png_ptr->chunkdata = NULL; | 1858 png_ptr->chunkdata = NULL; |
1870 return; | 1859 return; |
1871 } | 1860 } |
1872 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); | 1861 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep) + 1); |
1873 #endif | 1862 #endif |
1874 #endif | 1863 #endif |
1875 | 1864 |
1876 for (ep = png_ptr->chunkdata; *ep; ep++) | 1865 for (ep = png_ptr->chunkdata + 1; *ep; ep++) |
1877 /* Empty loop */ ; | 1866 /* Empty loop */ ; |
1878 ep++; | 1867 ep++; |
1879 | 1868 |
1880 if (png_ptr->chunkdata + slength < ep) | 1869 if (png_ptr->chunkdata + slength < ep) |
1881 { | 1870 { |
1882 png_warning(png_ptr, "Truncated sCAL chunk"); | 1871 png_warning(png_ptr, "Truncated sCAL chunk"); |
1883 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) | 1872 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) |
1884 png_free(png_ptr, swidth); | 1873 png_free(png_ptr, swidth); |
1885 #endif | 1874 #endif |
1886 png_free(png_ptr, png_ptr->chunkdata); | 1875 png_free(png_ptr, png_ptr->chunkdata); |
(...skipping 19 matching lines...) Expand all Loading... |
1906 if (sheight == NULL) | 1895 if (sheight == NULL) |
1907 { | 1896 { |
1908 png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); | 1897 png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); |
1909 png_free(png_ptr, png_ptr->chunkdata); | 1898 png_free(png_ptr, png_ptr->chunkdata); |
1910 png_ptr->chunkdata = NULL; | 1899 png_ptr->chunkdata = NULL; |
1911 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) | 1900 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) |
1912 png_free(png_ptr, swidth); | 1901 png_free(png_ptr, swidth); |
1913 #endif | 1902 #endif |
1914 return; | 1903 return; |
1915 } | 1904 } |
1916 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); | 1905 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep) + 1); |
1917 #endif | 1906 #endif |
1918 #endif | 1907 #endif |
1919 | 1908 |
1920 if (png_ptr->chunkdata + slength < ep | 1909 if (png_ptr->chunkdata + slength < ep |
1921 #ifdef PNG_FLOATING_POINT_SUPPORTED | 1910 #ifdef PNG_FLOATING_POINT_SUPPORTED |
1922 || width <= 0. || height <= 0. | 1911 || width <= 0. || height <= 0. |
1923 #endif | 1912 #endif |
1924 ) | 1913 ) |
1925 { | 1914 { |
1926 png_warning(png_ptr, "Invalid sCAL data"); | 1915 png_warning(png_ptr, "Invalid sCAL data"); |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2469 png_free(png_ptr, png_ptr->unknown_chunk.data); | 2458 png_free(png_ptr, png_ptr->unknown_chunk.data); |
2470 png_ptr->unknown_chunk.data = NULL; | 2459 png_ptr->unknown_chunk.data = NULL; |
2471 } | 2460 } |
2472 else | 2461 else |
2473 #endif | 2462 #endif |
2474 skip = length; | 2463 skip = length; |
2475 | 2464 |
2476 png_crc_finish(png_ptr, skip); | 2465 png_crc_finish(png_ptr, skip); |
2477 | 2466 |
2478 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED | 2467 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED |
2479 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ | 2468 PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ |
2480 #endif | 2469 #endif |
2481 } | 2470 } |
2482 | 2471 |
2483 /* This function is called to verify that a chunk name is valid. | 2472 /* This function is called to verify that a chunk name is valid. |
2484 This function can't have the "critical chunk check" incorporated | 2473 This function can't have the "critical chunk check" incorporated |
2485 into it, since in the future we will need to be able to call user | 2474 into it, since in the future we will need to be able to call user |
2486 functions to handle unknown critical chunks after we check that | 2475 functions to handle unknown critical chunks after we check that |
2487 the chunk name itself is valid. */ | 2476 the chunk name itself is valid. */ |
2488 | 2477 |
2489 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) | 2478 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2925 } | 2914 } |
2926 sp -= pixel_bytes; | 2915 sp -= pixel_bytes; |
2927 } | 2916 } |
2928 break; | 2917 break; |
2929 } | 2918 } |
2930 } | 2919 } |
2931 row_info->width = final_width; | 2920 row_info->width = final_width; |
2932 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); | 2921 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); |
2933 } | 2922 } |
2934 #ifndef PNG_READ_PACKSWAP_SUPPORTED | 2923 #ifndef PNG_READ_PACKSWAP_SUPPORTED |
2935 transformations = transformations; /* Silence compiler warning */ | 2924 PNG_UNUSED(transformations) /* Silence compiler warning */ |
2936 #endif | 2925 #endif |
2937 } | 2926 } |
2938 #endif /* PNG_READ_INTERLACING_SUPPORTED */ | 2927 #endif /* PNG_READ_INTERLACING_SUPPORTED */ |
2939 | 2928 |
2940 void /* PRIVATE */ | 2929 void /* PRIVATE */ |
2941 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, | 2930 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, |
2942 png_bytep prev_row, int filter) | 2931 png_bytep prev_row, int filter) |
2943 { | 2932 { |
2944 png_debug(1, "in png_read_filter_row"); | 2933 png_debug(1, "in png_read_filter_row"); |
2945 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); | 2934 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3388 png_debug1(3, "height = %lu,", png_ptr->height); | 3377 png_debug1(3, "height = %lu,", png_ptr->height); |
3389 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); | 3378 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); |
3390 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); | 3379 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); |
3391 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); | 3380 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); |
3392 png_debug1(3, "irowbytes = %lu", | 3381 png_debug1(3, "irowbytes = %lu", |
3393 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); | 3382 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); |
3394 | 3383 |
3395 png_ptr->flags |= PNG_FLAG_ROW_INIT; | 3384 png_ptr->flags |= PNG_FLAG_ROW_INIT; |
3396 } | 3385 } |
3397 #endif /* PNG_READ_SUPPORTED */ | 3386 #endif /* PNG_READ_SUPPORTED */ |
OLD | NEW |