1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-26 00:37:43 +03:00

encoding: Report malloc failures

Introduce new API functions that return a separate error code if a
memory allocation fails.

- xmlOpenCharEncodingHandler
- xmlLookupCharEncodingHandler

Fix a few places where malloc failures weren't reported.
This commit is contained in:
Nick Wellnhofer
2023-12-10 14:56:21 +01:00
parent da996c8d0f
commit bd5ad0308d
4 changed files with 416 additions and 249 deletions

View File

@@ -71,57 +71,6 @@ static int xmlCharEncodingAliasesMax = 0;
static int xmlLittleEndian = 1; static int xmlLittleEndian = 1;
#ifdef LIBXML_ICU_ENABLED
static uconv_t*
openIcuConverter(const char* name, int toUnicode)
{
UErrorCode status = U_ZERO_ERROR;
uconv_t *conv = (uconv_t *) xmlMalloc(sizeof(uconv_t));
if (conv == NULL)
return NULL;
conv->pivot_source = conv->pivot_buf;
conv->pivot_target = conv->pivot_buf;
conv->uconv = ucnv_open(name, &status);
if (U_FAILURE(status))
goto error;
status = U_ZERO_ERROR;
if (toUnicode) {
ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
NULL, NULL, NULL, &status);
}
else {
ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
NULL, NULL, NULL, &status);
}
if (U_FAILURE(status))
goto error;
status = U_ZERO_ERROR;
conv->utf8 = ucnv_open("UTF-8", &status);
if (U_SUCCESS(status))
return conv;
error:
if (conv->uconv)
ucnv_close(conv->uconv);
xmlFree(conv);
return NULL;
}
static void
closeIcuConverter(uconv_t *conv)
{
if (conv != NULL) {
ucnv_close(conv->uconv);
ucnv_close(conv->utf8);
xmlFree(conv);
}
}
#endif /* LIBXML_ICU_ENABLED */
/************************************************************************ /************************************************************************
* * * *
* Conversions To/From UTF8 encoding * * Conversions To/From UTF8 encoding *
@@ -1374,6 +1323,7 @@ static const xmlCharEncodingHandler defaultHandlers[] = {
static const xmlCharEncodingHandler *xmlUTF16LEHandler = &defaultHandlers[1]; static const xmlCharEncodingHandler *xmlUTF16LEHandler = &defaultHandlers[1];
static const xmlCharEncodingHandler *xmlUTF16BEHandler = &defaultHandlers[2]; static const xmlCharEncodingHandler *xmlUTF16BEHandler = &defaultHandlers[2];
static const xmlCharEncodingHandler *xmlLatin1Handler = &defaultHandlers[4];
/* the size should be growable, but it's not a big deal ... */ /* the size should be growable, but it's not a big deal ... */
#define MAX_ENCODING_HANDLERS 50 #define MAX_ENCODING_HANDLERS 50
@@ -1535,162 +1485,428 @@ free_handler:
} }
} }
#ifdef LIBXML_ICONV_ENABLED
static int
xmlCreateIconvHandler(const char *name, xmlCharEncodingHandler **out) {
xmlCharEncodingHandlerPtr enc = NULL;
iconv_t icv_in = (iconv_t) -1;
iconv_t icv_out = (iconv_t) -1;
int ret;
*out = NULL;
icv_in = iconv_open("UTF-8", name);
if (icv_in == (iconv_t) -1) {
if (errno == EINVAL)
ret = XML_ERR_UNSUPPORTED_ENCODING;
else if (errno == ENOMEM)
ret = XML_ERR_NO_MEMORY;
else
ret = XML_ERR_SYSTEM;
goto error;
}
icv_out = iconv_open(name, "UTF-8");
if (icv_out == (iconv_t) -1) {
if (errno == EINVAL)
ret = XML_ERR_UNSUPPORTED_ENCODING;
else if (errno == ENOMEM)
ret = XML_ERR_NO_MEMORY;
else
ret = XML_ERR_SYSTEM;
goto error;
}
enc = xmlMalloc(sizeof(*enc));
if (enc == NULL) {
ret = XML_ERR_NO_MEMORY;
goto error;
}
memset(enc, 0, sizeof(*enc));
enc->name = xmlMemStrdup(name);
if (enc->name == NULL) {
ret = XML_ERR_NO_MEMORY;
goto error;
}
enc->iconv_in = icv_in;
enc->iconv_out = icv_out;
*out = enc;
return(0);
error:
if (enc != NULL)
xmlFree(enc);
if (icv_in != (iconv_t) -1)
iconv_close(icv_in);
if (icv_out != (iconv_t) -1)
iconv_close(icv_out);
return(ret);
}
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
static int
openIcuConverter(const char* name, int toUnicode, uconv_t **out)
{
UErrorCode status;
uconv_t *conv;
*out = NULL;
conv = (uconv_t *) xmlMalloc(sizeof(uconv_t));
if (conv == NULL)
return(XML_ERR_NO_MEMORY);
conv->pivot_source = conv->pivot_buf;
conv->pivot_target = conv->pivot_buf;
status = U_ZERO_ERROR;
conv->uconv = ucnv_open(name, &status);
if (U_FAILURE(status))
goto error;
status = U_ZERO_ERROR;
if (toUnicode) {
ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
NULL, NULL, NULL, &status);
}
else {
ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
NULL, NULL, NULL, &status);
}
if (U_FAILURE(status))
goto error;
status = U_ZERO_ERROR;
conv->utf8 = ucnv_open("UTF-8", &status);
if (U_FAILURE(status))
goto error;
*out = conv;
return(0);
error:
if (conv->uconv)
ucnv_close(conv->uconv);
xmlFree(conv);
if (status == U_FILE_ACCESS_ERROR)
return(XML_ERR_UNSUPPORTED_ENCODING);
if (status == U_MEMORY_ALLOCATION_ERROR)
return(XML_ERR_NO_MEMORY);
return(XML_ERR_SYSTEM);
}
static void
closeIcuConverter(uconv_t *conv)
{
if (conv == NULL)
return;
ucnv_close(conv->uconv);
ucnv_close(conv->utf8);
xmlFree(conv);
}
static int
xmlCreateUconvHandler(const char *name, xmlCharEncodingHandler **out) {
xmlCharEncodingHandlerPtr enc = NULL;
uconv_t *ucv_in = NULL;
uconv_t *ucv_out = NULL;
int ret;
ret = openIcuConverter(name, 1, &ucv_in);
if (ret != 0)
goto error;
ret = openIcuConverter(name, 0, &ucv_out);
if (ret != 0)
goto error;
enc = (xmlCharEncodingHandlerPtr)
xmlMalloc(sizeof(xmlCharEncodingHandler));
if (enc == NULL) {
ret = XML_ERR_NO_MEMORY;
goto error;
}
memset(enc, 0, sizeof(xmlCharEncodingHandler));
enc->name = xmlMemStrdup(name);
if (enc->name == NULL) {
ret = XML_ERR_NO_MEMORY;
goto error;
}
enc->input = NULL;
enc->output = NULL;
enc->uconv_in = ucv_in;
enc->uconv_out = ucv_out;
*out = enc;
return(0);
error:
if (enc != NULL)
xmlFree(enc);
if (ucv_in != NULL)
closeIcuConverter(ucv_in);
if (ucv_out != NULL)
closeIcuConverter(ucv_out);
return(ret);
}
#endif /* LIBXML_ICU_ENABLED */
/** /**
* xmlGetCharEncodingHandler: * xmlFindExtraHandler:
* @enc: an xmlCharEncoding value. * @name: a string describing the char encoding.
* @out: pointer to resulting handler
* *
* Search in the registered set the handler able to read/write that encoding. * Search the non-default handlers for an exact match.
* *
* Returns the handler or NULL if not found * Returns 0 on success, 1 if no handler was found, -1 if a memory
* allocation failed.
*/ */
xmlCharEncodingHandlerPtr static int
xmlGetCharEncodingHandler(xmlCharEncoding enc) { xmlFindExtraHandler(const char *name, xmlCharEncodingHandler **out) {
xmlCharEncodingHandlerPtr handler; int ret;
int i;
(void) ret;
if (handlers != NULL) {
for (i = 0; i < nbCharEncodingHandler; i++) {
if (!xmlStrcasecmp((const xmlChar *) name,
(const xmlChar *) handlers[i]->name)) {
*out = handlers[i];
return(0);
}
}
}
#ifdef LIBXML_ICONV_ENABLED
ret = xmlCreateIconvHandler(name, out);
if (*out != NULL)
return(0);
if (ret != XML_ERR_UNSUPPORTED_ENCODING)
return(ret);
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
ret = xmlCreateUconvHandler(name, out);
if (*out != NULL)
return(0);
if (ret != XML_ERR_UNSUPPORTED_ENCODING)
return(ret);
#endif /* LIBXML_ICU_ENABLED */
return(XML_ERR_UNSUPPORTED_ENCODING);
}
/**
* xmlFindHandler:
* @name: a string describing the char encoding.
* @out: pointer to resulting handler
*
* Search all handlers for an exact match.
*
* Returns 0 on success, 1 if no handler was found, -1 if a memory
* allocation failed.
*/
static int
xmlFindHandler(const char *name, xmlCharEncodingHandler **out) {
int i;
/*
* Check for default handlers
*/
for (i = 0; i < (int) NUM_DEFAULT_HANDLERS; i++) {
if (xmlStrcasecmp((const xmlChar *) name,
(const xmlChar *) defaultHandlers[i].name) == 0) {
*out = (xmlCharEncodingHandler *) &defaultHandlers[i];
return(0);
}
}
/*
* Check for other handlers
*/
return(xmlFindExtraHandler(name, out));
}
/**
* xmlLookupCharEncodingHandler:
* @enc: an xmlCharEncoding value.
* @out: pointer to result
*
* Find or create a handler matching the encoding. If no default or
* registered handler could be found, try to create a handler using
* iconv or ICU if supported.
*
* The handler must be closed with xmlCharEncCloseFunc.
*
* Available since 2.13.0.
*
* Returns an xmlParserErrors error code.
*/
int
xmlLookupCharEncodingHandler(xmlCharEncoding enc,
xmlCharEncodingHandler **out) {
const char *name = NULL;
static const char *const ebcdicNames[] = {
"EBCDIC", "ebcdic", "EBCDIC-US", "IBM-037"
};
static const char *const ucs4Names[] = {
"ISO-10646-UCS-4", "UCS-4", "UCS4"
};
static const char *const ucs2Names[] = {
"ISO-10646-UCS-2", "UCS-2", "UCS2"
};
static const char *const shiftJisNames[] = {
"SHIFT-JIS", "SHIFT_JIS", "Shift_JIS",
};
const char *const *names = NULL;
int numNames = 0;
int ret;
int i;
if (out == NULL)
return(XML_ERR_ARGUMENT);
*out = NULL;
switch (enc) { switch (enc) {
case XML_CHAR_ENCODING_ERROR: case XML_CHAR_ENCODING_ERROR:
return(NULL); return(XML_ERR_UNSUPPORTED_ENCODING);
case XML_CHAR_ENCODING_NONE: case XML_CHAR_ENCODING_NONE:
return(NULL); return(0);
case XML_CHAR_ENCODING_UTF8: case XML_CHAR_ENCODING_UTF8:
return(NULL); return(0);
case XML_CHAR_ENCODING_UTF16LE: case XML_CHAR_ENCODING_UTF16LE:
return((xmlCharEncodingHandlerPtr) xmlUTF16LEHandler); *out = (xmlCharEncodingHandler *) xmlUTF16LEHandler;
return(0);
case XML_CHAR_ENCODING_UTF16BE: case XML_CHAR_ENCODING_UTF16BE:
return((xmlCharEncodingHandlerPtr) xmlUTF16BEHandler); *out = (xmlCharEncodingHandler *) xmlUTF16BEHandler;
return(0);
case XML_CHAR_ENCODING_EBCDIC: case XML_CHAR_ENCODING_EBCDIC:
handler = xmlFindCharEncodingHandler("EBCDIC"); names = ebcdicNames;
if (handler != NULL) return(handler); numNames = sizeof(ebcdicNames) / sizeof(ebcdicNames[0]);
handler = xmlFindCharEncodingHandler("ebcdic");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("EBCDIC-US");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("IBM-037");
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_UCS4BE: case XML_CHAR_ENCODING_UCS4BE:
handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("UCS-4");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("UCS4");
if (handler != NULL) return(handler);
break;
case XML_CHAR_ENCODING_UCS4LE: case XML_CHAR_ENCODING_UCS4LE:
handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4"); names = ucs4Names;
if (handler != NULL) return(handler); numNames = sizeof(ucs4Names) / sizeof(ucs4Names[0]);
handler = xmlFindCharEncodingHandler("UCS-4");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("UCS4");
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_UCS4_2143: case XML_CHAR_ENCODING_UCS4_2143:
break; break;
case XML_CHAR_ENCODING_UCS4_3412: case XML_CHAR_ENCODING_UCS4_3412:
break; break;
case XML_CHAR_ENCODING_UCS2: case XML_CHAR_ENCODING_UCS2:
handler = xmlFindCharEncodingHandler("ISO-10646-UCS-2"); names = ucs2Names;
if (handler != NULL) return(handler); numNames = sizeof(ucs2Names) / sizeof(ucs2Names[0]);
handler = xmlFindCharEncodingHandler("UCS-2");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("UCS2");
if (handler != NULL) return(handler);
break; break;
/*
* We used to keep ISO Latin encodings native in the
* generated data. This led to so many problems that
* this has been removed. One can still change this
* back by registering no-ops encoders for those
*/
case XML_CHAR_ENCODING_8859_1: case XML_CHAR_ENCODING_8859_1:
handler = xmlFindCharEncodingHandler("ISO-8859-1"); *out = (xmlCharEncodingHandler *) xmlLatin1Handler;
if (handler != NULL) return(handler); return(0);
break;
case XML_CHAR_ENCODING_8859_2: case XML_CHAR_ENCODING_8859_2:
handler = xmlFindCharEncodingHandler("ISO-8859-2"); name = "ISO-8859-2";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_3: case XML_CHAR_ENCODING_8859_3:
handler = xmlFindCharEncodingHandler("ISO-8859-3"); name = "ISO-8859-3";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_4: case XML_CHAR_ENCODING_8859_4:
handler = xmlFindCharEncodingHandler("ISO-8859-4"); name = "ISO-8859-4";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_5: case XML_CHAR_ENCODING_8859_5:
handler = xmlFindCharEncodingHandler("ISO-8859-5"); name = "ISO-8859-5";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_6: case XML_CHAR_ENCODING_8859_6:
handler = xmlFindCharEncodingHandler("ISO-8859-6"); name = "ISO-8859-6";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_7: case XML_CHAR_ENCODING_8859_7:
handler = xmlFindCharEncodingHandler("ISO-8859-7"); name = "ISO-8859-7";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_8: case XML_CHAR_ENCODING_8859_8:
handler = xmlFindCharEncodingHandler("ISO-8859-8"); name = "ISO-8859-8";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_8859_9: case XML_CHAR_ENCODING_8859_9:
handler = xmlFindCharEncodingHandler("ISO-8859-9"); name = "ISO-8859-9";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_2022_JP: case XML_CHAR_ENCODING_2022_JP:
handler = xmlFindCharEncodingHandler("ISO-2022-JP"); name = "ISO-2022-JP";
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_SHIFT_JIS: case XML_CHAR_ENCODING_SHIFT_JIS:
handler = xmlFindCharEncodingHandler("SHIFT-JIS"); names = shiftJisNames;
if (handler != NULL) return(handler); numNames = sizeof(shiftJisNames) / sizeof(shiftJisNames[0]);
handler = xmlFindCharEncodingHandler("SHIFT_JIS");
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("Shift_JIS");
if (handler != NULL) return(handler);
break; break;
case XML_CHAR_ENCODING_EUC_JP: case XML_CHAR_ENCODING_EUC_JP:
handler = xmlFindCharEncodingHandler("EUC-JP"); name = "EUC-JP";
if (handler != NULL) return(handler);
break; break;
default: default:
break; break;
} }
return(NULL); if (name != NULL)
return(xmlFindExtraHandler(name, out));
if (names != NULL) {
for (i = 0; i < numNames; i++) {
ret = xmlFindExtraHandler(names[i], out);
if (*out != NULL)
return(0);
if (ret != XML_ERR_UNSUPPORTED_ENCODING)
return(ret);
}
}
return(XML_ERR_UNSUPPORTED_ENCODING);
} }
/** /**
* xmlFindCharEncodingHandler: * xmlGetCharEncodingHandler:
* @name: a string describing the char encoding. * @enc: an xmlCharEncoding value.
* *
* Search in the registered set the handler able to read/write that encoding * DEPRECATED: Use xmlLookupCharEncodingHandler which has better error
* or create a new one. * reporting.
* *
* Returns the handler or NULL if not found * Returns the handler or NULL if no handler was found or an error
* occurred.
*/ */
xmlCharEncodingHandlerPtr xmlCharEncodingHandlerPtr
xmlFindCharEncodingHandler(const char *name) { xmlGetCharEncodingHandler(xmlCharEncoding enc) {
xmlCharEncodingHandler *ret;
xmlLookupCharEncodingHandler(enc, &ret);
return(ret);
}
/**
* xmlOpenCharEncodingHandler:
* @name: a string describing the char encoding.
* @out: pointer to result
*
* Find or create a handler matching the encoding. If no default or
* registered handler could be found, try to create a handler using
* iconv or ICU if supported.
*
* The handler must be closed with xmlCharEncCloseFunc.
*
* Available since 2.13.0.
*
* Returns an xmlParserErrors error code.
*/
int
xmlOpenCharEncodingHandler(const char *name, xmlCharEncodingHandler **out) {
const char *nalias; const char *nalias;
const char *norig; const char *norig;
xmlCharEncoding alias; xmlCharEncoding enc;
#ifdef LIBXML_ICONV_ENABLED int ret;
xmlCharEncodingHandlerPtr enc;
iconv_t icv_in, icv_out;
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
xmlCharEncodingHandlerPtr encu;
uconv_t *ucv_in, *ucv_out;
#endif /* LIBXML_ICU_ENABLED */
char upper[100];
int i;
if (name == NULL) return(NULL); if (out == NULL)
if (name[0] == 0) return(NULL); return(XML_ERR_ARGUMENT);
*out = NULL;
if (name == NULL)
return(XML_ERR_ARGUMENT);
/* /*
* Do the alias resolution * Do the alias resolution
@@ -1700,111 +1916,35 @@ xmlFindCharEncodingHandler(const char *name) {
if (nalias != NULL) if (nalias != NULL)
name = nalias; name = nalias;
/* ret = xmlFindHandler(name, out);
* Check first for directly registered encoding names if (*out != NULL)
*/ return(0);
for (i = 0;i < 99;i++) { if (ret != XML_ERR_UNSUPPORTED_ENCODING)
upper[i] = (char) toupper((unsigned char) name[i]); return(ret);
if (upper[i] == 0) break;
}
upper[i] = 0;
for (i = 0; i < (int) NUM_DEFAULT_HANDLERS; i++) {
if (strcmp(upper, defaultHandlers[i].name) == 0)
return((xmlCharEncodingHandlerPtr) &defaultHandlers[i]);
}
if (handlers != NULL) {
for (i = 0;i < nbCharEncodingHandler; i++) {
if (!strcmp(upper, handlers[i]->name)) {
return(handlers[i]);
}
}
}
#ifdef LIBXML_ICONV_ENABLED
/* check whether iconv can handle this */
icv_in = iconv_open("UTF-8", name);
icv_out = iconv_open(name, "UTF-8");
if (icv_in == (iconv_t) -1) {
icv_in = iconv_open("UTF-8", upper);
}
if (icv_out == (iconv_t) -1) {
icv_out = iconv_open(upper, "UTF-8");
}
if ((icv_in != (iconv_t) -1) && (icv_out != (iconv_t) -1)) {
enc = (xmlCharEncodingHandlerPtr)
xmlMalloc(sizeof(xmlCharEncodingHandler));
if (enc == NULL) {
iconv_close(icv_in);
iconv_close(icv_out);
return(NULL);
}
memset(enc, 0, sizeof(xmlCharEncodingHandler));
enc->name = xmlMemStrdup(name);
if (enc->name == NULL) {
xmlFree(enc);
iconv_close(icv_in);
iconv_close(icv_out);
return(NULL);
}
enc->input = NULL;
enc->output = NULL;
enc->iconv_in = icv_in;
enc->iconv_out = icv_out;
return enc;
} else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
if (icv_in != (iconv_t) -1)
iconv_close(icv_in);
else
iconv_close(icv_out);
}
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
/* check whether icu can handle this */
ucv_in = openIcuConverter(name, 1);
ucv_out = openIcuConverter(name, 0);
if (ucv_in != NULL && ucv_out != NULL) {
encu = (xmlCharEncodingHandlerPtr)
xmlMalloc(sizeof(xmlCharEncodingHandler));
if (encu == NULL) {
closeIcuConverter(ucv_in);
closeIcuConverter(ucv_out);
return(NULL);
}
memset(encu, 0, sizeof(xmlCharEncodingHandler));
encu->name = xmlMemStrdup(name);
if (encu->name == NULL) {
xmlFree(encu);
closeIcuConverter(ucv_in);
closeIcuConverter(ucv_out);
return(NULL);
}
encu->input = NULL;
encu->output = NULL;
encu->uconv_in = ucv_in;
encu->uconv_out = ucv_out;
return encu;
} else if (ucv_in != NULL || ucv_out != NULL) {
closeIcuConverter(ucv_in);
closeIcuConverter(ucv_out);
}
#endif /* LIBXML_ICU_ENABLED */
/* /*
* Fallback using the canonical names * Fallback using the canonical names
*/ */
alias = xmlParseCharEncoding(norig); enc = xmlParseCharEncoding(norig);
if (alias != XML_CHAR_ENCODING_ERROR) { return(xmlLookupCharEncodingHandler(enc, out));
const char* canon;
canon = xmlGetCharEncodingName(alias);
if ((canon != NULL) && (strcmp(name, canon))) {
return(xmlFindCharEncodingHandler(canon));
}
} }
/* If "none of the above", give up */ /**
return(NULL); * xmlFindCharEncodingHandler:
* @name: a string describing the char encoding.
*
* DEPRECATED: Use xmlOpenCharEncodingHandler which has better error
* reporting.
*
* Returns the handler or NULL if no handler was found or an error
* occurred.
*/
xmlCharEncodingHandlerPtr
xmlFindCharEncodingHandler(const char *name) {
xmlCharEncodingHandler *ret;
xmlOpenCharEncodingHandler(name, &ret);
return(ret);
} }
/************************************************************************ /************************************************************************
@@ -2169,7 +2309,8 @@ xmlCharEncInput(xmlParserInputBufferPtr input)
else else
input->rawconsumed += c_in; input->rawconsumed += c_in;
if ((c_out == 0) && (ret != 0)) { if (((ret != 0) && (c_out == 0)) ||
(ret == XML_ENC_ERR_MEMORY)) {
if (input->error == 0) if (input->error == 0)
input->error = xmlEncConvertError(ret); input->error = xmlEncConvertError(ret);
return(ret); return(ret);
@@ -2277,7 +2418,10 @@ retry:
if (toconv > 64 * 1024) if (toconv > 64 * 1024)
toconv = 64 * 1024; toconv = 64 * 1024;
if (toconv * 4 >= written) { if (toconv * 4 >= written) {
xmlBufGrow(out, toconv * 4); if (xmlBufGrow(out, toconv * 4) < 0) {
ret = XML_ENC_ERR_MEMORY;
goto error;
}
written = xmlBufAvail(out); written = xmlBufAvail(out);
} }
if (written > 256 * 1024) if (written > 256 * 1024)
@@ -2331,7 +2475,8 @@ retry:
} }
error: error:
if ((writtentot <= 0) && (ret != 0)) { if (((writtentot <= 0) && (ret != 0)) ||
(ret == XML_ENC_ERR_MEMORY)) {
if (output->error == 0) if (output->error == 0)
output->error = xmlEncConvertError(ret); output->error = xmlEncConvertError(ret);
return(ret); return(ret);

View File

@@ -162,6 +162,12 @@ XMLPUBFUN void
xmlCleanupCharEncodingHandlers (void); xmlCleanupCharEncodingHandlers (void);
XMLPUBFUN void XMLPUBFUN void
xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler); xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler);
XMLPUBFUN int
xmlLookupCharEncodingHandler (xmlCharEncoding enc,
xmlCharEncodingHandlerPtr *out);
XMLPUBFUN int
xmlOpenCharEncodingHandler (const char *name,
xmlCharEncodingHandlerPtr *out);
XMLPUBFUN xmlCharEncodingHandlerPtr XMLPUBFUN xmlCharEncodingHandlerPtr
xmlGetCharEncodingHandler (xmlCharEncoding enc); xmlGetCharEncodingHandler (xmlCharEncoding enc);
XMLPUBFUN xmlCharEncodingHandlerPtr XMLPUBFUN xmlCharEncodingHandlerPtr

View File

@@ -211,6 +211,10 @@ typedef enum {
XML_ERR_USER_STOP, /* 111 */ XML_ERR_USER_STOP, /* 111 */
XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */ XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */
XML_WAR_ENCODING_MISMATCH, /* 113 */ XML_WAR_ENCODING_MISMATCH, /* 113 */
XML_ERR_RESOURCE_LIMIT, /* 114 */
XML_ERR_ARGUMENT, /* 115 */
XML_ERR_SYSTEM, /* 116 */
XML_ERR_REDECL_PREDEF_ENTITY, /* 117 */
XML_NS_ERR_XML_NAMESPACE = 200, XML_NS_ERR_XML_NAMESPACE = 200,
XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */ XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
XML_NS_ERR_QNAME, /* 202 */ XML_NS_ERR_QNAME, /* 202 */

View File

@@ -373,6 +373,18 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
case XML_IO_UNKNOWN: case XML_IO_UNKNOWN:
errmsg = "I/O error"; errmsg = "I/O error";
break; break;
case XML_ERR_RESOURCE_LIMIT:
errmsg = "Resource limit exceeded";
break;
case XML_ERR_ARGUMENT:
errmsg = "Invalid argument";
break;
case XML_ERR_SYSTEM:
errmsg = "Out of system resources";
break;
case XML_ERR_REDECL_PREDEF_ENTITY:
errmsg = "Invalid redeclaration of predefined entity";
break;
#if 0 #if 0
case: case:
errmsg = ""; errmsg = "";