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