Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(879)

Side by Side Diff: third_party/libpng/pngerror.c

Issue 23271006: libpng 1.6.3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove trailing whitespaces. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libpng/pngdebug.h ('k') | third_party/libpng/pngget.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* pngerror.c - stub functions for i/o and memory allocation 2 /* pngerror.c - stub functions for i/o and memory allocation
3 * 3 *
4 * Last changed in libpng 1.2.45 [July 7, 2011] 4 * Last changed in libpng 1.6.1 [March 28, 2013]
5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson 5 * Copyright (c) 1998-2013 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 provides a location for all error handling. Users who 13 * This file provides a location for all error handling. Users who
14 * need special error handling are expected to write replacement functions 14 * need special error handling are expected to write replacement functions
15 * and use png_set_error_fn() to use those functions. See the instructions 15 * and use png_set_error_fn() to use those functions. See the instructions
16 * at each function. 16 * at each function.
17 */ 17 */
18 18
19 #define PNG_INTERNAL 19 #include "pngpriv.h"
20 #define PNG_NO_PEDANTIC_WARNINGS 20
21 #include "png.h"
22 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 21 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
23 22
24 static void /* PRIVATE */ 23 static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
25 png_default_error PNGARG((png_structp png_ptr, 24 png_const_charp error_message)),PNG_NORETURN);
26 png_const_charp error_message)) PNG_NORETURN; 25
27 #ifdef PNG_WARNINGS_SUPPORTED 26 #ifdef PNG_WARNINGS_SUPPORTED
28 static void /* PRIVATE */ 27 static void /* PRIVATE */
29 png_default_warning PNGARG((png_structp png_ptr, 28 png_default_warning PNGARG((png_const_structrp png_ptr,
30 png_const_charp warning_message)); 29 png_const_charp warning_message));
31 #endif /* PNG_WARNINGS_SUPPORTED */ 30 #endif /* PNG_WARNINGS_SUPPORTED */
32 31
33 /* This function is called whenever there is a fatal error. This function 32 /* This function is called whenever there is a fatal error. This function
34 * should not be changed. If there is a need to handle errors differently, 33 * should not be changed. If there is a need to handle errors differently,
35 * you should supply a replacement error function and use png_set_error_fn() 34 * you should supply a replacement error function and use png_set_error_fn()
36 * to replace the error function at run-time. 35 * to replace the error function at run-time.
37 */ 36 */
38 #ifdef PNG_ERROR_TEXT_SUPPORTED 37 #ifdef PNG_ERROR_TEXT_SUPPORTED
39 void PNGAPI 38 PNG_FUNCTION(void,PNGAPI
40 png_error(png_structp png_ptr, png_const_charp error_message) 39 png_error,(png_const_structrp png_ptr, png_const_charp error_message),
40 PNG_NORETURN)
41 { 41 {
42 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 42 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
43 char msg[16]; 43 char msg[16];
44 if (png_ptr != NULL) 44 if (png_ptr != NULL)
45 { 45 {
46 if (png_ptr->flags& 46 if (png_ptr->flags&
47 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 47 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
48 { 48 {
49 if (*error_message == PNG_LITERAL_SHARP) 49 if (*error_message == PNG_LITERAL_SHARP)
50 { 50 {
51 /* Strip "#nnnn " from beginning of error message. */ 51 /* Strip "#nnnn " from beginning of error message. */
52 int offset; 52 int offset;
53 for (offset = 1; offset<15; offset++) 53 for (offset = 1; offset<15; offset++)
54 if (error_message[offset] == ' ') 54 if (error_message[offset] == ' ')
55 break; 55 break;
56 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 56
57 { 57 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
58 int i; 58 {
59 for (i = 0; i < offset - 1; i++) 59 int i;
60 msg[i] = error_message[i + 1]; 60 for (i = 0; i < offset - 1; i++)
61 msg[i - 1] = '\0'; 61 msg[i] = error_message[i + 1];
62 error_message = msg; 62 msg[i - 1] = '\0';
63 } 63 error_message = msg;
64 else 64 }
65 error_message += offset; 65
66 } 66 else
67 else 67 error_message += offset;
68 { 68 }
69 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 69
70 { 70 else
71 msg[0] = '0'; 71 {
72 msg[1] = '\0'; 72 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
73 error_message = msg; 73 {
74 } 74 msg[0] = '0';
75 msg[1] = '\0';
76 error_message = msg;
77 }
75 } 78 }
76 } 79 }
77 } 80 }
78 #endif 81 #endif
79 if (png_ptr != NULL && png_ptr->error_fn != NULL) 82 if (png_ptr != NULL && png_ptr->error_fn != NULL)
80 (*(png_ptr->error_fn))(png_ptr, error_message); 83 (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
84 error_message);
81 85
82 /* If the custom handler doesn't exist, or if it returns, 86 /* If the custom handler doesn't exist, or if it returns,
83 use the default handler, which will not return. */ 87 use the default handler, which will not return. */
84 png_default_error(png_ptr, error_message); 88 png_default_error(png_ptr, error_message);
85 } 89 }
86 #else 90 #else
87 void PNGAPI 91 PNG_FUNCTION(void,PNGAPI
88 png_err(png_structp png_ptr) 92 png_err,(png_const_structrp png_ptr),PNG_NORETURN)
89 { 93 {
90 /* Prior to 1.2.45 the error_fn received a NULL pointer, expressed 94 /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
91 * erroneously as '\0', instead of the empty string "". This was 95 * erroneously as '\0', instead of the empty string "". This was
92 * apparently an error, introduced in libpng-1.2.20, and png_default_error 96 * apparently an error, introduced in libpng-1.2.20, and png_default_error
93 * will crash in this case. 97 * will crash in this case.
94 */ 98 */
95 if (png_ptr != NULL && png_ptr->error_fn != NULL) 99 if (png_ptr != NULL && png_ptr->error_fn != NULL)
96 (*(png_ptr->error_fn))(png_ptr, ""); 100 (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
97 101
98 /* If the custom handler doesn't exist, or if it returns, 102 /* If the custom handler doesn't exist, or if it returns,
99 use the default handler, which will not return. */ 103 use the default handler, which will not return. */
100 png_default_error(png_ptr, ""); 104 png_default_error(png_ptr, "");
101 } 105 }
102 #endif /* PNG_ERROR_TEXT_SUPPORTED */ 106 #endif /* PNG_ERROR_TEXT_SUPPORTED */
103 107
108 /* Utility to safely appends strings to a buffer. This never errors out so
109 * error checking is not required in the caller.
110 */
111 size_t
112 png_safecat(png_charp buffer, size_t bufsize, size_t pos,
113 png_const_charp string)
114 {
115 if (buffer != NULL && pos < bufsize)
116 {
117 if (string != NULL)
118 while (*string != '\0' && pos < bufsize-1)
119 buffer[pos++] = *string++;
120
121 buffer[pos] = '\0';
122 }
123
124 return pos;
125 }
126
127 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
128 /* Utility to dump an unsigned value into a buffer, given a start pointer and
129 * and end pointer (which should point just *beyond* the end of the buffer!)
130 * Returns the pointer to the start of the formatted string.
131 */
132 png_charp
133 png_format_number(png_const_charp start, png_charp end, int format,
134 png_alloc_size_t number)
135 {
136 int count = 0; /* number of digits output */
137 int mincount = 1; /* minimum number required */
138 int output = 0; /* digit output (for the fixed point format) */
139
140 *--end = '\0';
141
142 /* This is written so that the loop always runs at least once, even with
143 * number zero.
144 */
145 while (end > start && (number != 0 || count < mincount))
146 {
147
148 static const char digits[] = "0123456789ABCDEF";
149
150 switch (format)
151 {
152 case PNG_NUMBER_FORMAT_fixed:
153 /* Needs five digits (the fraction) */
154 mincount = 5;
155 if (output || number % 10 != 0)
156 {
157 *--end = digits[number % 10];
158 output = 1;
159 }
160 number /= 10;
161 break;
162
163 case PNG_NUMBER_FORMAT_02u:
164 /* Expects at least 2 digits. */
165 mincount = 2;
166 /* FALL THROUGH */
167
168 case PNG_NUMBER_FORMAT_u:
169 *--end = digits[number % 10];
170 number /= 10;
171 break;
172
173 case PNG_NUMBER_FORMAT_02x:
174 /* This format expects at least two digits */
175 mincount = 2;
176 /* FALL THROUGH */
177
178 case PNG_NUMBER_FORMAT_x:
179 *--end = digits[number & 0xf];
180 number >>= 4;
181 break;
182
183 default: /* an error */
184 number = 0;
185 break;
186 }
187
188 /* Keep track of the number of digits added */
189 ++count;
190
191 /* Float a fixed number here: */
192 if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)
193 {
194 /* End of the fraction, but maybe nothing was output? In that case
195 * drop the decimal point. If the number is a true zero handle that
196 * here.
197 */
198 if (output)
199 *--end = '.';
200 else if (number == 0) /* and !output */
201 *--end = '0';
202 }
203 }
204
205 return end;
206 }
207 #endif
208
104 #ifdef PNG_WARNINGS_SUPPORTED 209 #ifdef PNG_WARNINGS_SUPPORTED
105 /* This function is called whenever there is a non-fatal error. This function 210 /* This function is called whenever there is a non-fatal error. This function
106 * should not be changed. If there is a need to handle warnings differently, 211 * should not be changed. If there is a need to handle warnings differently,
107 * you should supply a replacement warning function and use 212 * you should supply a replacement warning function and use
108 * png_set_error_fn() to replace the warning function at run-time. 213 * png_set_error_fn() to replace the warning function at run-time.
109 */ 214 */
110 void PNGAPI 215 void PNGAPI
111 png_warning(png_structp png_ptr, png_const_charp warning_message) 216 png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
112 { 217 {
113 int offset = 0; 218 int offset = 0;
114 if (png_ptr != NULL) 219 if (png_ptr != NULL)
115 { 220 {
116 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 221 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
117 if (png_ptr->flags& 222 if (png_ptr->flags&
118 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 223 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
119 #endif 224 #endif
120 { 225 {
121 if (*warning_message == PNG_LITERAL_SHARP) 226 if (*warning_message == PNG_LITERAL_SHARP)
122 { 227 {
123 for (offset = 1; offset < 15; offset++) 228 for (offset = 1; offset < 15; offset++)
124 if (warning_message[offset] == ' ') 229 if (warning_message[offset] == ' ')
125 break; 230 break;
126 } 231 }
127 } 232 }
128 } 233 }
129 if (png_ptr != NULL && png_ptr->warning_fn != NULL) 234 if (png_ptr != NULL && png_ptr->warning_fn != NULL)
130 (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); 235 (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
236 warning_message + offset);
131 else 237 else
132 png_default_warning(png_ptr, warning_message + offset); 238 png_default_warning(png_ptr, warning_message + offset);
133 } 239 }
240
241 /* These functions support 'formatted' warning messages with up to
242 * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter
243 * is introduced by @<number>, where 'number' starts at 1. This follows the
244 * standard established by X/Open for internationalizable error messages.
245 */
246 void
247 png_warning_parameter(png_warning_parameters p, int number,
248 png_const_charp string)
249 {
250 if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
251 (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
252 }
253
254 void
255 png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
256 png_alloc_size_t value)
257 {
258 char buffer[PNG_NUMBER_BUFFER_SIZE];
259 png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
260 }
261
262 void
263 png_warning_parameter_signed(png_warning_parameters p, int number, int format,
264 png_int_32 value)
265 {
266 png_alloc_size_t u;
267 png_charp str;
268 char buffer[PNG_NUMBER_BUFFER_SIZE];
269
270 /* Avoid overflow by doing the negate in a png_alloc_size_t: */
271 u = (png_alloc_size_t)value;
272 if (value < 0)
273 u = ~u + 1;
274
275 str = PNG_FORMAT_NUMBER(buffer, format, u);
276
277 if (value < 0 && str > buffer)
278 *--str = '-';
279
280 png_warning_parameter(p, number, str);
281 }
282
283 void
284 png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
285 png_const_charp message)
286 {
287 /* The internal buffer is just 192 bytes - enough for all our messages,
288 * overflow doesn't happen because this code checks! If someone figures
289 * out how to send us a message longer than 192 bytes, all that will
290 * happen is that the message will be truncated appropriately.
291 */
292 size_t i = 0; /* Index in the msg[] buffer: */
293 char msg[192];
294
295 /* Each iteration through the following loop writes at most one character
296 * to msg[i++] then returns here to validate that there is still space for
297 * the trailing '\0'. It may (in the case of a parameter) read more than
298 * one character from message[]; it must check for '\0' and continue to the
299 * test if it finds the end of string.
300 */
301 while (i<(sizeof msg)-1 && *message != '\0')
302 {
303 /* '@' at end of string is now just printed (previously it was skipped);
304 * it is an error in the calling code to terminate the string with @.
305 */
306 if (p != NULL && *message == '@' && message[1] != '\0')
307 {
308 int parameter_char = *++message; /* Consume the '@' */
309 static const char valid_parameters[] = "123456789";
310 int parameter = 0;
311
312 /* Search for the parameter digit, the index in the string is the
313 * parameter to use.
314 */
315 while (valid_parameters[parameter] != parameter_char &&
316 valid_parameters[parameter] != '\0')
317 ++parameter;
318
319 /* If the parameter digit is out of range it will just get printed. */
320 if (parameter < PNG_WARNING_PARAMETER_COUNT)
321 {
322 /* Append this parameter */
323 png_const_charp parm = p[parameter];
324 png_const_charp pend = p[parameter] + (sizeof p[parameter]);
325
326 /* No need to copy the trailing '\0' here, but there is no guarantee
327 * that parm[] has been initialized, so there is no guarantee of a
328 * trailing '\0':
329 */
330 while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
331 msg[i++] = *parm++;
332
333 /* Consume the parameter digit too: */
334 ++message;
335 continue;
336 }
337
338 /* else not a parameter and there is a character after the @ sign; just
339 * copy that. This is known not to be '\0' because of the test above.
340 */
341 }
342
343 /* At this point *message can't be '\0', even in the bad parameter case
344 * above where there is a lone '@' at the end of the message string.
345 */
346 msg[i++] = *message++;
347 }
348
349 /* i is always less than (sizeof msg), so: */
350 msg[i] = '\0';
351
352 /* And this is the formatted message. It may be larger than
353 * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
354 * are not (currently) formatted.
355 */
356 png_warning(png_ptr, msg);
357 }
134 #endif /* PNG_WARNINGS_SUPPORTED */ 358 #endif /* PNG_WARNINGS_SUPPORTED */
135 359
136 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 360 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
137 void PNGAPI 361 void PNGAPI
138 png_benign_error(png_structp png_ptr, png_const_charp error_message) 362 png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
139 { 363 {
140 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) 364 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
141 png_warning(png_ptr, error_message); 365 {
366 # ifdef PNG_READ_SUPPORTED
367 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
368 png_ptr->chunk_name != 0)
369 png_chunk_warning(png_ptr, error_message);
370 else
371 # endif
372 png_warning(png_ptr, error_message);
373 }
374
375 else
376 {
377 # ifdef PNG_READ_SUPPORTED
378 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
379 png_ptr->chunk_name != 0)
380 png_chunk_error(png_ptr, error_message);
381 else
382 # endif
383 png_error(png_ptr, error_message);
384 }
385 }
386
387 void /* PRIVATE */
388 png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
389 {
390 if (png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN)
391 png_warning(png_ptr, error_message);
142 else 392 else
143 png_error(png_ptr, error_message); 393 png_error(png_ptr, error_message);
144 } 394 }
145 #endif 395
396 void /* PRIVATE */
397 png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
398 {
399 if (png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN)
400 png_warning(png_ptr, error_message);
401 else
402 png_error(png_ptr, error_message);
403 }
404 #endif /* BENIGN_ERRORS */
146 405
147 /* These utilities are used internally to build an error message that relates 406 /* These utilities are used internally to build an error message that relates
148 * to the current chunk. The chunk name comes from png_ptr->chunk_name, 407 * to the current chunk. The chunk name comes from png_ptr->chunk_name,
149 * this is used to prefix the message. The message is limited in length 408 * this is used to prefix the message. The message is limited in length
150 * to 63 bytes, the name characters are output as hex digits wrapped in [] 409 * to 63 bytes, the name characters are output as hex digits wrapped in []
151 * if the character is invalid. 410 * if the character is invalid.
152 */ 411 */
153 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 412 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
154 static PNG_CONST char png_digit[16] = { 413 static PNG_CONST char png_digit[16] = {
155 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 414 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
156 'A', 'B', 'C', 'D', 'E', 'F' 415 'A', 'B', 'C', 'D', 'E', 'F'
157 }; 416 };
158 417
159 #define PNG_MAX_ERROR_TEXT 64 418 #define PNG_MAX_ERROR_TEXT 196 /* Currently limited be profile_error in png.c */
160 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) 419 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
161 static void /* PRIVATE */ 420 static void /* PRIVATE */
162 png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp 421 png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
163 error_message) 422 error_message)
164 { 423 {
165 int iout = 0, iin = 0; 424 png_uint_32 chunk_name = png_ptr->chunk_name;
425 int iout = 0, ishift = 24;
166 426
167 while (iin < 4) 427 while (ishift >= 0)
168 { 428 {
169 int c = png_ptr->chunk_name[iin++]; 429 int c = (int)(chunk_name >> ishift) & 0xff;
430
431 ishift -= 8;
170 if (isnonalpha(c)) 432 if (isnonalpha(c))
171 { 433 {
172 buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; 434 buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
173 buffer[iout++] = png_digit[(c & 0xf0) >> 4]; 435 buffer[iout++] = png_digit[(c & 0xf0) >> 4];
174 buffer[iout++] = png_digit[c & 0x0f]; 436 buffer[iout++] = png_digit[c & 0x0f];
175 buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; 437 buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
176 } 438 }
439
177 else 440 else
178 { 441 {
179 buffer[iout++] = (png_byte)c; 442 buffer[iout++] = (char)c;
180 } 443 }
181 } 444 }
182 445
183 if (error_message == NULL) 446 if (error_message == NULL)
184 buffer[iout] = '\0'; 447 buffer[iout] = '\0';
448
185 else 449 else
186 { 450 {
451 int iin = 0;
452
187 buffer[iout++] = ':'; 453 buffer[iout++] = ':';
188 buffer[iout++] = ' '; 454 buffer[iout++] = ' ';
189 455
190 iin = 0;
191 while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') 456 while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
192 buffer[iout++] = error_message[iin++]; 457 buffer[iout++] = error_message[iin++];
193 458
194 /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ 459 /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
195 buffer[iout] = '\0'; 460 buffer[iout] = '\0';
196 } 461 }
197 } 462 }
463 #endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
198 464
199 #ifdef PNG_READ_SUPPORTED 465 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
200 void PNGAPI 466 PNG_FUNCTION(void,PNGAPI
201 png_chunk_error(png_structp png_ptr, png_const_charp error_message) 467 png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
468 PNG_NORETURN)
202 { 469 {
203 char msg[18+PNG_MAX_ERROR_TEXT]; 470 char msg[18+PNG_MAX_ERROR_TEXT];
204 if (png_ptr == NULL) 471 if (png_ptr == NULL)
205 png_error(png_ptr, error_message); 472 png_error(png_ptr, error_message);
473
206 else 474 else
207 { 475 {
208 png_format_buffer(png_ptr, msg, error_message); 476 png_format_buffer(png_ptr, msg, error_message);
209 png_error(png_ptr, msg); 477 png_error(png_ptr, msg);
210 } 478 }
211 } 479 }
212 #endif /* PNG_READ_SUPPORTED */ 480 #endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
213 #endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
214 481
215 #ifdef PNG_WARNINGS_SUPPORTED 482 #ifdef PNG_WARNINGS_SUPPORTED
216 void PNGAPI 483 void PNGAPI
217 png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) 484 png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
218 { 485 {
219 char msg[18+PNG_MAX_ERROR_TEXT]; 486 char msg[18+PNG_MAX_ERROR_TEXT];
220 if (png_ptr == NULL) 487 if (png_ptr == NULL)
221 png_warning(png_ptr, warning_message); 488 png_warning(png_ptr, warning_message);
489
222 else 490 else
223 { 491 {
224 png_format_buffer(png_ptr, msg, warning_message); 492 png_format_buffer(png_ptr, msg, warning_message);
225 png_warning(png_ptr, msg); 493 png_warning(png_ptr, msg);
226 } 494 }
227 } 495 }
228 #endif /* PNG_WARNINGS_SUPPORTED */ 496 #endif /* PNG_WARNINGS_SUPPORTED */
229 497
230 #ifdef PNG_READ_SUPPORTED 498 #ifdef PNG_READ_SUPPORTED
231 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 499 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
232 void PNGAPI 500 void PNGAPI
233 png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) 501 png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
234 { 502 error_message)
235 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) 503 {
236 png_chunk_warning(png_ptr, error_message); 504 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
237 else 505 png_chunk_warning(png_ptr, error_message);
238 png_chunk_error(png_ptr, error_message); 506
507 else
508 png_chunk_error(png_ptr, error_message);
239 } 509 }
240 #endif 510 #endif
241 #endif /* PNG_READ_SUPPORTED */ 511 #endif /* PNG_READ_SUPPORTED */
242 512
513 void /* PRIVATE */
514 png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
515 {
516 /* This is always supported, but for just read or just write it
517 * unconditionally does the right thing.
518 */
519 # if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
520 if (png_ptr->mode & PNG_IS_READ_STRUCT)
521 # endif
522
523 # ifdef PNG_READ_SUPPORTED
524 {
525 if (error < PNG_CHUNK_ERROR)
526 png_chunk_warning(png_ptr, message);
527
528 else
529 png_chunk_benign_error(png_ptr, message);
530 }
531 # endif
532
533 # if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
534 else if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
535 # endif
536
537 # ifdef PNG_WRITE_SUPPORTED
538 {
539 if (error < PNG_CHUNK_WRITE_ERROR)
540 png_app_warning(png_ptr, message);
541
542 else
543 png_app_error(png_ptr, message);
544 }
545 # endif
546 }
547
548 #ifdef PNG_ERROR_TEXT_SUPPORTED
549 #ifdef PNG_FLOATING_POINT_SUPPORTED
550 PNG_FUNCTION(void,
551 png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
552 {
553 # define fixed_message "fixed point overflow in "
554 # define fixed_message_ln ((sizeof fixed_message)-1)
555 int iin;
556 char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
557 memcpy(msg, fixed_message, fixed_message_ln);
558 iin = 0;
559 if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
560 {
561 msg[fixed_message_ln + iin] = name[iin];
562 ++iin;
563 }
564 msg[fixed_message_ln + iin] = 0;
565 png_error(png_ptr, msg);
566 }
567 #endif
568 #endif
569
570 #ifdef PNG_SETJMP_SUPPORTED
571 /* This API only exists if ANSI-C style error handling is used,
572 * otherwise it is necessary for png_default_error to be overridden.
573 */
574 jmp_buf* PNGAPI
575 png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
576 size_t jmp_buf_size)
577 {
578 /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
579 * and it must not change after that. Libpng doesn't care how big the
580 * buffer is, just that it doesn't change.
581 *
582 * If the buffer size is no *larger* than the size of jmp_buf when libpng is
583 * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
584 * semantics that this call will not fail. If the size is larger, however,
585 * the buffer is allocated and this may fail, causing the function to return
586 * NULL.
587 */
588 if (png_ptr == NULL)
589 return NULL;
590
591 if (png_ptr->jmp_buf_ptr == NULL)
592 {
593 png_ptr->jmp_buf_size = 0; /* not allocated */
594
595 if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
596 png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
597
598 else
599 {
600 png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
601 png_malloc_warn(png_ptr, jmp_buf_size));
602
603 if (png_ptr->jmp_buf_ptr == NULL)
604 return NULL; /* new NULL return on OOM */
605
606 png_ptr->jmp_buf_size = jmp_buf_size;
607 }
608 }
609
610 else /* Already allocated: check the size */
611 {
612 size_t size = png_ptr->jmp_buf_size;
613
614 if (size == 0)
615 {
616 size = (sizeof png_ptr->jmp_buf_local);
617 if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
618 {
619 /* This is an internal error in libpng: somehow we have been left
620 * with a stack allocated jmp_buf when the application regained
621 * control. It's always possible to fix this up, but for the moment
622 * this is a png_error because that makes it easy to detect.
623 */
624 png_error(png_ptr, "Libpng jmp_buf still allocated");
625 /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
626 }
627 }
628
629 if (size != jmp_buf_size)
630 {
631 png_warning(png_ptr, "Application jmp_buf size changed");
632 return NULL; /* caller will probably crash: no choice here */
633 }
634 }
635
636 /* Finally fill in the function, now we have a satisfactory buffer. It is
637 * valid to change the function on every call.
638 */
639 png_ptr->longjmp_fn = longjmp_fn;
640 return png_ptr->jmp_buf_ptr;
641 }
642
643 void /* PRIVATE */
644 png_free_jmpbuf(png_structrp png_ptr)
645 {
646 if (png_ptr != NULL)
647 {
648 jmp_buf *jb = png_ptr->jmp_buf_ptr;
649
650 /* A size of 0 is used to indicate a local, stack, allocation of the
651 * pointer; used here and in png.c
652 */
653 if (jb != NULL && png_ptr->jmp_buf_size > 0)
654 {
655
656 /* This stuff is so that a failure to free the error control structure
657 * does not leave libpng in a state with no valid error handling: the
658 * free always succeeds, if there is an error it gets ignored.
659 */
660 if (jb != &png_ptr->jmp_buf_local)
661 {
662 /* Make an internal, libpng, jmp_buf to return here */
663 jmp_buf free_jmp_buf;
664
665 if (!setjmp(free_jmp_buf))
666 {
667 png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
668 png_ptr->jmp_buf_size = 0; /* stack allocation */
669 png_ptr->longjmp_fn = longjmp;
670 png_free(png_ptr, jb); /* Return to setjmp on error */
671 }
672 }
673 }
674
675 /* *Always* cancel everything out: */
676 png_ptr->jmp_buf_size = 0;
677 png_ptr->jmp_buf_ptr = NULL;
678 png_ptr->longjmp_fn = 0;
679 }
680 }
681 #endif
682
243 /* This is the default error handling function. Note that replacements for 683 /* This is the default error handling function. Note that replacements for
244 * this function MUST NOT RETURN, or the program will likely crash. This 684 * this function MUST NOT RETURN, or the program will likely crash. This
245 * function is used by default, or if the program supplies NULL for the 685 * function is used by default, or if the program supplies NULL for the
246 * error function pointer in png_set_error_fn(). 686 * error function pointer in png_set_error_fn().
247 */ 687 */
248 static void /* PRIVATE */ 688 static PNG_FUNCTION(void /* PRIVATE */,
249 png_default_error(png_structp png_ptr, png_const_charp error_message) 689 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
690 PNG_NORETURN)
250 { 691 {
251 #ifdef PNG_CONSOLE_IO_SUPPORTED 692 #ifdef PNG_CONSOLE_IO_SUPPORTED
252 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 693 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
253 if (*error_message == PNG_LITERAL_SHARP) 694 /* Check on NULL only added in 1.5.4 */
254 { 695 if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
255 /* Strip "#nnnn " from beginning of error message. */ 696 {
256 int offset; 697 /* Strip "#nnnn " from beginning of error message. */
257 char error_number[16]; 698 int offset;
258 for (offset = 0; offset<15; offset++) 699 char error_number[16];
259 { 700 for (offset = 0; offset<15; offset++)
701 {
260 error_number[offset] = error_message[offset + 1]; 702 error_number[offset] = error_message[offset + 1];
261 if (error_message[offset] == ' ') 703 if (error_message[offset] == ' ')
262 break; 704 break;
263 } 705 }
264 if ((offset > 1) && (offset < 15)) 706
265 { 707 if ((offset > 1) && (offset < 15))
266 error_number[offset - 1] = '\0'; 708 {
267 fprintf(stderr, "libpng error no. %s: %s", 709 error_number[offset - 1] = '\0';
268 error_number, error_message + offset + 1); 710 fprintf(stderr, "libpng error no. %s: %s",
269 fprintf(stderr, PNG_STRING_NEWLINE); 711 error_number, error_message + offset + 1);
270 } 712 fprintf(stderr, PNG_STRING_NEWLINE);
271 else 713 }
272 { 714
273 fprintf(stderr, "libpng error: %s, offset=%d", 715 else
274 error_message, offset); 716 {
275 fprintf(stderr, PNG_STRING_NEWLINE); 717 fprintf(stderr, "libpng error: %s, offset=%d",
276 } 718 error_message, offset);
719 fprintf(stderr, PNG_STRING_NEWLINE);
720 }
277 } 721 }
278 else 722 else
279 #endif 723 #endif
280 { 724 {
281 fprintf(stderr, "libpng error: %s", error_message); 725 fprintf(stderr, "libpng error: %s", error_message ? error_message :
726 "undefined");
282 fprintf(stderr, PNG_STRING_NEWLINE); 727 fprintf(stderr, PNG_STRING_NEWLINE);
283 } 728 }
284 #endif 729 #else
285 730 PNG_UNUSED(error_message) /* Make compiler happy */
731 #endif
732 png_longjmp(png_ptr, 1);
733 }
734
735 PNG_FUNCTION(void,PNGAPI
736 png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
737 {
286 #ifdef PNG_SETJMP_SUPPORTED 738 #ifdef PNG_SETJMP_SUPPORTED
287 if (png_ptr) 739 if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr)
288 { 740 png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
289 # ifdef USE_FAR_KEYWORD 741 #endif
290 { 742
291 jmp_buf jmpbuf;
292 png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
293 longjmp(jmpbuf,1);
294 }
295 # else
296 longjmp(png_ptr->jmpbuf, 1);
297 # endif
298 }
299 #endif
300 /* Here if not setjmp support or if png_ptr is null. */ 743 /* Here if not setjmp support or if png_ptr is null. */
301 PNG_ABORT(); 744 PNG_ABORT();
302 #ifndef PNG_CONSOLE_IO_SUPPORTED
303 error_message = error_message; /* Make compiler happy */
304 #endif
305 } 745 }
306 746
307 #ifdef PNG_WARNINGS_SUPPORTED 747 #ifdef PNG_WARNINGS_SUPPORTED
308 /* This function is called when there is a warning, but the library thinks 748 /* This function is called when there is a warning, but the library thinks
309 * it can continue anyway. Replacement functions don't have to do anything 749 * it can continue anyway. Replacement functions don't have to do anything
310 * here if you don't want them to. In the default configuration, png_ptr is 750 * here if you don't want them to. In the default configuration, png_ptr is
311 * not used, but it is passed in case it may be useful. 751 * not used, but it is passed in case it may be useful.
312 */ 752 */
313 static void /* PRIVATE */ 753 static void /* PRIVATE */
314 png_default_warning(png_structp png_ptr, png_const_charp warning_message) 754 png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
315 { 755 {
316 #ifdef PNG_CONSOLE_IO_SUPPORTED 756 #ifdef PNG_CONSOLE_IO_SUPPORTED
317 # ifdef PNG_ERROR_NUMBERS_SUPPORTED 757 # ifdef PNG_ERROR_NUMBERS_SUPPORTED
318 if (*warning_message == PNG_LITERAL_SHARP) 758 if (*warning_message == PNG_LITERAL_SHARP)
319 { 759 {
320 int offset; 760 int offset;
321 char warning_number[16]; 761 char warning_number[16];
322 for (offset = 0; offset < 15; offset++) 762 for (offset = 0; offset < 15; offset++)
323 { 763 {
324 warning_number[offset] = warning_message[offset + 1]; 764 warning_number[offset] = warning_message[offset + 1];
325 if (warning_message[offset] == ' ') 765 if (warning_message[offset] == ' ')
326 break; 766 break;
327 } 767 }
328 if ((offset > 1) && (offset < 15)) 768
329 { 769 if ((offset > 1) && (offset < 15))
330 warning_number[offset + 1] = '\0'; 770 {
331 fprintf(stderr, "libpng warning no. %s: %s", 771 warning_number[offset + 1] = '\0';
332 warning_number, warning_message + offset); 772 fprintf(stderr, "libpng warning no. %s: %s",
333 fprintf(stderr, PNG_STRING_NEWLINE); 773 warning_number, warning_message + offset);
334 } 774 fprintf(stderr, PNG_STRING_NEWLINE);
335 else 775 }
336 { 776
337 fprintf(stderr, "libpng warning: %s", 777 else
338 warning_message); 778 {
339 fprintf(stderr, PNG_STRING_NEWLINE); 779 fprintf(stderr, "libpng warning: %s",
340 } 780 warning_message);
781 fprintf(stderr, PNG_STRING_NEWLINE);
782 }
341 } 783 }
342 else 784 else
343 # endif 785 # endif
786
344 { 787 {
345 fprintf(stderr, "libpng warning: %s", warning_message); 788 fprintf(stderr, "libpng warning: %s", warning_message);
346 fprintf(stderr, PNG_STRING_NEWLINE); 789 fprintf(stderr, PNG_STRING_NEWLINE);
347 } 790 }
348 #else 791 #else
349 warning_message = warning_message; /* Make compiler happy */ 792 PNG_UNUSED(warning_message) /* Make compiler happy */
350 #endif 793 #endif
351 png_ptr = png_ptr; /* Make compiler happy */ 794 PNG_UNUSED(png_ptr) /* Make compiler happy */
352 } 795 }
353 #endif /* PNG_WARNINGS_SUPPORTED */ 796 #endif /* PNG_WARNINGS_SUPPORTED */
354 797
355 /* This function is called when the application wants to use another method 798 /* This function is called when the application wants to use another method
356 * of handling errors and warnings. Note that the error function MUST NOT 799 * of handling errors and warnings. Note that the error function MUST NOT
357 * return to the calling routine or serious problems will occur. The return 800 * return to the calling routine or serious problems will occur. The return
358 * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) 801 * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
359 */ 802 */
360 void PNGAPI 803 void PNGAPI
361 png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, 804 png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
362 png_error_ptr error_fn, png_error_ptr warning_fn) 805 png_error_ptr error_fn, png_error_ptr warning_fn)
363 { 806 {
364 if (png_ptr == NULL) 807 if (png_ptr == NULL)
365 return; 808 return;
809
366 png_ptr->error_ptr = error_ptr; 810 png_ptr->error_ptr = error_ptr;
367 png_ptr->error_fn = error_fn; 811 png_ptr->error_fn = error_fn;
812 #ifdef PNG_WARNINGS_SUPPORTED
368 png_ptr->warning_fn = warning_fn; 813 png_ptr->warning_fn = warning_fn;
814 #else
815 PNG_UNUSED(warning_fn)
816 #endif
369 } 817 }
370 818
371 819
372 /* This function returns a pointer to the error_ptr associated with the user 820 /* This function returns a pointer to the error_ptr associated with the user
373 * functions. The application should free any memory associated with this 821 * functions. The application should free any memory associated with this
374 * pointer before png_write_destroy and png_read_destroy are called. 822 * pointer before png_write_destroy and png_read_destroy are called.
375 */ 823 */
376 png_voidp PNGAPI 824 png_voidp PNGAPI
377 png_get_error_ptr(png_structp png_ptr) 825 png_get_error_ptr(png_const_structrp png_ptr)
378 { 826 {
379 if (png_ptr == NULL) 827 if (png_ptr == NULL)
380 return NULL; 828 return NULL;
829
381 return ((png_voidp)png_ptr->error_ptr); 830 return ((png_voidp)png_ptr->error_ptr);
382 } 831 }
383 832
384 833
385 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 834 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
386 void PNGAPI 835 void PNGAPI
387 png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) 836 png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
388 { 837 {
389 if (png_ptr != NULL) 838 if (png_ptr != NULL)
390 { 839 {
391 png_ptr->flags &= 840 png_ptr->flags &=
392 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); 841 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
842 PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
393 } 843 }
394 } 844 }
395 #endif 845 #endif
846
847 #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
848 defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
849 /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
850 * possible to implement without setjmp support just so long as there is some
851 * way to handle the error return here:
852 */
853 PNG_FUNCTION(void /* PRIVATE */,
854 png_safe_error,(png_structp png_nonconst_ptr, png_const_charp error_message),
855 PNG_NORETURN)
856 {
857 const png_const_structrp png_ptr = png_nonconst_ptr;
858 png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
859
860 /* An error is always logged here, overwriting anything (typically a warning)
861 * that is already there:
862 */
863 if (image != NULL)
864 {
865 png_safecat(image->message, (sizeof image->message), 0, error_message);
866 image->warning_or_error |= PNG_IMAGE_ERROR;
867
868 /* Retrieve the jmp_buf from within the png_control, making this work for
869 * C++ compilation too is pretty tricky: C++ wants a pointer to the first
870 * element of a jmp_buf, but C doesn't tell us the type of that.
871 */
872 if (image->opaque != NULL && image->opaque->error_buf != NULL)
873 longjmp(png_control_jmp_buf(image->opaque), 1);
874
875 /* Missing longjmp buffer, the following is to help debugging: */
876 {
877 size_t pos = png_safecat(image->message, (sizeof image->message), 0,
878 "bad longjmp: ");
879 png_safecat(image->message, (sizeof image->message), pos,
880 error_message);
881 }
882 }
883
884 /* Here on an internal programming error. */
885 abort();
886 }
887
888 #ifdef PNG_WARNINGS_SUPPORTED
889 void /* PRIVATE */
890 png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
891 {
892 const png_const_structrp png_ptr = png_nonconst_ptr;
893 png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
894
895 /* A warning is only logged if there is no prior warning or error. */
896 if (image->warning_or_error == 0)
897 {
898 png_safecat(image->message, (sizeof image->message), 0, warning_message);
899 image->warning_or_error |= PNG_IMAGE_WARNING;
900 }
901 }
902 #endif
903
904 int /* PRIVATE */
905 png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
906 {
907 volatile png_imagep image = image_in;
908 volatile int result;
909 volatile png_voidp saved_error_buf;
910 jmp_buf safe_jmpbuf;
911
912 /* Safely execute function(arg) with png_error returning to this function. */
913 saved_error_buf = image->opaque->error_buf;
914 result = setjmp(safe_jmpbuf) == 0;
915
916 if (result)
917 {
918
919 image->opaque->error_buf = safe_jmpbuf;
920 result = function(arg);
921 }
922
923 image->opaque->error_buf = saved_error_buf;
924
925 /* And do the cleanup prior to any failure return. */
926 if (!result)
927 png_image_free(image);
928
929 return result;
930 }
931 #endif /* SIMPLIFIED READ/WRITE */
396 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ 932 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
OLDNEW
« no previous file with comments | « third_party/libpng/pngdebug.h ('k') | third_party/libpng/pngget.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698