[libpng15] Do png_check_keyword in png_set_*()

This commit is contained in:
John Bowler 2015-12-13 18:10:53 -06:00 committed by Glenn Randers-Pehrson
parent a510a813ef
commit e40ac66f81
3 changed files with 127 additions and 204 deletions

View File

@ -901,13 +901,6 @@ PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr,
png_const_uint_16p hist, int num_hist)); png_const_uint_16p hist, int num_hist));
#endif #endif
/* Chunks that have keywords */
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
png_const_charp key, png_charpp new_key));
#endif
#ifdef PNG_WRITE_tEXt_SUPPORTED #ifdef PNG_WRITE_tEXt_SUPPORTED
PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key,
png_const_charp text, png_size_t text_len)); png_const_charp text, png_size_t text_len));

249
pngset.c
View File

@ -20,6 +20,60 @@
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) ||\
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
* and if invalid, correct the keyword rather than discarding the entire
* chunk. The PNG 1.0 specification requires keywords 1-79 characters in
* length, forbids leading or trailing whitespace, multiple internal spaces,
* and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
*
* The 'new_key' buffer must be 80 characters in size (for the keyword plus a
* trailing '\0'). If this routine returns 0 then there was no keyword, or a
* valid one could not be generated, and the caller must handle the error by not
* setting the keyword.
*/
static png_uint_32
png_check_keyword(png_const_charp key, png_bytep new_key)
{
png_uint_32 key_len = 0;
int space = 1;
if (key == NULL)
{
*new_key = 0;
return 0;
}
while (*key && key_len < 79)
{
png_byte ch = (png_byte)*key++;
if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
*new_key++ = ch, ++key_len, space = 0;
else if (space == 0)
{
/* A space or an invalid character when one wasn't seen immediately
* before; output just a space.
*/
*new_key++ = 32, ++key_len, space = 1;
}
}
if (key_len > 0 && space != 0) /* trailing space */
--key_len, --new_key;
/* Terminate the keyword */
*new_key = 0;
if (key_len == 0)
return 0;
return key_len;
}
#endif /* TEXT || pCAL || iCCP || sPLT */
#ifdef PNG_bKGD_SUPPORTED #ifdef PNG_bKGD_SUPPORTED
void PNGAPI void PNGAPI
png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
@ -278,6 +332,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
int nparams, png_const_charp units, png_charpp params) int nparams, png_const_charp units, png_charpp params)
{ {
png_byte new_purpose[80];
png_size_t length; png_size_t length;
int i; int i;
@ -286,7 +341,15 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
length = png_strlen(purpose) + 1; length = png_check_keyword(purpose, new_purpose);
if (length == 0)
{
png_warning(png_ptr, "pCAL: invalid purpose keyword");
return;
}
++length;
png_debug1(3, "allocating purpose for info (%lu bytes)", png_debug1(3, "allocating purpose for info (%lu bytes)",
(unsigned long)length); (unsigned long)length);
@ -309,7 +372,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
return; return;
} }
png_memcpy(info_ptr->pcal_purpose, purpose, length); png_memcpy(info_ptr->pcal_purpose, new_purpose, length);
png_debug(3, "storing X0, X1, type, and nparams in info"); png_debug(3, "storing X0, X1, type, and nparams in info");
info_ptr->pcal_X0 = X0; info_ptr->pcal_X0 = X0;
@ -614,6 +677,7 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
png_const_charp name, int compression_type, png_const_charp name, int compression_type,
png_const_bytep profile, png_uint_32 proflen) png_const_bytep profile, png_uint_32 proflen)
{ {
png_byte new_name[80];
png_charp new_iccp_name; png_charp new_iccp_name;
png_bytep new_iccp_profile; png_bytep new_iccp_profile;
png_size_t length; png_size_t length;
@ -623,7 +687,15 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
return; return;
length = png_strlen(name)+1; length = png_check_keyword(name, new_name);
if (length == 0)
{
png_warning(png_ptr, "iCCP: invalid keyword");
return;
}
++length;
new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
if (new_iccp_name == NULL) if (new_iccp_name == NULL)
@ -632,7 +704,7 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
return; return;
} }
png_memcpy(new_iccp_name, name, length); png_memcpy(new_iccp_name, new_name, length);
new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
if (new_iccp_profile == NULL) if (new_iccp_profile == NULL)
@ -748,6 +820,7 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr,
} }
for (i = 0; i < num_text; i++) for (i = 0; i < num_text; i++)
{ {
png_byte new_key[80], new_lang[80];
png_size_t text_length, key_len; png_size_t text_length, key_len;
png_size_t lang_len, lang_key_len; png_size_t lang_len, lang_key_len;
png_textp textp = &(info_ptr->text[info_ptr->num_text]); png_textp textp = &(info_ptr->text[info_ptr->num_text]);
@ -762,7 +835,13 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr,
continue; continue;
} }
key_len = png_strlen(text_ptr[i].key); key_len = png_check_keyword(text_ptr[i].key, new_key);
if (key_len == 0)
{
png_warning(png_ptr, "invalid text keyword");
continue;
}
if (text_ptr[i].compression <= 0) if (text_ptr[i].compression <= 0)
{ {
@ -775,8 +854,9 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr,
{ {
/* Set iTXt data */ /* Set iTXt data */
/* Zero length language is OK */
if (text_ptr[i].lang != NULL) if (text_ptr[i].lang != NULL)
lang_len = png_strlen(text_ptr[i].lang); lang_len = png_check_keyword(text_ptr[i].lang, new_lang);
else else
lang_len = 0; lang_len = 0;
@ -824,7 +904,7 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr,
(key_len + lang_len + lang_key_len + text_length + 4), (key_len + lang_len + lang_key_len + text_length + 4),
textp->key); textp->key);
png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); png_memcpy(textp->key, new_key, (png_size_t)(key_len));
*(textp->key + key_len) = '\0'; *(textp->key + key_len) = '\0';
if (text_ptr[i].compression > 0) if (text_ptr[i].compression > 0)
@ -976,7 +1056,7 @@ png_set_sPLT(png_structp png_ptr,
*/ */
{ {
png_sPLT_tp np; png_sPLT_tp np;
int i; int i, j;
size_t element_size; size_t element_size;
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
@ -1008,13 +1088,22 @@ png_set_sPLT(png_structp png_ptr,
png_free(png_ptr, info_ptr->splt_palettes); png_free(png_ptr, info_ptr->splt_palettes);
info_ptr->splt_palettes=NULL; info_ptr->splt_palettes=NULL;
for (i = 0; i < nentries; i++) for (i = j = 0; i < nentries; i++)
{ {
png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; png_sPLT_tp to = np + info_ptr->splt_palettes_num + j;
png_const_sPLT_tp from = entries + i; png_const_sPLT_tp from = entries + i;
png_byte new_name[80];
png_size_t length; png_size_t length;
length = png_strlen(from->name) + 1; length = png_check_keyword(from->name, new_name);
if (length == 0)
{
png_warning(png_ptr, "sPLT: invalid keyword");
continue;
}
++length; /* for trailing '\0' */
to->name = (png_charp)png_malloc_warn(png_ptr, length); to->name = (png_charp)png_malloc_warn(png_ptr, length);
if (to->name == NULL) if (to->name == NULL)
@ -1024,7 +1113,7 @@ png_set_sPLT(png_structp png_ptr,
continue; continue;
} }
png_memcpy(to->name, from->name, length); png_memcpy(to->name, new_name, length);
to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
from->nentries * png_sizeof(png_sPLT_entry)); from->nentries * png_sizeof(png_sPLT_entry));
@ -1042,10 +1131,11 @@ png_set_sPLT(png_structp png_ptr,
to->nentries = from->nentries; to->nentries = from->nentries;
to->depth = from->depth; to->depth = from->depth;
++j;
} }
info_ptr->splt_palettes = np; info_ptr->splt_palettes = np;
info_ptr->splt_palettes_num += nentries; info_ptr->splt_palettes_num = j;
info_ptr->valid |= PNG_INFO_sPLT; info_ptr->valid |= PNG_INFO_sPLT;
info_ptr->free_me |= PNG_FREE_SPLT; info_ptr->free_me |= PNG_FREE_SPLT;
} }
@ -1348,137 +1438,4 @@ png_set_check_for_invalid_index(png_structp png_ptr, int allowed)
png_ptr->num_palette_max = -1; png_ptr->num_palette_max = -1;
} }
#endif #endif
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
* and if invalid, correct the keyword rather than discarding the entire
* chunk. The PNG 1.0 specification requires keywords 1-79 characters in
* length, forbids leading or trailing whitespace, multiple internal spaces,
* and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
*
* The new_key is allocated to hold the corrected keyword and must be freed
* by the calling routine. This avoids problems with trying to write to
* static keywords without having to have duplicate copies of the strings.
*/
png_size_t /* PRIVATE */
png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key)
{
png_size_t key_len;
png_const_charp ikp;
png_charp kp, dp;
int kflag;
int kwarn=0;
png_debug(1, "in png_check_keyword");
*new_key = NULL;
if (key == NULL || (key_len = png_strlen(key)) == 0)
{
png_warning(png_ptr, "zero length keyword");
return ((png_size_t)0);
}
png_debug1(2, "Keyword to be checked is '%s'", key);
*new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
if (*new_key == NULL)
{
png_warning(png_ptr, "Out of memory while procesing keyword");
return ((png_size_t)0);
}
/* Replace non-printing characters with a blank and print a warning */
for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++)
{
if ((png_byte)*ikp < 0x20 ||
((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1))
{
PNG_WARNING_PARAMETERS(p)
png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x,
(png_byte)*ikp);
png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1");
*dp = ' ';
}
else
{
*dp = *ikp;
}
}
*dp = '\0';
/* Remove any trailing white space. */
kp = *new_key + key_len - 1;
if (*kp == ' ')
{
png_warning(png_ptr, "trailing spaces removed from keyword");
while (key_len && *kp == ' ')
{
*(kp--) = '\0';
key_len--;
}
}
/* Remove any leading white space. */
kp = *new_key;
if (*kp == ' ')
{
png_warning(png_ptr, "leading spaces removed from keyword");
while (*kp == ' ')
{
kp++;
key_len--;
}
}
png_debug1(2, "Checking for multiple internal spaces in '%s'", kp);
/* Remove multiple internal spaces. */
for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
{
if (*kp == ' ' && kflag == 0)
{
*(dp++) = *kp;
kflag = 1;
}
else if (*kp == ' ')
{
key_len--;
kwarn = 1;
}
else
{
*(dp++) = *kp;
kflag = 0;
}
}
*dp = '\0';
if (kwarn != 0)
png_warning(png_ptr, "extra interior spaces removed from keyword");
if (key_len == 0)
{
png_free(png_ptr, *new_key);
png_warning(png_ptr, "Zero length keyword");
}
if (key_len > 79)
{
png_warning(png_ptr, "keyword length must be 1 - 79 characters");
(*new_key)[79] = '\0';
key_len = 79;
}
return (key_len);
}
#endif /* TEXT || pCAL) || iCCP || sPLT */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

