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

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

Issue 23494067: Revert "libpng 1.6.3" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
« 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.6.1 [March 28, 2013] 4 * Last changed in libpng 1.2.45 [July 7, 2011]
5 * Copyright (c) 1998-2013 Glenn Randers-Pehrson 5 * Copyright (c) 1998-2011 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 #include "pngpriv.h" 19 #define PNG_INTERNAL
20 20 #define PNG_NO_PEDANTIC_WARNINGS
21 #include "png.h"
21 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 22 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
22 23
23 static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, 24 static void /* PRIVATE */
24 png_const_charp error_message)),PNG_NORETURN); 25 png_default_error PNGARG((png_structp png_ptr,
25 26 png_const_charp error_message)) PNG_NORETURN;
26 #ifdef PNG_WARNINGS_SUPPORTED 27 #ifdef PNG_WARNINGS_SUPPORTED
27 static void /* PRIVATE */ 28 static void /* PRIVATE */
28 png_default_warning PNGARG((png_const_structrp png_ptr, 29 png_default_warning PNGARG((png_structp png_ptr,
29 png_const_charp warning_message)); 30 png_const_charp warning_message));
30 #endif /* PNG_WARNINGS_SUPPORTED */ 31 #endif /* PNG_WARNINGS_SUPPORTED */
31 32
32 /* This function is called whenever there is a fatal error. This function 33 /* This function is called whenever there is a fatal error. This function
33 * should not be changed. If there is a need to handle errors differently, 34 * should not be changed. If there is a need to handle errors differently,
34 * you should supply a replacement error function and use png_set_error_fn() 35 * you should supply a replacement error function and use png_set_error_fn()
35 * to replace the error function at run-time. 36 * to replace the error function at run-time.
36 */ 37 */
37 #ifdef PNG_ERROR_TEXT_SUPPORTED 38 #ifdef PNG_ERROR_TEXT_SUPPORTED
38 PNG_FUNCTION(void,PNGAPI 39 void PNGAPI
39 png_error,(png_const_structrp png_ptr, png_const_charp error_message), 40 png_error(png_structp 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 56 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
57 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 57 {
58 { 58 int i;
59 int i; 59 for (i = 0; i < offset - 1; i++)
60 for (i = 0; i < offset - 1; i++) 60 msg[i] = error_message[i + 1];
61 msg[i] = error_message[i + 1]; 61 msg[i - 1] = '\0';
62 msg[i - 1] = '\0'; 62 error_message = msg;
63 error_message = msg; 63 }
64 } 64 else
65 65 error_message += offset;
66 else 66 }
67 error_message += offset; 67 else
68 } 68 {
69 69 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
70 else 70 {
71 { 71 msg[0] = '0';
72 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 72 msg[1] = '\0';
73 { 73 error_message = msg;
74 msg[0] = '0'; 74 }
75 msg[1] = '\0';
76 error_message = msg;
77 }
78 } 75 }
79 } 76 }
80 } 77 }
81 #endif 78 #endif
82 if (png_ptr != NULL && png_ptr->error_fn != NULL) 79 if (png_ptr != NULL && png_ptr->error_fn != NULL)
83 (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), 80 (*(png_ptr->error_fn))(png_ptr, error_message);
84 error_message);
85 81
86 /* If the custom handler doesn't exist, or if it returns, 82 /* If the custom handler doesn't exist, or if it returns,
87 use the default handler, which will not return. */ 83 use the default handler, which will not return. */
88 png_default_error(png_ptr, error_message); 84 png_default_error(png_ptr, error_message);
89 } 85 }
90 #else 86 #else
91 PNG_FUNCTION(void,PNGAPI 87 void PNGAPI
92 png_err,(png_const_structrp png_ptr),PNG_NORETURN) 88 png_err(png_structp png_ptr)
93 { 89 {
94 /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed 90 /* Prior to 1.2.45 the error_fn received a NULL pointer, expressed
95 * erroneously as '\0', instead of the empty string "". This was 91 * erroneously as '\0', instead of the empty string "". This was
96 * apparently an error, introduced in libpng-1.2.20, and png_default_error 92 * apparently an error, introduced in libpng-1.2.20, and png_default_error
97 * will crash in this case. 93 * will crash in this case.
98 */ 94 */
99 if (png_ptr != NULL && png_ptr->error_fn != NULL) 95 if (png_ptr != NULL && png_ptr->error_fn != NULL)
100 (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); 96 (*(png_ptr->error_fn))(png_ptr, "");
101 97
102 /* If the custom handler doesn't exist, or if it returns, 98 /* If the custom handler doesn't exist, or if it returns,
103 use the default handler, which will not return. */ 99 use the default handler, which will not return. */
104 png_default_error(png_ptr, ""); 100 png_default_error(png_ptr, "");
105 } 101 }
106 #endif /* PNG_ERROR_TEXT_SUPPORTED */ 102 #endif /* PNG_ERROR_TEXT_SUPPORTED */
107 103
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
209 #ifdef PNG_WARNINGS_SUPPORTED 104 #ifdef PNG_WARNINGS_SUPPORTED
210 /* This function is called whenever there is a non-fatal error. This function 105 /* This function is called whenever there is a non-fatal error. This function
211 * should not be changed. If there is a need to handle warnings differently, 106 * should not be changed. If there is a need to handle warnings differently,
212 * you should supply a replacement warning function and use 107 * you should supply a replacement warning function and use
213 * png_set_error_fn() to replace the warning function at run-time. 108 * png_set_error_fn() to replace the warning function at run-time.
214 */ 109 */
215 void PNGAPI 110 void PNGAPI
216 png_warning(png_const_structrp png_ptr, png_const_charp warning_message) 111 png_warning(png_structp png_ptr, png_const_charp warning_message)
217 { 112 {
218 int offset = 0; 113 int offset = 0;
219 if (png_ptr != NULL) 114 if (png_ptr != NULL)
220 { 115 {
221 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 116 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
222 if (png_ptr->flags& 117 if (png_ptr->flags&
223 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 118 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
224 #endif 119 #endif
225 { 120 {
226 if (*warning_message == PNG_LITERAL_SHARP) 121 if (*warning_message == PNG_LITERAL_SHARP)
227 { 122 {
228 for (offset = 1; offset < 15; offset++) 123 for (offset = 1; offset < 15; offset++)
229 if (warning_message[offset] == ' ') 124 if (warning_message[offset] == ' ')
230 break; 125 break;
231 } 126 }
232 } 127 }
233 } 128 }
234 if (png_ptr != NULL && png_ptr->warning_fn != NULL) 129 if (png_ptr != NULL && png_ptr->warning_fn != NULL)
235 (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), 130 (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
236 warning_message + offset);
237 else 131 else
238 png_default_warning(png_ptr, warning_message + offset); 132 png_default_warning(png_ptr, warning_message + offset);
239 } 133 }
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 }
358 #endif /* PNG_WARNINGS_SUPPORTED */ 134 #endif /* PNG_WARNINGS_SUPPORTED */
359 135
360 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 136 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
361 void PNGAPI 137 void PNGAPI
362 png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) 138 png_benign_error(png_structp png_ptr, png_const_charp error_message)
363 { 139 {
364 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) 140 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
365 { 141 png_warning(png_ptr, error_message);
366 # ifdef PNG_READ_SUPPORTED 142 else
367 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && 143 png_error(png_ptr, error_message);
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 } 144 }
386 145 #endif
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);
392 else
393 png_error(png_ptr, error_message);
394 }
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 */
405 146
406 /* These utilities are used internally to build an error message that relates 147 /* These utilities are used internally to build an error message that relates
407 * to the current chunk. The chunk name comes from png_ptr->chunk_name, 148 * to the current chunk. The chunk name comes from png_ptr->chunk_name,
408 * this is used to prefix the message. The message is limited in length 149 * this is used to prefix the message. The message is limited in length
409 * to 63 bytes, the name characters are output as hex digits wrapped in [] 150 * to 63 bytes, the name characters are output as hex digits wrapped in []
410 * if the character is invalid. 151 * if the character is invalid.
411 */ 152 */
412 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 153 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
413 static PNG_CONST char png_digit[16] = { 154 static PNG_CONST char png_digit[16] = {
414 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 155 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
415 'A', 'B', 'C', 'D', 'E', 'F' 156 'A', 'B', 'C', 'D', 'E', 'F'
416 }; 157 };
417 158
418 #define PNG_MAX_ERROR_TEXT 196 /* Currently limited be profile_error in png.c */ 159 #define PNG_MAX_ERROR_TEXT 64
419 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) 160 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
420 static void /* PRIVATE */ 161 static void /* PRIVATE */
421 png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp 162 png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
422 error_message) 163 error_message)
423 { 164 {
424 png_uint_32 chunk_name = png_ptr->chunk_name; 165 int iout = 0, iin = 0;
425 int iout = 0, ishift = 24;
426 166
427 while (ishift >= 0) 167 while (iin < 4)
428 { 168 {
429 int c = (int)(chunk_name >> ishift) & 0xff; 169 int c = png_ptr->chunk_name[iin++];
430
431 ishift -= 8;
432 if (isnonalpha(c)) 170 if (isnonalpha(c))
433 { 171 {
434 buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; 172 buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
435 buffer[iout++] = png_digit[(c & 0xf0) >> 4]; 173 buffer[iout++] = png_digit[(c & 0xf0) >> 4];
436 buffer[iout++] = png_digit[c & 0x0f]; 174 buffer[iout++] = png_digit[c & 0x0f];
437 buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; 175 buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
438 } 176 }
439
440 else 177 else
441 { 178 {
442 buffer[iout++] = (char)c; 179 buffer[iout++] = (png_byte)c;
443 } 180 }
444 } 181 }
445 182
446 if (error_message == NULL) 183 if (error_message == NULL)
447 buffer[iout] = '\0'; 184 buffer[iout] = '\0';
448
449 else 185 else
450 { 186 {
451 int iin = 0;
452
453 buffer[iout++] = ':'; 187 buffer[iout++] = ':';
454 buffer[iout++] = ' '; 188 buffer[iout++] = ' ';
455 189
190 iin = 0;
456 while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') 191 while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
457 buffer[iout++] = error_message[iin++]; 192 buffer[iout++] = error_message[iin++];
458 193
459 /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ 194 /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
460 buffer[iout] = '\0'; 195 buffer[iout] = '\0';
461 } 196 }
462 } 197 }
463 #endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
464 198
465 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) 199 #ifdef PNG_READ_SUPPORTED
466 PNG_FUNCTION(void,PNGAPI 200 void PNGAPI
467 png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), 201 png_chunk_error(png_structp png_ptr, png_const_charp error_message)
468 PNG_NORETURN)
469 { 202 {
470 char msg[18+PNG_MAX_ERROR_TEXT]; 203 char msg[18+PNG_MAX_ERROR_TEXT];
471 if (png_ptr == NULL) 204 if (png_ptr == NULL)
472 png_error(png_ptr, error_message); 205 png_error(png_ptr, error_message);
473
474 else 206 else
475 { 207 {
476 png_format_buffer(png_ptr, msg, error_message); 208 png_format_buffer(png_ptr, msg, error_message);
477 png_error(png_ptr, msg); 209 png_error(png_ptr, msg);
478 } 210 }
479 } 211 }
480 #endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */ 212 #endif /* PNG_READ_SUPPORTED */
213 #endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
481 214
482 #ifdef PNG_WARNINGS_SUPPORTED 215 #ifdef PNG_WARNINGS_SUPPORTED
483 void PNGAPI 216 void PNGAPI
484 png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) 217 png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
485 { 218 {
486 char msg[18+PNG_MAX_ERROR_TEXT]; 219 char msg[18+PNG_MAX_ERROR_TEXT];
487 if (png_ptr == NULL) 220 if (png_ptr == NULL)
488 png_warning(png_ptr, warning_message); 221 png_warning(png_ptr, warning_message);
489
490 else 222 else
491 { 223 {
492 png_format_buffer(png_ptr, msg, warning_message); 224 png_format_buffer(png_ptr, msg, warning_message);
493 png_warning(png_ptr, msg); 225 png_warning(png_ptr, msg);
494 } 226 }
495 } 227 }
496 #endif /* PNG_WARNINGS_SUPPORTED */ 228 #endif /* PNG_WARNINGS_SUPPORTED */
497 229
498 #ifdef PNG_READ_SUPPORTED 230 #ifdef PNG_READ_SUPPORTED
499 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 231 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
500 void PNGAPI 232 void PNGAPI
501 png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp 233 png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
502 error_message)
503 { 234 {
504 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) 235 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
505 png_chunk_warning(png_ptr, error_message); 236 png_chunk_warning(png_ptr, error_message);
506 237 else
507 else 238 png_chunk_error(png_ptr, error_message);
508 png_chunk_error(png_ptr, error_message);
509 } 239 }
510 #endif 240 #endif
511 #endif /* PNG_READ_SUPPORTED */ 241 #endif /* PNG_READ_SUPPORTED */
512 242
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
683 /* This is the default error handling function. Note that replacements for 243 /* This is the default error handling function. Note that replacements for
684 * this function MUST NOT RETURN, or the program will likely crash. This 244 * this function MUST NOT RETURN, or the program will likely crash. This
685 * function is used by default, or if the program supplies NULL for the 245 * function is used by default, or if the program supplies NULL for the
686 * error function pointer in png_set_error_fn(). 246 * error function pointer in png_set_error_fn().
687 */ 247 */
688 static PNG_FUNCTION(void /* PRIVATE */, 248 static void /* PRIVATE */
689 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), 249 png_default_error(png_structp png_ptr, png_const_charp error_message)
690 PNG_NORETURN)
691 { 250 {
692 #ifdef PNG_CONSOLE_IO_SUPPORTED 251 #ifdef PNG_CONSOLE_IO_SUPPORTED
693 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 252 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
694 /* Check on NULL only added in 1.5.4 */ 253 if (*error_message == PNG_LITERAL_SHARP)
695 if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
696 { 254 {
697 /* Strip "#nnnn " from beginning of error message. */ 255 /* Strip "#nnnn " from beginning of error message. */
698 int offset; 256 int offset;
699 char error_number[16]; 257 char error_number[16];
700 for (offset = 0; offset<15; offset++) 258 for (offset = 0; offset<15; offset++)
701 { 259 {
702 error_number[offset] = error_message[offset + 1]; 260 error_number[offset] = error_message[offset + 1];
703 if (error_message[offset] == ' ') 261 if (error_message[offset] == ' ')
704 break; 262 break;
705 } 263 }
706 264 if ((offset > 1) && (offset < 15))
707 if ((offset > 1) && (offset < 15)) 265 {
708 { 266 error_number[offset - 1] = '\0';
709 error_number[offset - 1] = '\0'; 267 fprintf(stderr, "libpng error no. %s: %s",
710 fprintf(stderr, "libpng error no. %s: %s", 268 error_number, error_message + offset + 1);
711 error_number, error_message + offset + 1); 269 fprintf(stderr, PNG_STRING_NEWLINE);
712 fprintf(stderr, PNG_STRING_NEWLINE); 270 }
713 } 271 else
714 272 {
715 else 273 fprintf(stderr, "libpng error: %s, offset=%d",
716 { 274 error_message, offset);
717 fprintf(stderr, "libpng error: %s, offset=%d", 275 fprintf(stderr, PNG_STRING_NEWLINE);
718 error_message, offset); 276 }
719 fprintf(stderr, PNG_STRING_NEWLINE);
720 }
721 } 277 }
722 else 278 else
723 #endif 279 #endif
724 { 280 {
725 fprintf(stderr, "libpng error: %s", error_message ? error_message : 281 fprintf(stderr, "libpng error: %s", error_message);
726 "undefined");
727 fprintf(stderr, PNG_STRING_NEWLINE); 282 fprintf(stderr, PNG_STRING_NEWLINE);
728 } 283 }
729 #else
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 {
738 #ifdef PNG_SETJMP_SUPPORTED
739 if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr)
740 png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
741 #endif 284 #endif
742 285
286 #ifdef PNG_SETJMP_SUPPORTED
287 if (png_ptr)
288 {
289 # ifdef USE_FAR_KEYWORD
290 {
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
743 /* Here if not setjmp support or if png_ptr is null. */ 300 /* Here if not setjmp support or if png_ptr is null. */
744 PNG_ABORT(); 301 PNG_ABORT();
302 #ifndef PNG_CONSOLE_IO_SUPPORTED
303 error_message = error_message; /* Make compiler happy */
304 #endif
745 } 305 }
746 306
747 #ifdef PNG_WARNINGS_SUPPORTED 307 #ifdef PNG_WARNINGS_SUPPORTED
748 /* This function is called when there is a warning, but the library thinks 308 /* This function is called when there is a warning, but the library thinks
749 * it can continue anyway. Replacement functions don't have to do anything 309 * it can continue anyway. Replacement functions don't have to do anything
750 * here if you don't want them to. In the default configuration, png_ptr is 310 * here if you don't want them to. In the default configuration, png_ptr is
751 * not used, but it is passed in case it may be useful. 311 * not used, but it is passed in case it may be useful.
752 */ 312 */
753 static void /* PRIVATE */ 313 static void /* PRIVATE */
754 png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) 314 png_default_warning(png_structp png_ptr, png_const_charp warning_message)
755 { 315 {
756 #ifdef PNG_CONSOLE_IO_SUPPORTED 316 #ifdef PNG_CONSOLE_IO_SUPPORTED
757 # ifdef PNG_ERROR_NUMBERS_SUPPORTED 317 # ifdef PNG_ERROR_NUMBERS_SUPPORTED
758 if (*warning_message == PNG_LITERAL_SHARP) 318 if (*warning_message == PNG_LITERAL_SHARP)
759 { 319 {
760 int offset; 320 int offset;
761 char warning_number[16]; 321 char warning_number[16];
762 for (offset = 0; offset < 15; offset++) 322 for (offset = 0; offset < 15; offset++)
763 { 323 {
764 warning_number[offset] = warning_message[offset + 1]; 324 warning_number[offset] = warning_message[offset + 1];
765 if (warning_message[offset] == ' ') 325 if (warning_message[offset] == ' ')
766 break; 326 break;
767 } 327 }
768 328 if ((offset > 1) && (offset < 15))
769 if ((offset > 1) && (offset < 15)) 329 {
770 { 330 warning_number[offset + 1] = '\0';
771 warning_number[offset + 1] = '\0'; 331 fprintf(stderr, "libpng warning no. %s: %s",
772 fprintf(stderr, "libpng warning no. %s: %s", 332 warning_number, warning_message + offset);
773 warning_number, warning_message + offset); 333 fprintf(stderr, PNG_STRING_NEWLINE);
774 fprintf(stderr, PNG_STRING_NEWLINE); 334 }
775 } 335 else
776 336 {
777 else 337 fprintf(stderr, "libpng warning: %s",
778 { 338 warning_message);
779 fprintf(stderr, "libpng warning: %s", 339 fprintf(stderr, PNG_STRING_NEWLINE);
780 warning_message); 340 }
781 fprintf(stderr, PNG_STRING_NEWLINE);
782 }
783 } 341 }
784 else 342 else
785 # endif 343 # endif
786
787 { 344 {
788 fprintf(stderr, "libpng warning: %s", warning_message); 345 fprintf(stderr, "libpng warning: %s", warning_message);
789 fprintf(stderr, PNG_STRING_NEWLINE); 346 fprintf(stderr, PNG_STRING_NEWLINE);
790 } 347 }
791 #else 348 #else
792 PNG_UNUSED(warning_message) /* Make compiler happy */ 349 warning_message = warning_message; /* Make compiler happy */
793 #endif 350 #endif
794 PNG_UNUSED(png_ptr) /* Make compiler happy */ 351 png_ptr = png_ptr; /* Make compiler happy */
795 } 352 }
796 #endif /* PNG_WARNINGS_SUPPORTED */ 353 #endif /* PNG_WARNINGS_SUPPORTED */
797 354
798 /* This function is called when the application wants to use another method 355 /* This function is called when the application wants to use another method
799 * of handling errors and warnings. Note that the error function MUST NOT 356 * of handling errors and warnings. Note that the error function MUST NOT
800 * return to the calling routine or serious problems will occur. The return 357 * return to the calling routine or serious problems will occur. The return
801 * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) 358 * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
802 */ 359 */
803 void PNGAPI 360 void PNGAPI
804 png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, 361 png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
805 png_error_ptr error_fn, png_error_ptr warning_fn) 362 png_error_ptr error_fn, png_error_ptr warning_fn)
806 { 363 {
807 if (png_ptr == NULL) 364 if (png_ptr == NULL)
808 return; 365 return;
809
810 png_ptr->error_ptr = error_ptr; 366 png_ptr->error_ptr = error_ptr;
811 png_ptr->error_fn = error_fn; 367 png_ptr->error_fn = error_fn;
812 #ifdef PNG_WARNINGS_SUPPORTED
813 png_ptr->warning_fn = warning_fn; 368 png_ptr->warning_fn = warning_fn;
814 #else
815 PNG_UNUSED(warning_fn)
816 #endif
817 } 369 }
818 370
819 371
820 /* This function returns a pointer to the error_ptr associated with the user 372 /* This function returns a pointer to the error_ptr associated with the user
821 * functions. The application should free any memory associated with this 373 * functions. The application should free any memory associated with this
822 * pointer before png_write_destroy and png_read_destroy are called. 374 * pointer before png_write_destroy and png_read_destroy are called.
823 */ 375 */
824 png_voidp PNGAPI 376 png_voidp PNGAPI
825 png_get_error_ptr(png_const_structrp png_ptr) 377 png_get_error_ptr(png_structp png_ptr)
826 { 378 {
827 if (png_ptr == NULL) 379 if (png_ptr == NULL)
828 return NULL; 380 return NULL;
829
830 return ((png_voidp)png_ptr->error_ptr); 381 return ((png_voidp)png_ptr->error_ptr);
831 } 382 }
832 383
833 384
834 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 385 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
835 void PNGAPI 386 void PNGAPI
836 png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) 387 png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
837 { 388 {
838 if (png_ptr != NULL) 389 if (png_ptr != NULL)
839 { 390 {
840 png_ptr->flags &= 391 png_ptr->flags &=
841 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | 392 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
842 PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
843 } 393 }
844 } 394 }
845 #endif 395 #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 */
932 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ 396 #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