From a0bb96c34e65378853ee518bac502842d26c2d1a Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Wed, 22 Jul 2009 11:50:02 -0400 Subject: Update libpng to 1.2.38 to patch a minor security issue. --- pngpread.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 178 insertions(+), 45 deletions(-) (limited to 'pngpread.c') diff --git a/pngpread.c b/pngpread.c index b06fbad..9eddd6e 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,18 +1,21 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.2.32 [September 18, 2008] - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2008 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [July 16, 2009] + * Copyright (c) 1998-2009 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* push model modes */ +/* Push model modes */ #define PNG_READ_SIG_MODE 0 #define PNG_READ_CHUNK_MODE 1 #define PNG_READ_IDAT_MODE 2 @@ -27,7 +30,9 @@ void PNGAPI png_process_data(png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size) { - if (png_ptr == NULL || info_ptr == NULL) return; + if (png_ptr == NULL || info_ptr == NULL) + return; + png_push_restore_buffer(png_ptr, buffer, buffer_size); while (png_ptr->buffer_size) @@ -42,7 +47,9 @@ png_process_data(png_structp png_ptr, png_infop info_ptr, void /* PRIVATE */ png_process_some_data(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr == NULL) return; + if (png_ptr == NULL) + return; + switch (png_ptr->process_mode) { case PNG_READ_SIG_MODE: @@ -50,22 +57,26 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_sig(png_ptr, info_ptr); break; } + case PNG_READ_CHUNK_MODE: { png_push_read_chunk(png_ptr, info_ptr); break; } + case PNG_READ_IDAT_MODE: { png_push_read_IDAT(png_ptr); break; } + #if defined(PNG_READ_tEXt_SUPPORTED) case PNG_READ_tEXt_MODE: { png_push_read_tEXt(png_ptr, info_ptr); break; } + #endif #if defined(PNG_READ_zTXt_SUPPORTED) case PNG_READ_zTXt_MODE: @@ -73,6 +84,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_zTXt(png_ptr, info_ptr); break; } + #endif #if defined(PNG_READ_iTXt_SUPPORTED) case PNG_READ_iTXt_MODE: @@ -80,12 +92,14 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_iTXt(png_ptr, info_ptr); break; } + #endif case PNG_SKIP_MODE: { png_push_crc_finish(png_ptr); break; } + default: { png_ptr->buffer_size = 0; @@ -224,13 +238,16 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { if (png_ptr->push_length != 13) png_error(png_ptr, "Invalid IHDR length"); + if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } + png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); } + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -238,11 +255,13 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); png_ptr->process_mode = PNG_READ_DONE_MODE; png_push_have_end(png_ptr, info_ptr); } + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) { @@ -251,20 +270,26 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); } } + #endif else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) { @@ -275,23 +300,26 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { /* If we reach an IDAT chunk, this means we have read all of the * header chunks, and we can start reading the image (or if this * is called after the image has been read - we have an error). */ - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before IDAT"); - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); if (png_ptr->mode & PNG_HAVE_IDAT) { if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) - if (png_ptr->push_length == 0) - return; + if (png_ptr->push_length == 0) + return; if (png_ptr->mode & PNG_AFTER_IDAT) png_error(png_ptr, "Too many IDAT's found"); @@ -305,6 +333,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_ptr->zstream.next_out = png_ptr->row_buf; return; } + #if defined(PNG_READ_gAMA_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) { @@ -313,8 +342,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sBIT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) @@ -324,8 +355,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_cHRM_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) @@ -335,8 +368,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sRGB_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) @@ -346,8 +381,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_iCCP_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) @@ -357,8 +394,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sPLT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) @@ -368,8 +407,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_tRNS_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) @@ -379,8 +420,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_bKGD_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) @@ -390,8 +433,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_hIST_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) @@ -401,8 +446,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) @@ -412,8 +459,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_oFFs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) @@ -423,9 +472,11 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); } #endif + #if defined(PNG_READ_pCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) { @@ -434,8 +485,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) @@ -445,8 +498,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_tIME_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) @@ -456,8 +511,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) @@ -467,8 +524,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) @@ -478,8 +537,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) @@ -489,8 +550,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); } + #endif else { @@ -565,7 +628,9 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { png_bytep ptr; - if (png_ptr == NULL) return; + if (png_ptr == NULL) + return; + ptr = buffer; if (png_ptr->save_buffer_size) { @@ -589,6 +654,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) if (length < png_ptr->current_buffer_size) save_size = length; + else save_size = png_ptr->current_buffer_size; @@ -629,6 +695,7 @@ png_push_save_buffer(png_structp png_ptr) { png_error(png_ptr, "Potential overflow of save_buffer"); } + new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; old_buffer = png_ptr->save_buffer; png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, @@ -697,7 +764,8 @@ png_push_read_IDAT(png_structp png_ptr) if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) { save_size = (png_size_t)png_ptr->idat_size; - /* check for overflow */ + + /* Check for overflow */ if ((png_uint_32)save_size != png_ptr->idat_size) png_error(png_ptr, "save_size overflowed in pngpread"); } @@ -705,8 +773,10 @@ png_push_read_IDAT(png_structp png_ptr) save_size = png_ptr->save_buffer_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + png_ptr->idat_size -= save_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; @@ -719,7 +789,8 @@ png_push_read_IDAT(png_structp png_ptr) if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) { save_size = (png_size_t)png_ptr->idat_size; - /* check for overflow */ + + /* Check for overflow */ if ((png_uint_32)save_size != png_ptr->idat_size) png_error(png_ptr, "save_size overflowed in pngpread"); } @@ -769,6 +840,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, { if (png_ptr->zstream.avail_in) png_error(png_ptr, "Extra compressed data"); + if (!(png_ptr->zstream.avail_out)) { png_push_process_row(png_ptr); @@ -780,6 +852,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, } else if (ret == Z_BUF_ERROR) break; + else png_error(png_ptr, "Decompression Error"); } @@ -801,6 +874,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.next_out = png_ptr->row_buf; } + else break; } @@ -829,7 +903,7 @@ png_push_process_row(png_structp png_ptr) png_do_read_transformations(png_ptr); #if defined(PNG_READ_INTERLACING_SUPPORTED) - /* blow up interlaced rows to full size */ + /* Blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) @@ -847,9 +921,10 @@ png_push_process_row(png_structp png_ptr) for (i = 0; i < 8 && png_ptr->pass == 0; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */ + png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ } - if (png_ptr->pass == 2) /* pass 1 might be empty */ + + if (png_ptr->pass == 2) /* Pass 1 might be empty */ { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { @@ -857,6 +932,7 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + if (png_ptr->pass == 4 && png_ptr->height <= 4) { for (i = 0; i < 2 && png_ptr->pass == 4; i++) @@ -865,13 +941,16 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + if (png_ptr->pass == 6 && png_ptr->height <= 4) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } + break; } + case 1: { int i; @@ -880,7 +959,8 @@ png_push_process_row(png_structp png_ptr) png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 2) /* skip top 4 generated rows */ + + if (png_ptr->pass == 2) /* Skip top 4 generated rows */ { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { @@ -888,22 +968,27 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + break; } + case 2: { int i; + for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } + for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 4) /* pass 3 might be empty */ + + if (png_ptr->pass == 4) /* Pass 3 might be empty */ { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { @@ -911,17 +996,21 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + break; } + case 3: { int i; + for (i = 0; i < 4 && png_ptr->pass == 3; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 4) /* skip top two generated rows */ + + if (png_ptr->pass == 4) /* Skip top two generated rows */ { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { @@ -929,49 +1018,61 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + break; } + case 4: { int i; + for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } + for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 6) /* pass 5 might be empty */ + + if (png_ptr->pass == 6) /* Pass 5 might be empty */ { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } + break; } + case 5: { int i; + for (i = 0; i < 2 && png_ptr->pass == 5; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 6) /* skip top generated row */ + + if (png_ptr->pass == 6) /* Skip top generated row */ { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } + break; } case 6: { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); + if (png_ptr->pass != 6) break; + png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } @@ -989,18 +1090,18 @@ void /* PRIVATE */ png_read_push_finish_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ + /* Start of interlace block */ PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ + /* Offset to next interlace block */ PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - /* start of interlace block in the y direction */ + /* Start of interlace block in the y direction */ PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - /* offset to next interlace block in the y direction */ + /* Offset to next interlace block in the y direction */ PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Height of interlace block. This is not currently used - if you need @@ -1013,6 +1114,7 @@ png_read_push_finish_row(png_structp png_ptr) if (png_ptr->row_number < png_ptr->num_rows) return; +#if defined(PNG_READ_INTERLACING_SUPPORTED) if (png_ptr->interlaced) { png_ptr->row_number = 0; @@ -1028,6 +1130,7 @@ png_read_push_finish_row(png_structp png_ptr) if (png_ptr->pass > 7) png_ptr->pass--; + if (png_ptr->pass >= 7) break; @@ -1049,6 +1152,7 @@ png_read_push_finish_row(png_structp png_ptr) } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ } #if defined(PNG_READ_tEXt_SUPPORTED) @@ -1059,7 +1163,7 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place tEXt"); - info_ptr = info_ptr; /* to quiet some compiler warnings */ + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #ifdef PNG_MAX_MALLOC_64K @@ -1091,8 +1195,10 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) if (png_ptr->buffer_size < png_ptr->current_text_left) text_size = png_ptr->buffer_size; + else text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; @@ -1120,7 +1226,7 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) key = png_ptr->current_text; for (text = key; *text; text++) - /* empty loop */ ; + /* Empty loop */ ; if (text < key + png_ptr->current_text_size) text++; @@ -1155,7 +1261,7 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place zTXt"); - info_ptr = info_ptr; /* to quiet some compiler warnings */ + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #ifdef PNG_MAX_MALLOC_64K @@ -1189,8 +1295,10 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) text_size = png_ptr->buffer_size; + else text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; @@ -1214,7 +1322,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) key = png_ptr->current_text; for (text = key; *text; text++) - /* empty loop */ ; + /* Empty loop */ ; /* zTXt can't have zero text */ if (text >= key + png_ptr->current_text_size) @@ -1226,7 +1334,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text++; - if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */ + if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ { png_ptr->current_text = NULL; png_free(png_ptr, key); @@ -1265,11 +1373,15 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text = (png_charp)png_malloc(png_ptr, (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + key_size + 1)); + png_memcpy(text + key_size, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_memcpy(text, key, key_size); + text_size = key_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; } else @@ -1280,10 +1392,13 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text = (png_charp)png_malloc(png_ptr, text_size + (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); + png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } @@ -1347,7 +1462,7 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place iTXt"); - info_ptr = info_ptr; /* to quiet some compiler warnings */ + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #ifdef PNG_MAX_MALLOC_64K @@ -1380,8 +1495,10 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) if (png_ptr->buffer_size < png_ptr->current_text_left) text_size = png_ptr->buffer_size; + else text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; @@ -1412,23 +1529,25 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) key = png_ptr->current_text; for (lang = key; *lang; lang++) - /* empty loop */ ; + /* Empty loop */ ; if (lang < key + png_ptr->current_text_size - 3) lang++; comp_flag = *lang++; - lang++; /* skip comp_type, always zero */ + lang++; /* Skip comp_type, always zero */ for (lang_key = lang; *lang_key; lang_key++) - /* empty loop */ ; - lang_key++; /* skip NUL separator */ + /* Empty loop */ ; + + lang_key++; /* Skip NUL separator */ text=lang_key; + if (lang_key < key + png_ptr->current_text_size - 1) { for (; *text; text++) - /* empty loop */ ; + /* Empty loop */ ; } if (text < key + png_ptr->current_text_size) @@ -1436,6 +1555,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = comp_flag + 2; text_ptr->key = key; text_ptr->lang = lang; @@ -1477,7 +1597,7 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_chunk_error(png_ptr, "unknown critical chunk"); - info_ptr = info_ptr; /* to quiet some compiler warnings */ + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) @@ -1498,23 +1618,28 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 = '\0'; png_ptr->unknown_chunk.size = (png_size_t)length; + if (length == 0) png_ptr->unknown_chunk.data = NULL; + else { png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, (png_uint_32)length); png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); } + #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) if (png_ptr->read_user_chunk_fn != NULL) { - /* callback to user unknown chunk handler */ + /* Callback to user unknown chunk handler */ int ret; ret = (*(png_ptr->read_user_chunk_fn)) (png_ptr, &png_ptr->unknown_chunk); + if (ret < 0) png_chunk_error(png_ptr, "error in user chunk"); + if (ret == 0) { if (!(png_ptr->chunk_name[0] & 0x20)) @@ -1525,12 +1650,14 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 &png_ptr->unknown_chunk, 1); } } + else #endif png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); png_free(png_ptr, png_ptr->unknown_chunk.data); png_ptr->unknown_chunk.data = NULL; } + else #endif skip=length; @@ -1567,7 +1694,9 @@ png_progressive_combine_row (png_structp png_ptr, PNG_CONST int FARDATA png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; #endif - if (png_ptr == NULL) return; + if (png_ptr == NULL) + return; + if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); } @@ -1577,7 +1706,9 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn) { - if (png_ptr == NULL) return; + if (png_ptr == NULL) + return; + png_ptr->info_fn = info_fn; png_ptr->row_fn = row_fn; png_ptr->end_fn = end_fn; @@ -1588,7 +1719,9 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, png_voidp PNGAPI png_get_progressive_ptr(png_structp png_ptr) { - if (png_ptr == NULL) return (NULL); + if (png_ptr == NULL) + return (NULL); + return png_ptr->io_ptr; } #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -- cgit v1.1