1 
2 /* pngerror.c - stub functions for i/o and memory allocation
3  *
4  * Copyright (c) 2018 Cosmin Truta
5  * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
6  * Copyright (c) 1996-1997 Andreas Dilger
7  * 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_const_structrp png_ptr,
24     png_const_charp error_message)),PNG_NORETURN);
25 
26 PNG_FUNCTION(void,PNGAPI
27 png_err,(png_const_structrp png_ptr),PNG_NORETURN)
28 {
29    if (png_ptr != NULL && png_ptr->error_fn != NULL)
30       (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
31    png_default_error(png_ptr, "");
32 }
33 size_t
png_safecat(png_charp buffer,size_t bufsize,size_t pos,png_const_charp string)34 png_safecat(png_charp buffer, size_t bufsize, size_t pos,
35     png_const_charp string)
36 {
37    if (buffer != NULL && pos < bufsize)
38    {
39       if (string != NULL)
40          while (*string != '\0' && pos < bufsize-1)
41            buffer[pos++] = *string++;
42 
43       buffer[pos] = '\0';
44    }
45 
46    return pos;
47 }
48 
49 #define PNG_MAX_ERROR_TEXT 196
50 
51 void
png_chunk_report(png_const_structrp png_ptr,png_const_charp message,int error)52 png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
53 {
54 #  ifndef PNG_WARNINGS_SUPPORTED
55       PNG_UNUSED(message)
56 #  endif
57 
58 
59 #  ifdef PNG_WRITE_SUPPORTED
60       {
61          if (error < PNG_CHUNK_WRITE_ERROR)
62             png_app_warning(png_ptr, message);
63 
64          else
65             png_app_error(png_ptr, message);
66       }
67 #  endif
68 }
69 
70 #ifdef PNG_SETJMP_SUPPORTED
71 jmp_buf* PNGAPI
png_set_longjmp_fn(png_structrp png_ptr,png_longjmp_ptr longjmp_fn,size_t jmp_buf_size)72 png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
73     size_t jmp_buf_size)
74 {
75    if (png_ptr == NULL)
76       return NULL;
77 
78    if (png_ptr->jmp_buf_ptr == NULL)
79    {
80       png_ptr->jmp_buf_size = 0;
81 
82       if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
83          png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
84 
85       else
86       {
87          png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
88              png_malloc_warn(png_ptr, jmp_buf_size));
89 
90          if (png_ptr->jmp_buf_ptr == NULL)
91             return NULL;
92 
93          png_ptr->jmp_buf_size = jmp_buf_size;
94       }
95    }
96 
97    else
98    {
99       size_t size = png_ptr->jmp_buf_size;
100 
101       if (size == 0)
102       {
103          size = (sizeof png_ptr->jmp_buf_local);
104          if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
105          {
106             png_error(png_ptr, "Libpng jmp_buf still allocated");
107          }
108       }
109 
110       if (size != jmp_buf_size)
111       {
112          png_warning(png_ptr, "Application jmp_buf size changed");
113          return NULL;
114       }
115    }
116    png_ptr->longjmp_fn = longjmp_fn;
117    return png_ptr->jmp_buf_ptr;
118 }
119 
120 void
png_free_jmpbuf(png_structrp png_ptr)121 png_free_jmpbuf(png_structrp png_ptr)
122 {
123    if (png_ptr != NULL)
124    {
125       jmp_buf *jb = png_ptr->jmp_buf_ptr;
126       if (jb != NULL && png_ptr->jmp_buf_size > 0)
127       {
128          if (jb != &png_ptr->jmp_buf_local)
129          {
130             jmp_buf free_jmp_buf;
131 
132             if (!setjmp(free_jmp_buf))
133             {
134                png_ptr->jmp_buf_ptr = &free_jmp_buf;
135                png_ptr->jmp_buf_size = 0;
136                png_ptr->longjmp_fn = longjmp;
137                png_free(png_ptr, jb);
138             }
139          }
140       }
141       png_ptr->jmp_buf_size = 0;
142       png_ptr->jmp_buf_ptr = NULL;
143       png_ptr->longjmp_fn = 0;
144    }
145 }
146 #endif
147 static PNG_FUNCTION(void,
148 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
149     PNG_NORETURN)
150 {
151    PNG_UNUSED(error_message)
152    png_longjmp(png_ptr, 1);
153 }
154 
155 PNG_FUNCTION(void,PNGAPI
156 png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
157 {
158 #ifdef PNG_SETJMP_SUPPORTED
159    if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
160        png_ptr->jmp_buf_ptr != NULL)
161       png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
162 #else
163    PNG_UNUSED(png_ptr)
164    PNG_UNUSED(val)
165 #endif
166    PNG_ABORT();
167 }
168 void PNGAPI
png_set_error_fn(png_structrp png_ptr,png_voidp error_ptr,png_error_ptr error_fn,png_error_ptr warning_fn)169 png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
170     png_error_ptr error_fn, png_error_ptr warning_fn)
171 {
172    if (png_ptr == NULL)
173       return;
174 
175    png_ptr->error_ptr = error_ptr;
176    png_ptr->error_fn = error_fn;
177 #ifdef PNG_WARNINGS_SUPPORTED
178    png_ptr->warning_fn = warning_fn;
179 #else
180    PNG_UNUSED(warning_fn)
181 #endif
182 }
183 png_voidp PNGAPI
png_get_error_ptr(png_const_structrp png_ptr)184 png_get_error_ptr(png_const_structrp png_ptr)
185 {
186    if (png_ptr == NULL)
187       return NULL;
188 
189    return ((png_voidp)png_ptr->error_ptr);
190 }
191 #endif
192