Subversion Repositories Kolibri OS

Rev

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 @, where 'number' starts at 1.  This follows the
-
 
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)