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