Path: blob/master/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
41154 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/* pngerror.c - stub functions for i/o and memory allocation25*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file and, per its terms, should not be removed:30*31* Copyright (c) 2018 Cosmin Truta32* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson33* Copyright (c) 1996-1997 Andreas Dilger34* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.35*36* This code is released under the libpng license.37* For conditions of distribution and use, see the disclaimer38* and license in png.h39*40* This file provides a location for all error handling. Users who41* need special error handling are expected to write replacement functions42* and use png_set_error_fn() to use those functions. See the instructions43* at each function.44*/4546#include "pngpriv.h"4748#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)4950static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,51png_const_charp error_message)),PNG_NORETURN);5253#ifdef PNG_WARNINGS_SUPPORTED54static void /* PRIVATE */55png_default_warning PNGARG((png_const_structrp png_ptr,56png_const_charp warning_message));57#endif /* WARNINGS */5859/* This function is called whenever there is a fatal error. This function60* should not be changed. If there is a need to handle errors differently,61* you should supply a replacement error function and use png_set_error_fn()62* to replace the error function at run-time.63*/64#ifdef PNG_ERROR_TEXT_SUPPORTED65PNG_FUNCTION(void,PNGAPI66png_error,(png_const_structrp png_ptr, png_const_charp error_message),67PNG_NORETURN)68{69#ifdef PNG_ERROR_NUMBERS_SUPPORTED70char msg[16];71if (png_ptr != NULL)72{73if ((png_ptr->flags &74(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)75{76if (*error_message == PNG_LITERAL_SHARP)77{78/* Strip "#nnnn " from beginning of error message. */79int offset;80for (offset = 1; offset<15; offset++)81if (error_message[offset] == ' ')82break;8384if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)85{86int i;87for (i = 0; i < offset - 1; i++)88msg[i] = error_message[i + 1];89msg[i - 1] = '\0';90error_message = msg;91}9293else94error_message += offset;95}9697else98{99if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)100{101msg[0] = '0';102msg[1] = '\0';103error_message = msg;104}105}106}107}108#endif109if (png_ptr != NULL && png_ptr->error_fn != NULL)110(*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),111error_message);112113/* If the custom handler doesn't exist, or if it returns,114use the default handler, which will not return. */115png_default_error(png_ptr, error_message);116}117#else118PNG_FUNCTION(void,PNGAPI119png_err,(png_const_structrp png_ptr),PNG_NORETURN)120{121/* Prior to 1.5.2 the error_fn received a NULL pointer, expressed122* erroneously as '\0', instead of the empty string "". This was123* apparently an error, introduced in libpng-1.2.20, and png_default_error124* will crash in this case.125*/126if (png_ptr != NULL && png_ptr->error_fn != NULL)127(*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");128129/* If the custom handler doesn't exist, or if it returns,130use the default handler, which will not return. */131png_default_error(png_ptr, "");132}133#endif /* ERROR_TEXT */134135/* Utility to safely appends strings to a buffer. This never errors out so136* error checking is not required in the caller.137*/138size_t139png_safecat(png_charp buffer, size_t bufsize, size_t pos,140png_const_charp string)141{142if (buffer != NULL && pos < bufsize)143{144if (string != NULL)145while (*string != '\0' && pos < bufsize-1)146buffer[pos++] = *string++;147148buffer[pos] = '\0';149}150151return pos;152}153154#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)155/* Utility to dump an unsigned value into a buffer, given a start pointer and156* and end pointer (which should point just *beyond* the end of the buffer!)157* Returns the pointer to the start of the formatted string.158*/159png_charp160png_format_number(png_const_charp start, png_charp end, int format,161png_alloc_size_t number)162{163int count = 0; /* number of digits output */164int mincount = 1; /* minimum number required */165int output = 0; /* digit output (for the fixed point format) */166167*--end = '\0';168169/* This is written so that the loop always runs at least once, even with170* number zero.171*/172while (end > start && (number != 0 || count < mincount))173{174175static const char digits[] = "0123456789ABCDEF";176177switch (format)178{179case PNG_NUMBER_FORMAT_fixed:180/* Needs five digits (the fraction) */181mincount = 5;182if (output != 0 || number % 10 != 0)183{184*--end = digits[number % 10];185output = 1;186}187number /= 10;188break;189190case PNG_NUMBER_FORMAT_02u:191/* Expects at least 2 digits. */192mincount = 2;193/* FALLTHROUGH */194195case PNG_NUMBER_FORMAT_u:196*--end = digits[number % 10];197number /= 10;198break;199200case PNG_NUMBER_FORMAT_02x:201/* This format expects at least two digits */202mincount = 2;203/* FALLTHROUGH */204205case PNG_NUMBER_FORMAT_x:206*--end = digits[number & 0xf];207number >>= 4;208break;209210default: /* an error */211number = 0;212break;213}214215/* Keep track of the number of digits added */216++count;217218/* Float a fixed number here: */219if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))220{221/* End of the fraction, but maybe nothing was output? In that case222* drop the decimal point. If the number is a true zero handle that223* here.224*/225if (output != 0)226*--end = '.';227else if (number == 0) /* and !output */228*--end = '0';229}230}231232return end;233}234#endif235236#ifdef PNG_WARNINGS_SUPPORTED237/* This function is called whenever there is a non-fatal error. This function238* should not be changed. If there is a need to handle warnings differently,239* you should supply a replacement warning function and use240* png_set_error_fn() to replace the warning function at run-time.241*/242void PNGAPI243png_warning(png_const_structrp png_ptr, png_const_charp warning_message)244{245int offset = 0;246if (png_ptr != NULL)247{248#ifdef PNG_ERROR_NUMBERS_SUPPORTED249if ((png_ptr->flags &250(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)251#endif252{253if (*warning_message == PNG_LITERAL_SHARP)254{255for (offset = 1; offset < 15; offset++)256if (warning_message[offset] == ' ')257break;258}259}260}261if (png_ptr != NULL && png_ptr->warning_fn != NULL)262(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),263warning_message + offset);264else265png_default_warning(png_ptr, warning_message + offset);266}267268/* These functions support 'formatted' warning messages with up to269* PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter270* is introduced by @<number>, where 'number' starts at 1. This follows the271* standard established by X/Open for internationalizable error messages.272*/273void274png_warning_parameter(png_warning_parameters p, int number,275png_const_charp string)276{277if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)278(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);279}280281void282png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,283png_alloc_size_t value)284{285char buffer[PNG_NUMBER_BUFFER_SIZE];286png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));287}288289void290png_warning_parameter_signed(png_warning_parameters p, int number, int format,291png_int_32 value)292{293png_alloc_size_t u;294png_charp str;295char buffer[PNG_NUMBER_BUFFER_SIZE];296297/* Avoid overflow by doing the negate in a png_alloc_size_t: */298u = (png_alloc_size_t)value;299if (value < 0)300u = ~u + 1;301302str = PNG_FORMAT_NUMBER(buffer, format, u);303304if (value < 0 && str > buffer)305*--str = '-';306307png_warning_parameter(p, number, str);308}309310void311png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,312png_const_charp message)313{314/* The internal buffer is just 192 bytes - enough for all our messages,315* overflow doesn't happen because this code checks! If someone figures316* out how to send us a message longer than 192 bytes, all that will317* happen is that the message will be truncated appropriately.318*/319size_t i = 0; /* Index in the msg[] buffer: */320char msg[192];321322/* Each iteration through the following loop writes at most one character323* to msg[i++] then returns here to validate that there is still space for324* the trailing '\0'. It may (in the case of a parameter) read more than325* one character from message[]; it must check for '\0' and continue to the326* test if it finds the end of string.327*/328while (i<(sizeof msg)-1 && *message != '\0')329{330/* '@' at end of string is now just printed (previously it was skipped);331* it is an error in the calling code to terminate the string with @.332*/333if (p != NULL && *message == '@' && message[1] != '\0')334{335int parameter_char = *++message; /* Consume the '@' */336static const char valid_parameters[] = "123456789";337int parameter = 0;338339/* Search for the parameter digit, the index in the string is the340* parameter to use.341*/342while (valid_parameters[parameter] != parameter_char &&343valid_parameters[parameter] != '\0')344++parameter;345346/* If the parameter digit is out of range it will just get printed. */347if (parameter < PNG_WARNING_PARAMETER_COUNT)348{349/* Append this parameter */350png_const_charp parm = p[parameter];351png_const_charp pend = p[parameter] + (sizeof p[parameter]);352353/* No need to copy the trailing '\0' here, but there is no guarantee354* that parm[] has been initialized, so there is no guarantee of a355* trailing '\0':356*/357while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)358msg[i++] = *parm++;359360/* Consume the parameter digit too: */361++message;362continue;363}364365/* else not a parameter and there is a character after the @ sign; just366* copy that. This is known not to be '\0' because of the test above.367*/368}369370/* At this point *message can't be '\0', even in the bad parameter case371* above where there is a lone '@' at the end of the message string.372*/373msg[i++] = *message++;374}375376/* i is always less than (sizeof msg), so: */377msg[i] = '\0';378379/* And this is the formatted message. It may be larger than380* PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these381* are not (currently) formatted.382*/383png_warning(png_ptr, msg);384}385#endif /* WARNINGS */386387#ifdef PNG_BENIGN_ERRORS_SUPPORTED388void PNGAPI389png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)390{391if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)392{393# ifdef PNG_READ_SUPPORTED394if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&395png_ptr->chunk_name != 0)396png_chunk_warning(png_ptr, error_message);397else398# endif399png_warning(png_ptr, error_message);400}401402else403{404# ifdef PNG_READ_SUPPORTED405if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&406png_ptr->chunk_name != 0)407png_chunk_error(png_ptr, error_message);408else409# endif410png_error(png_ptr, error_message);411}412413# ifndef PNG_ERROR_TEXT_SUPPORTED414PNG_UNUSED(error_message)415# endif416}417418void /* PRIVATE */419png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)420{421if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)422png_warning(png_ptr, error_message);423else424png_error(png_ptr, error_message);425426# ifndef PNG_ERROR_TEXT_SUPPORTED427PNG_UNUSED(error_message)428# endif429}430431void /* PRIVATE */432png_app_error(png_const_structrp png_ptr, png_const_charp error_message)433{434if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)435png_warning(png_ptr, error_message);436else437png_error(png_ptr, error_message);438439# ifndef PNG_ERROR_TEXT_SUPPORTED440PNG_UNUSED(error_message)441# endif442}443#endif /* BENIGN_ERRORS */444445#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */446#if defined(PNG_WARNINGS_SUPPORTED) || \447(defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))448/* These utilities are used internally to build an error message that relates449* to the current chunk. The chunk name comes from png_ptr->chunk_name,450* which is used to prefix the message. The message is limited in length451* to 63 bytes. The name characters are output as hex digits wrapped in []452* if the character is invalid.453*/454#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))455static const char png_digit[16] = {456'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',457'A', 'B', 'C', 'D', 'E', 'F'458};459460static void /* PRIVATE */461png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp462error_message)463{464png_uint_32 chunk_name = png_ptr->chunk_name;465int iout = 0, ishift = 24;466467while (ishift >= 0)468{469int c = (int)(chunk_name >> ishift) & 0xff;470471ishift -= 8;472if (isnonalpha(c) != 0)473{474buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;475buffer[iout++] = png_digit[(c & 0xf0) >> 4];476buffer[iout++] = png_digit[c & 0x0f];477buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;478}479480else481{482buffer[iout++] = (char)c;483}484}485486if (error_message == NULL)487buffer[iout] = '\0';488489else490{491int iin = 0;492493buffer[iout++] = ':';494buffer[iout++] = ' ';495496while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')497buffer[iout++] = error_message[iin++];498499/* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */500buffer[iout] = '\0';501}502}503#endif /* WARNINGS || ERROR_TEXT */504505#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)506PNG_FUNCTION(void,PNGAPI507png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),508PNG_NORETURN)509{510char msg[18+PNG_MAX_ERROR_TEXT];511if (png_ptr == NULL)512png_error(png_ptr, error_message);513514else515{516png_format_buffer(png_ptr, msg, error_message);517png_error(png_ptr, msg);518}519}520#endif /* READ && ERROR_TEXT */521522#ifdef PNG_WARNINGS_SUPPORTED523void PNGAPI524png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)525{526char msg[18+PNG_MAX_ERROR_TEXT];527if (png_ptr == NULL)528png_warning(png_ptr, warning_message);529530else531{532png_format_buffer(png_ptr, msg, warning_message);533png_warning(png_ptr, msg);534}535}536#endif /* WARNINGS */537538#ifdef PNG_READ_SUPPORTED539#ifdef PNG_BENIGN_ERRORS_SUPPORTED540void PNGAPI541png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp542error_message)543{544if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)545png_chunk_warning(png_ptr, error_message);546547else548png_chunk_error(png_ptr, error_message);549550# ifndef PNG_ERROR_TEXT_SUPPORTED551PNG_UNUSED(error_message)552# endif553}554#endif555#endif /* READ */556557void /* PRIVATE */558png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)559{560# ifndef PNG_WARNINGS_SUPPORTED561PNG_UNUSED(message)562# endif563564/* This is always supported, but for just read or just write it565* unconditionally does the right thing.566*/567# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)568if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)569# endif570571# ifdef PNG_READ_SUPPORTED572{573if (error < PNG_CHUNK_ERROR)574png_chunk_warning(png_ptr, message);575576else577png_chunk_benign_error(png_ptr, message);578}579# endif580581# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)582else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)583# endif584585# ifdef PNG_WRITE_SUPPORTED586{587if (error < PNG_CHUNK_WRITE_ERROR)588png_app_warning(png_ptr, message);589590else591png_app_error(png_ptr, message);592}593# endif594}595596#ifdef PNG_ERROR_TEXT_SUPPORTED597#ifdef PNG_FLOATING_POINT_SUPPORTED598PNG_FUNCTION(void,599png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)600{601# define fixed_message "fixed point overflow in "602# define fixed_message_ln ((sizeof fixed_message)-1)603unsigned int iin;604char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];605memcpy(msg, fixed_message, fixed_message_ln);606iin = 0;607if (name != NULL)608while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)609{610msg[fixed_message_ln + iin] = name[iin];611++iin;612}613msg[fixed_message_ln + iin] = 0;614png_error(png_ptr, msg);615}616#endif617#endif618619#ifdef PNG_SETJMP_SUPPORTED620/* This API only exists if ANSI-C style error handling is used,621* otherwise it is necessary for png_default_error to be overridden.622*/623jmp_buf* PNGAPI624png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,625size_t jmp_buf_size)626{627/* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value628* and it must not change after that. Libpng doesn't care how big the629* buffer is, just that it doesn't change.630*631* If the buffer size is no *larger* than the size of jmp_buf when libpng is632* compiled a built in jmp_buf is returned; this preserves the pre-1.6.0633* semantics that this call will not fail. If the size is larger, however,634* the buffer is allocated and this may fail, causing the function to return635* NULL.636*/637if (png_ptr == NULL)638return NULL;639640if (png_ptr->jmp_buf_ptr == NULL)641{642png_ptr->jmp_buf_size = 0; /* not allocated */643644if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))645png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;646647else648{649png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,650png_malloc_warn(png_ptr, jmp_buf_size));651652if (png_ptr->jmp_buf_ptr == NULL)653return NULL; /* new NULL return on OOM */654655png_ptr->jmp_buf_size = jmp_buf_size;656}657}658659else /* Already allocated: check the size */660{661size_t size = png_ptr->jmp_buf_size;662663if (size == 0)664{665size = (sizeof png_ptr->jmp_buf_local);666if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)667{668/* This is an internal error in libpng: somehow we have been left669* with a stack allocated jmp_buf when the application regained670* control. It's always possible to fix this up, but for the moment671* this is a png_error because that makes it easy to detect.672*/673png_error(png_ptr, "Libpng jmp_buf still allocated");674/* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */675}676}677678if (size != jmp_buf_size)679{680png_warning(png_ptr, "Application jmp_buf size changed");681return NULL; /* caller will probably crash: no choice here */682}683}684685/* Finally fill in the function, now we have a satisfactory buffer. It is686* valid to change the function on every call.687*/688png_ptr->longjmp_fn = longjmp_fn;689return png_ptr->jmp_buf_ptr;690}691692void /* PRIVATE */693png_free_jmpbuf(png_structrp png_ptr)694{695if (png_ptr != NULL)696{697jmp_buf *jb = png_ptr->jmp_buf_ptr;698699/* A size of 0 is used to indicate a local, stack, allocation of the700* pointer; used here and in png.c701*/702if (jb != NULL && png_ptr->jmp_buf_size > 0)703{704705/* This stuff is so that a failure to free the error control structure706* does not leave libpng in a state with no valid error handling: the707* free always succeeds, if there is an error it gets ignored.708*/709if (jb != &png_ptr->jmp_buf_local)710{711/* Make an internal, libpng, jmp_buf to return here */712jmp_buf free_jmp_buf;713714if (!setjmp(free_jmp_buf))715{716png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */717png_ptr->jmp_buf_size = 0; /* stack allocation */718png_ptr->longjmp_fn = longjmp;719png_free(png_ptr, jb); /* Return to setjmp on error */720}721}722}723724/* *Always* cancel everything out: */725png_ptr->jmp_buf_size = 0;726png_ptr->jmp_buf_ptr = NULL;727png_ptr->longjmp_fn = 0;728}729}730#endif731732/* This is the default error handling function. Note that replacements for733* this function MUST NOT RETURN, or the program will likely crash. This734* function is used by default, or if the program supplies NULL for the735* error function pointer in png_set_error_fn().736*/737static PNG_FUNCTION(void /* PRIVATE */,738png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),739PNG_NORETURN)740{741#ifdef PNG_CONSOLE_IO_SUPPORTED742#ifdef PNG_ERROR_NUMBERS_SUPPORTED743/* Check on NULL only added in 1.5.4 */744if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)745{746/* Strip "#nnnn " from beginning of error message. */747int offset;748char error_number[16];749for (offset = 0; offset<15; offset++)750{751error_number[offset] = error_message[offset + 1];752if (error_message[offset] == ' ')753break;754}755756if ((offset > 1) && (offset < 15))757{758error_number[offset - 1] = '\0';759fprintf(stderr, "libpng error no. %s: %s",760error_number, error_message + offset + 1);761fprintf(stderr, PNG_STRING_NEWLINE);762}763764else765{766fprintf(stderr, "libpng error: %s, offset=%d",767error_message, offset);768fprintf(stderr, PNG_STRING_NEWLINE);769}770}771else772#endif773{774fprintf(stderr, "libpng error: %s", error_message ? error_message :775"undefined");776fprintf(stderr, PNG_STRING_NEWLINE);777}778#else779PNG_UNUSED(error_message) /* Make compiler happy */780#endif781png_longjmp(png_ptr, 1);782}783784PNG_FUNCTION(void,PNGAPI785png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)786{787#ifdef PNG_SETJMP_SUPPORTED788if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&789png_ptr->jmp_buf_ptr != NULL)790png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);791#else792PNG_UNUSED(png_ptr)793PNG_UNUSED(val)794#endif795796/* If control reaches this point, png_longjmp() must not return. The only797* choice is to terminate the whole process (or maybe the thread); to do798* this the ANSI-C abort() function is used unless a different method is799* implemented by overriding the default configuration setting for800* PNG_ABORT().801*/802PNG_ABORT();803}804805#ifdef PNG_WARNINGS_SUPPORTED806/* This function is called when there is a warning, but the library thinks807* it can continue anyway. Replacement functions don't have to do anything808* here if you don't want them to. In the default configuration, png_ptr is809* not used, but it is passed in case it may be useful.810*/811static void /* PRIVATE */812png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)813{814#ifdef PNG_CONSOLE_IO_SUPPORTED815# ifdef PNG_ERROR_NUMBERS_SUPPORTED816if (*warning_message == PNG_LITERAL_SHARP)817{818int offset;819char warning_number[16];820for (offset = 0; offset < 15; offset++)821{822warning_number[offset] = warning_message[offset + 1];823if (warning_message[offset] == ' ')824break;825}826827if ((offset > 1) && (offset < 15))828{829warning_number[offset + 1] = '\0';830fprintf(stderr, "libpng warning no. %s: %s",831warning_number, warning_message + offset);832fprintf(stderr, PNG_STRING_NEWLINE);833}834835else836{837fprintf(stderr, "libpng warning: %s",838warning_message);839fprintf(stderr, PNG_STRING_NEWLINE);840}841}842else843# endif844845{846fprintf(stderr, "libpng warning: %s", warning_message);847fprintf(stderr, PNG_STRING_NEWLINE);848}849#else850PNG_UNUSED(warning_message) /* Make compiler happy */851#endif852PNG_UNUSED(png_ptr) /* Make compiler happy */853}854#endif /* WARNINGS */855856/* This function is called when the application wants to use another method857* of handling errors and warnings. Note that the error function MUST NOT858* return to the calling routine or serious problems will occur. The return859* method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)860*/861void PNGAPI862png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,863png_error_ptr error_fn, png_error_ptr warning_fn)864{865if (png_ptr == NULL)866return;867868png_ptr->error_ptr = error_ptr;869png_ptr->error_fn = error_fn;870#ifdef PNG_WARNINGS_SUPPORTED871png_ptr->warning_fn = warning_fn;872#else873PNG_UNUSED(warning_fn)874#endif875}876877878/* This function returns a pointer to the error_ptr associated with the user879* functions. The application should free any memory associated with this880* pointer before png_write_destroy and png_read_destroy are called.881*/882png_voidp PNGAPI883png_get_error_ptr(png_const_structrp png_ptr)884{885if (png_ptr == NULL)886return NULL;887888return ((png_voidp)png_ptr->error_ptr);889}890891892#ifdef PNG_ERROR_NUMBERS_SUPPORTED893void PNGAPI894png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)895{896if (png_ptr != NULL)897{898png_ptr->flags &=899((~(PNG_FLAG_STRIP_ERROR_NUMBERS |900PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);901}902}903#endif904905#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\906defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)907/* Currently the above both depend on SETJMP_SUPPORTED, however it would be908* possible to implement without setjmp support just so long as there is some909* way to handle the error return here:910*/911PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI912png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),913PNG_NORETURN)914{915png_const_structrp png_ptr = png_nonconst_ptr;916png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);917918/* An error is always logged here, overwriting anything (typically a warning)919* that is already there:920*/921if (image != NULL)922{923png_safecat(image->message, (sizeof image->message), 0, error_message);924image->warning_or_error |= PNG_IMAGE_ERROR;925926/* Retrieve the jmp_buf from within the png_control, making this work for927* C++ compilation too is pretty tricky: C++ wants a pointer to the first928* element of a jmp_buf, but C doesn't tell us the type of that.929*/930if (image->opaque != NULL && image->opaque->error_buf != NULL)931longjmp(png_control_jmp_buf(image->opaque), 1);932933/* Missing longjmp buffer, the following is to help debugging: */934{935size_t pos = png_safecat(image->message, (sizeof image->message), 0,936"bad longjmp: ");937png_safecat(image->message, (sizeof image->message), pos,938error_message);939}940}941942/* Here on an internal programming error. */943abort();944}945946#ifdef PNG_WARNINGS_SUPPORTED947void /* PRIVATE */ PNGCBAPI948png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)949{950png_const_structrp png_ptr = png_nonconst_ptr;951png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);952953/* A warning is only logged if there is no prior warning or error. */954if (image->warning_or_error == 0)955{956png_safecat(image->message, (sizeof image->message), 0, warning_message);957image->warning_or_error |= PNG_IMAGE_WARNING;958}959}960#endif961962int /* PRIVATE */963png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)964{965volatile png_imagep image = image_in;966volatile int result;967volatile png_voidp saved_error_buf;968jmp_buf safe_jmpbuf;969970/* Safely execute function(arg) with png_error returning to this function. */971saved_error_buf = image->opaque->error_buf;972result = setjmp(safe_jmpbuf) == 0;973974if (result != 0)975{976977image->opaque->error_buf = safe_jmpbuf;978result = function(arg);979}980981image->opaque->error_buf = saved_error_buf;982983/* And do the cleanup prior to any failure return. */984if (result == 0)985png_image_free(image);986987return result;988}989#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */990#endif /* READ || WRITE */991992993