1 | ␍␊ |
2 | /* pngerror.c - stub functions for i/o and memory allocation␍␊ |
3 | *␍␊ |
4 | * Last changed in libpng 1.5.8 [February 1, 2011]␍␊ |
5 | * Copyright (c) 1998-2011 Glenn Randers-Pehrson␍␊ |
6 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)␍␊ |
7 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)␍␊ |
8 | *␍␊ |
9 | * This code is released under the libpng license.␍␊ |
10 | * For conditions of distribution and use, see the disclaimer␍␊ |
11 | * and license in png.h␍␊ |
12 | *␍␊ |
13 | * This file provides a location for all error handling. Users who␍␊ |
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␍␊ |
16 | * at each function.␍␊ |
17 | */␍␊ |
18 | ␍␊ |
19 | #include "pngpriv.h"␍␊ |
20 | ␍␊ |
21 | #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)␍␊ |
22 | ␍␊ |
23 | static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr,␍␊ |
24 | png_const_charp error_message)),PNG_NORETURN);␍␊ |
25 | ␍␊ |
26 | #ifdef PNG_WARNINGS_SUPPORTED␍␊ |
27 | static void /* PRIVATE */␍␊ |
28 | png_default_warning PNGARG((png_structp png_ptr,␍␊ |
29 | png_const_charp warning_message));␍␊ |
30 | #endif /* PNG_WARNINGS_SUPPORTED */␍␊ |
31 | ␍␊ |
32 | /* 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 | * you should supply a replacement error function and use png_set_error_fn()␍␊ |
35 | * to replace the error function at run-time.␍␊ |
36 | */␍␊ |
37 | #ifdef PNG_ERROR_TEXT_SUPPORTED␍␊ |
38 | PNG_FUNCTION(void,PNGAPI␍␊ |
39 | png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)␍␊ |
40 | {␍␊ |
41 | #ifdef PNG_ERROR_NUMBERS_SUPPORTED␍␊ |
42 | char msg[16];␍␊ |
43 | if (png_ptr != NULL)␍␊ |
44 | {␍␊ |
45 | if (png_ptr->flags&␍␊ |
46 | (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))␍␊ |
47 | {␍␊ |
48 | if (*error_message == PNG_LITERAL_SHARP)␍␊ |
49 | {␍␊ |
50 | /* Strip "#nnnn " from beginning of error message. */␍␊ |
51 | int offset;␍␊ |
52 | for (offset = 1; offset<15; offset++)␍␊ |
53 | if (error_message[offset] == ' ')␍␊ |
54 | break;␍␊ |
55 | ␍␊ |
56 | if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)␍␊ |
57 | {␍␊ |
58 | int i;␍␊ |
59 | for (i = 0; i < offset - 1; i++)␍␊ |
60 | msg[i] = error_message[i + 1];␍␊ |
61 | msg[i - 1] = '\0';␍␊ |
62 | error_message = msg;␍␊ |
63 | }␍␊ |
64 | ␍␊ |
65 | else␍␊ |
66 | error_message += offset;␍␊ |
67 | }␍␊ |
68 | ␍␊ |
69 | else␍␊ |
70 | {␍␊ |
71 | if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)␍␊ |
72 | {␍␊ |
73 | msg[0] = '0';␍␊ |
74 | msg[1] = '\0';␍␊ |
75 | error_message = msg;␍␊ |
76 | }␍␊ |
77 | }␍␊ |
78 | }␍␊ |
79 | }␍␊ |
80 | #endif␍␊ |
81 | if (png_ptr != NULL && png_ptr->error_fn != NULL)␍␊ |
82 | (*(png_ptr->error_fn))(png_ptr, error_message);␍␊ |
83 | ␍␊ |
84 | /* If the custom handler doesn't exist, or if it returns,␍␊ |
85 | use the default handler, which will not return. */␍␊ |
86 | png_default_error(png_ptr, error_message);␍␊ |
87 | }␍␊ |
88 | #else␍␊ |
89 | PNG_FUNCTION(void,PNGAPI␍␊ |
90 | png_err,(png_structp png_ptr),PNG_NORETURN)␍␊ |
91 | {␍␊ |
92 | /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed␍␊ |
93 | * erroneously as '\0', instead of the empty string "". This was␍␊ |
94 | * apparently an error, introduced in libpng-1.2.20, and png_default_error␍␊ |
95 | * will crash in this case.␍␊ |
96 | */␍␊ |
97 | if (png_ptr != NULL && png_ptr->error_fn != NULL)␍␊ |
98 | (*(png_ptr->error_fn))(png_ptr, "");␍␊ |
99 | ␍␊ |
100 | /* If the custom handler doesn't exist, or if it returns,␍␊ |
101 | use the default handler, which will not return. */␍␊ |
102 | png_default_error(png_ptr, "");␍␊ |
103 | }␍␊ |
104 | #endif /* PNG_ERROR_TEXT_SUPPORTED */␍␊ |
105 | ␍␊ |
106 | /* Utility to safely appends strings to a buffer. This never errors out so␍␊ |
107 | * error checking is not required in the caller.␍␊ |
108 | */␍␊ |
109 | size_t␍␊ |
110 | png_safecat(png_charp buffer, size_t bufsize, size_t pos,␍␊ |
111 | png_const_charp string)␍␊ |
112 | {␍␊ |
113 | if (buffer != NULL && pos < bufsize)␍␊ |
114 | {␍␊ |
115 | if (string != NULL)␍␊ |
116 | while (*string != '\0' && pos < bufsize-1)␍␊ |
117 | buffer[pos++] = *string++;␍␊ |
118 | ␍␊ |
119 | buffer[pos] = '\0';␍␊ |
120 | }␍␊ |
121 | ␍␊ |
122 | return pos;␍␊ |
123 | }␍␊ |
124 | ␍␊ |
125 | #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)␍␊ |
126 | /* Utility to dump an unsigned value into a buffer, given a start pointer and␍␊ |
127 | * and end pointer (which should point just *beyond* the end of the buffer!)␍␊ |
128 | * Returns the pointer to the start of the formatted string.␍␊ |
129 | */␍␊ |
130 | png_charp␍␊ |
131 | png_format_number(png_const_charp start, png_charp end, int format,␍␊ |
132 | png_alloc_size_t number)␍␊ |
133 | {␍␊ |
134 | int count = 0; /* number of digits output */␍␊ |
135 | int mincount = 1; /* minimum number required */␍␊ |
136 | int output = 0; /* digit output (for the fixed point format) */␍␊ |
137 | ␍␊ |
138 | *--end = '\0';␍␊ |
139 | ␍␊ |
140 | /* This is written so that the loop always runs at least once, even with␍␊ |
141 | * number zero.␍␊ |
142 | */␍␊ |
143 | while (end > start && (number != 0 || count < mincount))␍␊ |
144 | {␍␊ |
145 | ␍␊ |
146 | static const char digits[] = "0123456789ABCDEF";␍␊ |
147 | ␍␊ |
148 | switch (format)␍␊ |
149 | {␍␊ |
150 | case PNG_NUMBER_FORMAT_fixed:␍␊ |
151 | /* Needs five digits (the fraction) */␍␊ |
152 | mincount = 5;␍␊ |
153 | if (output || number % 10 != 0)␍␊ |
154 | {␍␊ |
155 | *--end = digits[number % 10];␍␊ |
156 | output = 1;␍␊ |
157 | }␍␊ |
158 | number /= 10;␍␊ |
159 | break;␍␊ |
160 | ␍␊ |
161 | case PNG_NUMBER_FORMAT_02u:␍␊ |
162 | /* Expects at least 2 digits. */␍␊ |
163 | mincount = 2;␍␊ |
164 | /* fall through */␍␊ |
165 | ␍␊ |
166 | case PNG_NUMBER_FORMAT_u:␍␊ |
167 | *--end = digits[number % 10];␍␊ |
168 | number /= 10;␍␊ |
169 | break;␍␊ |
170 | ␍␊ |
171 | case PNG_NUMBER_FORMAT_02x:␍␊ |
172 | /* This format expects at least two digits */␍␊ |
173 | mincount = 2;␍␊ |
174 | /* fall through */␍␊ |
175 | ␍␊ |
176 | case PNG_NUMBER_FORMAT_x:␍␊ |
177 | *--end = digits[number & 0xf];␍␊ |
178 | number >>= 4;␍␊ |
179 | break;␍␊ |
180 | ␍␊ |
181 | default: /* an error */␍␊ |
182 | number = 0;␍␊ |
183 | break;␍␊ |
184 | }␍␊ |
185 | ␍␊ |
186 | /* Keep track of the number of digits added */␍␊ |
187 | ++count;␍␊ |
188 | ␍␊ |
189 | /* Float a fixed number here: */␍␊ |
190 | if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)␍␊ |
191 | {␍␊ |
192 | /* End of the fraction, but maybe nothing was output? In that case␍␊ |
193 | * drop the decimal point. If the number is a true zero handle that␍␊ |
194 | * here.␍␊ |
195 | */␍␊ |
196 | if (output)␍␊ |
197 | *--end = '.';␍␊ |
198 | else if (number == 0) /* and !output */␍␊ |
199 | *--end = '0';␍␊ |
200 | }␍␊ |
201 | }␍␊ |
202 | ␍␊ |
203 | return end;␍␊ |
204 | }␍␊ |
205 | #endif␍␊ |
206 | ␍␊ |
207 | #ifdef PNG_WARNINGS_SUPPORTED␍␊ |
208 | /* This function is called whenever there is a non-fatal error. This function␍␊ |
209 | * should not be changed. If there is a need to handle warnings differently,␍␊ |
210 | * you should supply a replacement warning function and use␍␊ |
211 | * png_set_error_fn() to replace the warning function at run-time.␍␊ |
212 | */␍␊ |
213 | void PNGAPI␍␊ |
214 | png_warning(png_structp png_ptr, png_const_charp warning_message)␍␊ |
215 | {␍␊ |
216 | int offset = 0;␍␊ |
217 | if (png_ptr != NULL)␍␊ |
218 | {␍␊ |
219 | #ifdef PNG_ERROR_NUMBERS_SUPPORTED␍␊ |
220 | if (png_ptr->flags&␍␊ |
221 | (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))␍␊ |
222 | #endif␍␊ |
223 | {␍␊ |
224 | if (*warning_message == PNG_LITERAL_SHARP)␍␊ |
225 | {␍␊ |
226 | for (offset = 1; offset < 15; offset++)␍␊ |
227 | if (warning_message[offset] == ' ')␍␊ |
228 | break;␍␊ |
229 | }␍␊ |
230 | }␍␊ |
231 | }␍␊ |
232 | if (png_ptr != NULL && png_ptr->warning_fn != NULL)␍␊ |
233 | (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);␍␊ |
234 | else␍␊ |
235 | png_default_warning(png_ptr, warning_message + offset);␍␊ |
236 | }␍␊ |
237 | ␍␊ |
238 | /* These functions support 'formatted' warning messages with up to␍␊ |
239 | * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter␍␊ |
240 | * is introduced by @<number>, where 'number' starts at 1. This follows the␍␊ |
241 | * standard established by X/Open for internationalizable error messages.␍␊ |
242 | */␍␊ |
243 | void␍␊ |
244 | png_warning_parameter(png_warning_parameters p, int number,␍␊ |
245 | png_const_charp string)␍␊ |
246 | {␍␊ |
247 | if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)␍␊ |
248 | (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);␍␊ |
249 | }␍␊ |
250 | ␍␊ |
251 | void␍␊ |
252 | png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,␍␊ |
253 | png_alloc_size_t value)␍␊ |
254 | {␍␊ |
255 | char buffer[PNG_NUMBER_BUFFER_SIZE];␍␊ |
256 | png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));␍␊ |
257 | }␍␊ |
258 | ␍␊ |
259 | void␍␊ |
260 | png_warning_parameter_signed(png_warning_parameters p, int number, int format,␍␊ |
261 | png_int_32 value)␍␊ |
262 | {␍␊ |
263 | png_alloc_size_t u;␍␊ |
264 | png_charp str;␍␊ |
265 | char buffer[PNG_NUMBER_BUFFER_SIZE];␍␊ |
266 | ␍␊ |
267 | /* Avoid overflow by doing the negate in a png_alloc_size_t: */␍␊ |
268 | u = (png_alloc_size_t)value;␍␊ |
269 | if (value < 0)␍␊ |
270 | u = ~u + 1;␍␊ |
271 | ␍␊ |
272 | str = PNG_FORMAT_NUMBER(buffer, format, u);␍␊ |
273 | ␍␊ |
274 | if (value < 0 && str > buffer)␍␊ |
275 | *--str = '-';␍␊ |
276 | ␍␊ |
277 | png_warning_parameter(p, number, str);␍␊ |
278 | }␍␊ |
279 | ␍␊ |
280 | void␍␊ |
281 | png_formatted_warning(png_structp png_ptr, png_warning_parameters p,␍␊ |
282 | png_const_charp message)␍␊ |
283 | {␍␊ |
284 | /* The internal buffer is just 192 bytes - enough for all our messages,␍␊ |
285 | * overflow doesn't happen because this code checks! If someone figures␍␊ |
286 | * out how to send us a message longer than 192 bytes, all that will␍␊ |
287 | * happen is that the message will be truncated appropriately.␍␊ |
288 | */␍␊ |
289 | size_t i = 0; /* Index in the msg[] buffer: */␍␊ |
290 | char msg[192];␍␊ |
291 | ␍␊ |
292 | /* Each iteration through the following loop writes at most one character␍␊ |
293 | * to msg[i++] then returns here to validate that there is still space for␍␊ |
294 | * the trailing '\0'. It may (in the case of a parameter) read more than␍␊ |
295 | * one character from message[]; it must check for '\0' and continue to the␍␊ |
296 | * test if it finds the end of string.␍␊ |
297 | */␍␊ |
298 | while (i<(sizeof msg)-1 && *message != '\0')␍␊ |
299 | {␍␊ |
300 | /* '@' at end of string is now just printed (previously it was skipped);␍␊ |
301 | * it is an error in the calling code to terminate the string with @.␍␊ |
302 | */␍␊ |
303 | if (p != NULL && *message == '@' && message[1] != '\0')␍␊ |
304 | {␍␊ |
305 | int parameter_char = *++message; /* Consume the '@' */␍␊ |
306 | static const char valid_parameters[] = "123456789";␍␊ |
307 | int parameter = 0;␍␊ |
308 | ␍␊ |
309 | /* Search for the parameter digit, the index in the string is the␍␊ |
310 | * parameter to use.␍␊ |
311 | */␍␊ |
312 | while (valid_parameters[parameter] != parameter_char &&␍␊ |
313 | valid_parameters[parameter] != '\0')␍␊ |
314 | ++parameter;␍␊ |
315 | ␍␊ |
316 | /* If the parameter digit is out of range it will just get printed. */␍␊ |
317 | if (parameter < PNG_WARNING_PARAMETER_COUNT)␍␊ |
318 | {␍␊ |
319 | /* Append this parameter */␍␊ |
320 | png_const_charp parm = p[parameter];␍␊ |
321 | png_const_charp pend = p[parameter] + (sizeof p[parameter]);␍␊ |
322 | ␍␊ |
323 | /* No need to copy the trailing '\0' here, but there is no guarantee␍␊ |
324 | * that parm[] has been initialized, so there is no guarantee of a␍␊ |
325 | * trailing '\0':␍␊ |
326 | */␍␊ |
327 | while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)␍␊ |
328 | msg[i++] = *parm++;␍␊ |
329 | ␍␊ |
330 | /* Consume the parameter digit too: */␍␊ |
331 | ++message;␍␊ |
332 | continue;␍␊ |
333 | }␍␊ |
334 | ␍␊ |
335 | /* else not a parameter and there is a character after the @ sign; just␍␊ |
336 | * copy that. This is known not to be '\0' because of the test above.␍␊ |
337 | */␍␊ |
338 | }␍␊ |
339 | ␍␊ |
340 | /* At this point *message can't be '\0', even in the bad parameter case␍␊ |
341 | * above where there is a lone '@' at the end of the message string.␍␊ |
342 | */␍␊ |
343 | msg[i++] = *message++;␍␊ |
344 | }␍␊ |
345 | ␍␊ |
346 | /* i is always less than (sizeof msg), so: */␍␊ |
347 | msg[i] = '\0';␍␊ |
348 | ␍␊ |
349 | /* And this is the formatted message, it may be larger than␍␊ |
350 | * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are␍␊ |
351 | * not (currently) formatted.␍␊ |
352 | */␍␊ |
353 | png_warning(png_ptr, msg);␍␊ |
354 | }␍␊ |
355 | #endif /* PNG_WARNINGS_SUPPORTED */␍␊ |
356 | ␍␊ |
357 | #ifdef PNG_BENIGN_ERRORS_SUPPORTED␍␊ |
358 | void PNGAPI␍␊ |
359 | png_benign_error(png_structp png_ptr, png_const_charp error_message)␍␊ |
360 | {␍␊ |
361 | if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)␍␊ |
362 | png_warning(png_ptr, error_message);␍␊ |
363 | else␍␊ |
364 | png_error(png_ptr, error_message);␍␊ |
365 | }␍␊ |
366 | #endif␍␊ |
367 | ␍␊ |
368 | /* These utilities are used internally to build an error message that relates␍␊ |
369 | * to the current chunk. The chunk name comes from png_ptr->chunk_name,␍␊ |
370 | * this is used to prefix the message. The message is limited in length␍␊ |
371 | * to 63 bytes, the name characters are output as hex digits wrapped in []␍␊ |
372 | * if the character is invalid.␍␊ |
373 | */␍␊ |
374 | #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))␍␊ |
375 | static PNG_CONST char png_digit[16] = {␍␊ |
376 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',␍␊ |
377 | 'A', 'B', 'C', 'D', 'E', 'F'␍␊ |
378 | };␍␊ |
379 | ␍␊ |
380 | #define PNG_MAX_ERROR_TEXT 64␍␊ |
381 | #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)␍␊ |
382 | static void /* PRIVATE */␍␊ |
383 | png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp␍␊ |
384 | error_message)␍␊ |
385 | {␍␊ |
386 | png_uint_32 chunk_name = png_ptr->chunk_name;␍␊ |
387 | int iout = 0, ishift = 24;␍␊ |
388 | ␍␊ |
389 | while (ishift >= 0)␍␊ |
390 | {␍␊ |
391 | int c = (int)(chunk_name >> ishift) & 0xff;␍␊ |
392 | ␍␊ |
393 | ishift -= 8;␍␊ |
394 | if (isnonalpha(c))␍␊ |
395 | {␍␊ |
396 | buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;␍␊ |
397 | buffer[iout++] = png_digit[(c & 0xf0) >> 4];␍␊ |
398 | buffer[iout++] = png_digit[c & 0x0f];␍␊ |
399 | buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;␍␊ |
400 | }␍␊ |
401 | ␍␊ |
402 | else␍␊ |
403 | {␍␊ |
404 | buffer[iout++] = (char)c;␍␊ |
405 | }␍␊ |
406 | }␍␊ |
407 | ␍␊ |
408 | if (error_message == NULL)␍␊ |
409 | buffer[iout] = '\0';␍␊ |
410 | ␍␊ |
411 | else␍␊ |
412 | {␍␊ |
413 | int iin = 0;␍␊ |
414 | ␍␊ |
415 | buffer[iout++] = ':';␍␊ |
416 | buffer[iout++] = ' ';␍␊ |
417 | ␍␊ |
418 | while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')␍␊ |
419 | buffer[iout++] = error_message[iin++];␍␊ |
420 | ␍␊ |
421 | /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */␍␊ |
422 | buffer[iout] = '\0';␍␊ |
423 | }␍␊ |
424 | }␍␊ |
425 | #endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */␍␊ |
426 | ␍␊ |
427 | #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)␍␊ |
428 | PNG_FUNCTION(void,PNGAPI␍␊ |
429 | png_chunk_error,(png_structp png_ptr, png_const_charp error_message),␍␊ |
430 | PNG_NORETURN)␍␊ |
431 | {␍␊ |
432 | char msg[18+PNG_MAX_ERROR_TEXT];␍␊ |
433 | if (png_ptr == NULL)␍␊ |
434 | png_error(png_ptr, error_message);␍␊ |
435 | ␍␊ |
436 | else␍␊ |
437 | {␍␊ |
438 | png_format_buffer(png_ptr, msg, error_message);␍␊ |
439 | png_error(png_ptr, msg);␍␊ |
440 | }␍␊ |
441 | }␍␊ |
442 | #endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */␍␊ |
443 | ␍␊ |
444 | #ifdef PNG_WARNINGS_SUPPORTED␍␊ |
445 | void PNGAPI␍␊ |
446 | png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)␍␊ |
447 | {␍␊ |
448 | char msg[18+PNG_MAX_ERROR_TEXT];␍␊ |
449 | if (png_ptr == NULL)␍␊ |
450 | png_warning(png_ptr, warning_message);␍␊ |
451 | ␍␊ |
452 | else␍␊ |
453 | {␍␊ |
454 | png_format_buffer(png_ptr, msg, warning_message);␍␊ |
455 | png_warning(png_ptr, msg);␍␊ |
456 | }␍␊ |
457 | }␍␊ |
458 | #endif /* PNG_WARNINGS_SUPPORTED */␍␊ |
459 | ␍␊ |
460 | #ifdef PNG_READ_SUPPORTED␍␊ |
461 | #ifdef PNG_BENIGN_ERRORS_SUPPORTED␍␊ |
462 | void PNGAPI␍␊ |
463 | png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)␍␊ |
464 | {␍␊ |
465 | if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)␍␊ |
466 | png_chunk_warning(png_ptr, error_message);␍␊ |
467 | ␍␊ |
468 | else␍␊ |
469 | png_chunk_error(png_ptr, error_message);␍␊ |
470 | }␍␊ |
471 | #endif␍␊ |
472 | #endif /* PNG_READ_SUPPORTED */␍␊ |
473 | ␍␊ |
474 | #ifdef PNG_ERROR_TEXT_SUPPORTED␍␊ |
475 | #ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
476 | PNG_FUNCTION(void,␍␊ |
477 | png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN)␍␊ |
478 | {␍␊ |
479 | # define fixed_message "fixed point overflow in "␍␊ |
480 | # define fixed_message_ln ((sizeof fixed_message)-1)␍␊ |
481 | int iin;␍␊ |
482 | char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];␍␊ |
483 | png_memcpy(msg, fixed_message, fixed_message_ln);␍␊ |
484 | iin = 0;␍␊ |
485 | if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)␍␊ |
486 | {␍␊ |
487 | msg[fixed_message_ln + iin] = name[iin];␍␊ |
488 | ++iin;␍␊ |
489 | }␍␊ |
490 | msg[fixed_message_ln + iin] = 0;␍␊ |
491 | png_error(png_ptr, msg);␍␊ |
492 | }␍␊ |
493 | #endif␍␊ |
494 | #endif␍␊ |
495 | ␍␊ |
496 | #ifdef PNG_SETJMP_SUPPORTED␍␊ |
497 | /* This API only exists if ANSI-C style error handling is used,␍␊ |
498 | * otherwise it is necessary for png_default_error to be overridden.␍␊ |
499 | */␍␊ |
500 | jmp_buf* PNGAPI␍␊ |
501 | png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,␍␊ |
502 | size_t jmp_buf_size)␍␊ |
503 | {␍␊ |
504 | if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))␍␊ |
505 | return NULL;␍␊ |
506 | ␍␊ |
507 | png_ptr->longjmp_fn = longjmp_fn;␍␊ |
508 | return &png_ptr->longjmp_buffer;␍␊ |
509 | }␍␊ |
510 | #endif␍␊ |
511 | ␍␊ |
512 | /* This is the default error handling function. Note that replacements for␍␊ |
513 | * this function MUST NOT RETURN, or the program will likely crash. This␍␊ |
514 | * function is used by default, or if the program supplies NULL for the␍␊ |
515 | * error function pointer in png_set_error_fn().␍␊ |
516 | */␍␊ |
517 | static PNG_FUNCTION(void /* PRIVATE */,␍␊ |
518 | png_default_error,(png_structp png_ptr, png_const_charp error_message),␍␊ |
519 | PNG_NORETURN)␍␊ |
520 | {␍␊ |
521 | #ifdef PNG_CONSOLE_IO_SUPPORTED␍␊ |
522 | #ifdef PNG_ERROR_NUMBERS_SUPPORTED␍␊ |
523 | /* Check on NULL only added in 1.5.4 */␍␊ |
524 | if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)␍␊ |
525 | {␍␊ |
526 | /* Strip "#nnnn " from beginning of error message. */␍␊ |
527 | int offset;␍␊ |
528 | char error_number[16];␍␊ |
529 | for (offset = 0; offset<15; offset++)␍␊ |
530 | {␍␊ |
531 | error_number[offset] = error_message[offset + 1];␍␊ |
532 | if (error_message[offset] == ' ')␍␊ |
533 | break;␍␊ |
534 | }␍␊ |
535 | ␍␊ |
536 | if ((offset > 1) && (offset < 15))␍␊ |
537 | {␍␊ |
538 | error_number[offset - 1] = '\0';␍␊ |
539 | fprintf(stderr, "libpng error no. %s: %s",␍␊ |
540 | error_number, error_message + offset + 1);␍␊ |
541 | fprintf(stderr, PNG_STRING_NEWLINE);␍␊ |
542 | }␍␊ |
543 | ␍␊ |
544 | else␍␊ |
545 | {␍␊ |
546 | fprintf(stderr, "libpng error: %s, offset=%d",␍␊ |
547 | error_message, offset);␍␊ |
548 | fprintf(stderr, PNG_STRING_NEWLINE);␍␊ |
549 | }␍␊ |
550 | }␍␊ |
551 | else␍␊ |
552 | #endif␍␊ |
553 | {␍␊ |
554 | printf( "libpng error: %s", error_message ? error_message :␍␊ |
555 | "undefined");␍␊ |
556 | printf("%s", PNG_STRING_NEWLINE);␍␊ |
557 | }␍␊ |
558 | #else␍␊ |
559 | PNG_UNUSED(error_message) /* Make compiler happy */␍␊ |
560 | #endif␍␊ |
561 | png_longjmp(png_ptr, 1);␍␊ |
562 | }␍␊ |
563 | ␍␊ |
564 | PNG_FUNCTION(void,PNGAPI␍␊ |
565 | png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN)␍␊ |
566 | {␍␊ |
567 | #ifdef PNG_SETJMP_SUPPORTED␍␊ |
568 | if (png_ptr && png_ptr->longjmp_fn)␍␊ |
569 | {␍␊ |
570 | # ifdef USE_FAR_KEYWORD␍␊ |
571 | {␍␊ |
572 | jmp_buf tmp_jmpbuf;␍␊ |
573 | png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf));␍␊ |
574 | png_ptr->longjmp_fn(tmp_jmpbuf, val);␍␊ |
575 | }␍␊ |
576 | ␍␊ |
577 | # else␍␊ |
578 | png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val);␍␊ |
579 | # endif␍␊ |
580 | }␍␊ |
581 | #endif␍␊ |
582 | /* Here if not setjmp support or if png_ptr is null. */␍␊ |
583 | PNG_ABORT();␍␊ |
584 | }␍␊ |
585 | ␍␊ |
586 | #ifdef PNG_WARNINGS_SUPPORTED␍␊ |
587 | /* This function is called when there is a warning, but the library thinks␍␊ |
588 | * it can continue anyway. Replacement functions don't have to do anything␍␊ |
589 | * here if you don't want them to. In the default configuration, png_ptr is␍␊ |
590 | * not used, but it is passed in case it may be useful.␍␊ |
591 | */␍␊ |
592 | static void /* PRIVATE */␍␊ |
593 | png_default_warning(png_structp png_ptr, png_const_charp warning_message)␍␊ |
594 | {␍␊ |
595 | #ifdef PNG_CONSOLE_IO_SUPPORTED␍␊ |
596 | # ifdef PNG_ERROR_NUMBERS_SUPPORTED␍␊ |
597 | if (*warning_message == PNG_LITERAL_SHARP)␍␊ |
598 | {␍␊ |
599 | int offset;␍␊ |
600 | char warning_number[16];␍␊ |
601 | for (offset = 0; offset < 15; offset++)␍␊ |
602 | {␍␊ |
603 | warning_number[offset] = warning_message[offset + 1];␍␊ |
604 | if (warning_message[offset] == ' ')␍␊ |
605 | break;␍␊ |
606 | }␍␊ |
607 | ␍␊ |
608 | if ((offset > 1) && (offset < 15))␍␊ |
609 | {␍␊ |
610 | warning_number[offset + 1] = '\0';␍␊ |
611 | fprintf(stderr, "libpng warning no. %s: %s",␍␊ |
612 | warning_number, warning_message + offset);␍␊ |
613 | fprintf(stderr, PNG_STRING_NEWLINE);␍␊ |
614 | }␍␊ |
615 | ␍␊ |
616 | else␍␊ |
617 | {␍␊ |
618 | fprintf(stderr, "libpng warning: %s",␍␊ |
619 | warning_message);␍␊ |
620 | fprintf(stderr, PNG_STRING_NEWLINE);␍␊ |
621 | }␍␊ |
622 | }␍␊ |
623 | else␍␊ |
624 | # endif␍␊ |
625 | ␍␊ |
626 | {␍␊ |
627 | printf( "libpng warning: %s", warning_message);␍␊ |
628 | printf("%s", PNG_STRING_NEWLINE);␍␊ |
629 | }␍␊ |
630 | #else␍␊ |
631 | PNG_UNUSED(warning_message) /* Make compiler happy */␍␊ |
632 | #endif␍␊ |
633 | PNG_UNUSED(png_ptr) /* Make compiler happy */␍␊ |
634 | }␍␊ |
635 | #endif /* PNG_WARNINGS_SUPPORTED */␍␊ |
636 | ␍␊ |
637 | /* This function is called when the application wants to use another method␍␊ |
638 | * of handling errors and warnings. Note that the error function MUST NOT␍␊ |
639 | * return to the calling routine or serious problems will occur. The return␍␊ |
640 | * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1)␍␊ |
641 | */␍␊ |
642 | void PNGAPI␍␊ |
643 | png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,␍␊ |
644 | png_error_ptr error_fn, png_error_ptr warning_fn)␍␊ |
645 | {␍␊ |
646 | if (png_ptr == NULL)␍␊ |
647 | return;␍␊ |
648 | ␍␊ |
649 | png_ptr->error_ptr = error_ptr;␍␊ |
650 | png_ptr->error_fn = error_fn;␍␊ |
651 | #ifdef PNG_WARNINGS_SUPPORTED␍␊ |
652 | png_ptr->warning_fn = warning_fn;␍␊ |
653 | #else␍␊ |
654 | PNG_UNUSED(warning_fn)␍␊ |
655 | #endif␍␊ |
656 | }␍␊ |
657 | ␍␊ |
658 | ␍␊ |
659 | /* This function returns a pointer to the error_ptr associated with the user␍␊ |
660 | * functions. The application should free any memory associated with this␍␊ |
661 | * pointer before png_write_destroy and png_read_destroy are called.␍␊ |
662 | */␍␊ |
663 | png_voidp PNGAPI␍␊ |
664 | png_get_error_ptr(png_const_structp png_ptr)␍␊ |
665 | {␍␊ |
666 | if (png_ptr == NULL)␍␊ |
667 | return NULL;␍␊ |
668 | ␍␊ |
669 | return ((png_voidp)png_ptr->error_ptr);␍␊ |
670 | }␍␊ |
671 | ␍␊ |
672 | ␍␊ |
673 | #ifdef PNG_ERROR_NUMBERS_SUPPORTED␍␊ |
674 | void PNGAPI␍␊ |
675 | png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)␍␊ |
676 | {␍␊ |
677 | if (png_ptr != NULL)␍␊ |
678 | {␍␊ |
679 | png_ptr->flags &=␍␊ |
680 | ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |␍␊ |
681 | PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);␍␊ |
682 | }␍␊ |
683 | }␍␊ |
684 | #endif␍␊ |
685 | #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */␍␊ |
686 | |