View File

@ -1099,7 +1099,6 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
png_const_charp profile, int profile_len) png_const_charp profile, int profile_len)
{ {
png_size_t name_len; png_size_t name_len;
png_charp new_name;
compression_state comp; compression_state comp;
int embedded_profile_len = 0; int embedded_profile_len = 0;
@ -1111,8 +1110,7 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
comp.input = NULL; comp.input = NULL;
comp.input_len = 0; comp.input_len = 0;
if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) name_len = png_strlen(name);
return;
if (compression_type != PNG_COMPRESSION_TYPE_BASE) if (compression_type != PNG_COMPRESSION_TYPE_BASE)
png_warning(png_ptr, "Unknown compression type in iCCP chunk"); png_warning(png_ptr, "Unknown compression type in iCCP chunk");
@ -1131,8 +1129,6 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Embedded profile length in iCCP chunk is negative"); "Embedded profile length in iCCP chunk is negative");
png_free(png_ptr, new_name);
return; return;
} }
@ -1140,8 +1136,6 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Embedded profile length too large in iCCP chunk"); "Embedded profile length too large in iCCP chunk");
png_free(png_ptr, new_name);
return; return;
} }
@ -1161,10 +1155,14 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
png_write_chunk_header(png_ptr, png_iCCP, png_write_chunk_header(png_ptr, png_iCCP,
(png_uint_32)(name_len + profile_len + 2)); (png_uint_32)(name_len + profile_len + 2));
new_name[name_len + 1] = 0x00; png_write_chunk_data(png_ptr, (png_bytep)name, name_len);
png_write_chunk_data(png_ptr, (png_bytep)new_name, {
(png_size_t)(name_len + 2)); png_byte buffer[2];
buffer[0] = 0; /* terminate name */
buffer[1] = 0xFFU & compression_type;
png_write_chunk_data(png_ptr, buffer, 2);
}
if (profile_len != 0) if (profile_len != 0)
{ {
@ -1172,7 +1170,6 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
} }
png_write_chunk_end(png_ptr); png_write_chunk_end(png_ptr);
png_free(png_ptr, new_name);
} }
#endif #endif
@ -1182,7 +1179,6 @@ void /* PRIVATE */
png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
{ {
png_size_t name_len; png_size_t name_len;
png_charp new_name;
png_byte entrybuf[10]; png_byte entrybuf[10];
png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
png_size_t palette_size = entry_size * spalette->nentries; png_size_t palette_size = entry_size * spalette->nentries;
@ -1193,14 +1189,13 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
png_debug(1, "in png_write_sPLT"); png_debug(1, "in png_write_sPLT");
if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) name_len = png_strlen(spalette->name);
return;
/* Make sure we include the NULL after the name */ /* Make sure we include the NULL after the name */
png_write_chunk_header(png_ptr, png_sPLT, png_write_chunk_header(png_ptr, png_sPLT,
(png_uint_32)(name_len + 2 + palette_size)); (png_uint_32)(name_len + 2 + palette_size));
png_write_chunk_data(png_ptr, (png_bytep)new_name, png_write_chunk_data(png_ptr, (png_bytep)spalette->name,
(png_size_t)(name_len + 1)); (png_size_t)(name_len + 1));
png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
@ -1256,7 +1251,6 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
#endif #endif
png_write_chunk_end(png_ptr); png_write_chunk_end(png_ptr);
png_free(png_ptr, new_name);
} }
#endif #endif
@ -1519,12 +1513,10 @@ png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
png_size_t text_len) png_size_t text_len)
{ {
png_size_t key_len; png_size_t key_len;
png_charp new_key;
png_debug(1, "in png_write_tEXt"); png_debug(1, "in png_write_tEXt");
if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) key_len = strlen(key);
return;
if (text == NULL || *text == '\0') if (text == NULL || *text == '\0')
text_len = 0; text_len = 0;
@ -1541,7 +1533,7 @@ png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
* any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
* The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
*/ */
png_write_chunk_data(png_ptr, (png_bytep)new_key, png_write_chunk_data(png_ptr, (png_bytep)key,
(png_size_t)(key_len + 1)); (png_size_t)(key_len + 1));
if (text_len != 0) if (text_len != 0)
@ -1549,7 +1541,6 @@ png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
(png_size_t)text_len); (png_size_t)text_len);
png_write_chunk_end(png_ptr); png_write_chunk_end(png_ptr);
png_free(png_ptr, new_key);
} }
#endif #endif
@ -1561,7 +1552,6 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
{ {
png_size_t key_len; png_size_t key_len;
png_byte buf; png_byte buf;
png_charp new_key;
compression_state comp; compression_state comp;
png_debug(1, "in png_write_zTXt"); png_debug(1, "in png_write_zTXt");
@ -1572,16 +1562,11 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
comp.input = NULL; comp.input = NULL;
comp.input_len = 0; comp.input_len = 0;
if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) key_len = strlen(key);
{
png_free(png_ptr, new_key);
return;
}
if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
{ {
png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); png_write_tEXt(png_ptr, key, text, (png_size_t)0);
png_free(png_ptr, new_key);
return; return;
} }
@ -1596,11 +1581,9 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
(png_uint_32)(key_len+text_len + 2)); (png_uint_32)(key_len+text_len + 2));
/* Write key */ /* Write key */
png_write_chunk_data(png_ptr, (png_bytep)new_key, png_write_chunk_data(png_ptr, (png_bytep)key,
(png_size_t)(key_len + 1)); (png_size_t)(key_len + 1));
png_free(png_ptr, new_key);
buf = (png_byte)compression; buf = (png_byte)compression;
/* Write compression */ /* Write compression */
@ -1621,8 +1604,6 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
png_const_charp lang, png_const_charp lang_key, png_const_charp text) png_const_charp lang, png_const_charp lang_key, png_const_charp text)
{ {
png_size_t lang_len, key_len, lang_key_len, text_len; png_size_t lang_len, key_len, lang_key_len, text_len;
png_charp new_lang;
png_charp new_key = NULL;
png_byte cbuf[2]; png_byte cbuf[2];
compression_state comp; compression_state comp;
@ -1633,15 +1614,13 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
comp.output_ptr = NULL; comp.output_ptr = NULL;
comp.input = NULL; comp.input = NULL;
if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) key_len = png_strlen(key);
return;
if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) if (lang == NULL)
{
png_warning(png_ptr, "Empty language field in iTXt chunk");
new_lang = NULL;
lang_len = 0; lang_len = 0;
}
else
lang_len = png_strlen(lang);
if (lang_key == NULL) if (lang_key == NULL)
lang_key_len = 0; lang_key_len = 0;
@ -1676,7 +1655,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
* any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
* The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
*/ */
png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); png_write_chunk_data(png_ptr, (png_bytep)key, (png_size_t)(key_len + 1));
/* Set the compression flag */ /* Set the compression flag */
if (compression == PNG_ITXT_COMPRESSION_NONE || if (compression == PNG_ITXT_COMPRESSION_NONE ||
@ -1692,7 +1671,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
cbuf[0] = 0; cbuf[0] = 0;
png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), png_write_chunk_data(png_ptr, (lang ? (png_const_bytep)lang : cbuf),
(png_size_t)(lang_len + 1)); (png_size_t)(lang_len + 1));
png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf),
@ -1701,9 +1680,6 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
png_write_compressed_data_out(png_ptr, &comp, text_len); png_write_compressed_data_out(png_ptr, &comp, text_len);
png_write_chunk_end(png_ptr); png_write_chunk_end(png_ptr);
png_free(png_ptr, new_key);
png_free(png_ptr, new_lang);
} }
#endif #endif
@ -1737,7 +1713,6 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
png_size_t purpose_len, units_len, total_len; png_size_t purpose_len, units_len, total_len;
png_size_tp params_len; png_size_tp params_len;
png_byte buf[10]; png_byte buf[10];
png_charp new_purpose;
int i; int i;
png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
@ -1745,7 +1720,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
if (type >= PNG_EQUATION_LAST) if (type >= PNG_EQUATION_LAST)
png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; purpose_len = strlen(purpose) + 1;
png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
png_debug1(3, "pCAL units length = %d", (int)units_len); png_debug1(3, "pCAL units length = %d", (int)units_len);
@ -1767,7 +1742,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
png_debug1(3, "pCAL total length = %d", (int)total_len); png_debug1(3, "pCAL total length = %d", (int)total_len);
png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len); png_write_chunk_data(png_ptr, (png_const_bytep)purpose, purpose_len);
png_save_int_32(buf, X0); png_save_int_32(buf, X0);
png_save_int_32(buf + 4, X1); png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)type; buf[8] = (png_byte)type;
@ -1775,8 +1750,6 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
png_write_chunk_data(png_ptr, buf, (png_size_t)10); png_write_chunk_data(png_ptr, buf, (png_size_t)10);
png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
png_free(png_ptr, new_purpose);
for (i = 0; i < nparams; i++) for (i = 0; i < nparams; i++)
{ {
png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);