diff options
author | John Bowler <jbowler@acm.org> | 2012-01-14 19:44:43 -0600 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2012-01-14 19:44:43 -0600 |
commit | 00c6a9a62c1825617c35c03ceb408114fffeca32 (patch) | |
tree | 17eeaf091432b8c49cd3e696e33f8eb74af396b4 /pngerror.c | |
parent | 665031e8343952ac5d55812f0a54e5da8e03f669 (diff) | |
download | libpng-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.c | 57 |
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 */ |