summaryrefslogtreecommitdiff
path: root/pngerror.c
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@acm.org>2012-01-14 19:44:43 -0600
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2012-01-14 19:44:43 -0600
commit00c6a9a62c1825617c35c03ceb408114fffeca32 (patch)
tree17eeaf091432b8c49cd3e696e33f8eb74af396b4 /pngerror.c
parent665031e8343952ac5d55812f0a54e5da8e03f669 (diff)
downloadlibpng-00c6a9a62c1825617c35c03ceb408114fffeca32.tar.gz
[libpng16] Fix bug in pngerror.c: some long warnings were being improperly
truncated (bug introduced in libpng-1.5.3beta05).
Diffstat (limited to 'pngerror.c')
-rw-r--r--pngerror.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/pngerror.c b/pngerror.c
index 434495335..622b41307 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -286,32 +286,35 @@ png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
/* The internal buffer is just 128 bytes - enough for all our messages,
* overflow doesn't happen because this code checks!
*/
- size_t i;
+ size_t i = 0; /* Index in the msg[] buffer: */
char msg[128];
- for (i=0; i<(sizeof msg)-1 && *message != '\0'; ++i)
+ /* Each iteration through the following loop writes at most one character
+ * to msg[i++] then returns here to validate that there is still space for
+ * the trailing '\0'. It may (in the case of a parameter) read more than
+ * one character from message[]; it must check for '\0' and continue to the
+ * test if it finds the end of string.
+ */
+ while (i<(sizeof msg)-1 && *message != '\0')
{
- if (*message == '@')
+ /* '@' at end of string is now just printed (previously it was skipped);
+ * it is an error in the calling code to terminate the string with @.
+ */
+ if (p != NULL && *message == '@' && message[1] != '\0')
{
- int parameter = -1;
- switch (*++message)
- {
- case '1':
- parameter = 0;
- break;
-
- case '2':
- parameter = 1;
- break;
+ int parameter_char = *++message; /* Consume the '@' */
+ static const char valid_parameters[] = "123456789";
+ int parameter = 0;
- case '\0':
- continue; /* To break out of the for loop above. */
-
- default:
- break;
- }
+ /* Search for the parameter digit, the index in the string is the
+ * parameter to use.
+ */
+ while (valid_parameters[parameter] != parameter_char &&
+ valid_parameters[parameter] != '\0')
+ ++parameter;
- if (parameter >= 0 && parameter < PNG_WARNING_PARAMETER_COUNT)
+ /* If the parameter digit is out of range it will just get printed. */
+ if (parameter < PNG_WARNING_PARAMETER_COUNT)
{
/* Append this parameter */
png_const_charp parm = p[parameter];
@@ -321,28 +324,32 @@ png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
* that parm[] has been initialized, so there is no guarantee of a
* trailing '\0':
*/
- for (; i<(sizeof msg)-1 && parm != '\0' && parm < pend; ++i)
- msg[i] = *parm++;
+ while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
+ msg[i++] = *parm++;
+ /* Consume the parameter digit too: */
++message;
continue;
}
/* else not a parameter and there is a character after the @ sign; just
- * copy that.
+ * copy that. This is known not to be '\0' because of the test above.
*/
}
/* At this point *message can't be '\0', even in the bad parameter case
* above where there is a lone '@' at the end of the message string.
*/
- msg[i] = *message++;
+ msg[i++] = *message++;
}
/* i is always less than (sizeof msg), so: */
msg[i] = '\0';
- /* And this is the formatted message: */
+ /* And this is the formatted message, it may be larger than
+ * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are
+ * not (currently) formatted.
+ */
png_warning(png_ptr, msg);
}
#endif /* PNG_WARNINGS_SUPPORTED */