1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-12 09:17:37 +03:00

encoding: Check whether encoding handlers support input/output

The "HTML" encoding handler doesn't support input which could lead to a
wrong error report.
This commit is contained in:
Nick Wellnhofer 2024-01-02 18:33:57 +01:00
parent 85f99023ae
commit 0821efc8ee
6 changed files with 75 additions and 32 deletions

View File

@ -389,7 +389,7 @@ htmlFindOutputEncoder(const char *encoding) {
enc = xmlParseCharEncoding(encoding);
if (enc != XML_CHAR_ENCODING_UTF8) {
handler = xmlFindCharEncodingHandler(encoding);
xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
if (handler == NULL)
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
}
@ -398,9 +398,9 @@ htmlFindOutputEncoder(const char *encoding) {
* Fallback to HTML or ASCII when the encoding is unspecified
*/
if (handler == NULL)
handler = xmlFindCharEncodingHandler("HTML");
xmlOpenCharEncodingHandler("HTML", /* output */ 1, &handler);
if (handler == NULL)
handler = xmlFindCharEncodingHandler("ascii");
xmlOpenCharEncodingHandler("ascii", /* output */ 1, &handler);
}
return(handler);

View File

@ -1659,6 +1659,7 @@ error:
/**
* xmlFindExtraHandler:
* @name: a string describing the char encoding.
* @output: boolean, use handler for output
* @out: pointer to resulting handler
*
* Search the non-default handlers for an exact match.
@ -1667,7 +1668,8 @@ error:
* allocation failed.
*/
static int
xmlFindExtraHandler(const char *name, xmlCharEncodingHandler **out) {
xmlFindExtraHandler(const char *name, int output,
xmlCharEncodingHandler **out) {
int ret;
int i;
@ -1675,10 +1677,21 @@ xmlFindExtraHandler(const char *name, xmlCharEncodingHandler **out) {
if (handlers != NULL) {
for (i = 0; i < nbCharEncodingHandler; i++) {
xmlCharEncodingHandler *handler = handlers[i];
if (!xmlStrcasecmp((const xmlChar *) name,
(const xmlChar *) handlers[i]->name)) {
*out = handlers[i];
return(0);
(const xmlChar *) handler->name)) {
if (output) {
if (handler->output != NULL) {
*out = handler;
return(0);
}
} else {
if (handler->input != NULL) {
*out = handler;
return(0);
}
}
}
}
}
@ -1705,6 +1718,7 @@ xmlFindExtraHandler(const char *name, xmlCharEncodingHandler **out) {
/**
* xmlFindHandler:
* @name: a string describing the char encoding.
* @output: boolean, use handler for output
* @out: pointer to resulting handler
*
* Search all handlers for an exact match.
@ -1713,24 +1727,37 @@ xmlFindExtraHandler(const char *name, xmlCharEncodingHandler **out) {
* allocation failed.
*/
static int
xmlFindHandler(const char *name, xmlCharEncodingHandler **out) {
xmlFindHandler(const char *name, int output, xmlCharEncodingHandler **out) {
int i;
/*
* Check for default handlers
*/
for (i = 0; i < (int) NUM_DEFAULT_HANDLERS; i++) {
xmlCharEncodingHandler *handler;
handler = (xmlCharEncodingHandler *) &defaultHandlers[i];
if (xmlStrcasecmp((const xmlChar *) name,
(const xmlChar *) defaultHandlers[i].name) == 0) {
*out = (xmlCharEncodingHandler *) &defaultHandlers[i];
return(0);
(const xmlChar *) handler->name) == 0) {
if (output) {
if (handler->output != NULL) {
*out = handler;
return(0);
}
} else {
if (handler->input != NULL) {
*out = handler;
return(0);
}
}
}
}
/*
* Check for other handlers
*/
return(xmlFindExtraHandler(name, out));
return(xmlFindExtraHandler(name, output, out));
}
/**
@ -1850,11 +1877,11 @@ xmlLookupCharEncodingHandler(xmlCharEncoding enc,
}
if (name != NULL)
return(xmlFindExtraHandler(name, out));
return(xmlFindExtraHandler(name, 0, out));
if (names != NULL) {
for (i = 0; i < numNames; i++) {
ret = xmlFindExtraHandler(names[i], out);
ret = xmlFindExtraHandler(names[i], 0, out);
if (*out != NULL)
return(0);
if (ret != XML_ERR_UNSUPPORTED_ENCODING)
@ -1886,6 +1913,7 @@ xmlGetCharEncodingHandler(xmlCharEncoding enc) {
/**
* xmlOpenCharEncodingHandler:
* @name: a string describing the char encoding.
* @output: boolean, use handler for output
* @out: pointer to result
*
* Find or create a handler matching the encoding. If no default or
@ -1899,7 +1927,8 @@ xmlGetCharEncodingHandler(xmlCharEncoding enc) {
* Returns an xmlParserErrors error code.
*/
int
xmlOpenCharEncodingHandler(const char *name, xmlCharEncodingHandler **out) {
xmlOpenCharEncodingHandler(const char *name, int output,
xmlCharEncodingHandler **out) {
const char *nalias;
const char *norig;
xmlCharEncoding enc;
@ -1920,7 +1949,7 @@ xmlOpenCharEncodingHandler(const char *name, xmlCharEncodingHandler **out) {
if (nalias != NULL)
name = nalias;
ret = xmlFindHandler(name, out);
ret = xmlFindHandler(name, output, out);
if (*out != NULL)
return(0);
if (ret != XML_ERR_UNSUPPORTED_ENCODING)
@ -1947,7 +1976,7 @@ xmlCharEncodingHandlerPtr
xmlFindCharEncodingHandler(const char *name) {
xmlCharEncodingHandler *ret;
xmlOpenCharEncodingHandler(name, &ret);
xmlOpenCharEncodingHandler(name, 0, &ret);
return(ret);
}

View File

@ -167,6 +167,7 @@ XMLPUBFUN int
xmlCharEncodingHandlerPtr *out);
XMLPUBFUN int
xmlOpenCharEncodingHandler (const char *name,
int output,
xmlCharEncodingHandlerPtr *out);
XMLPUBFUN xmlCharEncodingHandlerPtr
xmlGetCharEncodingHandler (xmlCharEncoding enc);

View File

@ -999,7 +999,8 @@ xmlDetectEBCDIC(xmlParserInputPtr input, xmlCharEncodingHandlerPtr *hout) {
break;
out[i] = 0;
xmlCharEncCloseFunc(handler);
res = xmlOpenCharEncodingHandler((char *) out + start, &handler);
res = xmlOpenCharEncodingHandler((char *) out + start,
/* output */ 0, &handler);
if (res != 0)
return(res);
*hout = handler;
@ -1089,7 +1090,7 @@ xmlSwitchInputEncodingName(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
if (encoding == NULL)
return(-1);
res = xmlOpenCharEncodingHandler(encoding, &handler);
res = xmlOpenCharEncodingHandler(encoding, /* output */ 0, &handler);
if (res != 0) {
xmlFatalErr(ctxt, res, encoding);
return(-1);

View File

@ -1609,7 +1609,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
encoding = xmlXIncludeGetProp(ctxt, ref->elem, XINCLUDE_PARSE_ENCODING);
}
if (encoding != NULL) {
res = xmlOpenCharEncodingHandler((const char *) encoding, &handler);
res = xmlOpenCharEncodingHandler((const char *) encoding,
/* output */ 0, &handler);
if (res != 0) {
if (res == XML_ERR_NO_MEMORY) {

View File

@ -321,9 +321,15 @@ xmlNewSaveCtxt(const char *encoding, int options)
memset(ret, 0, sizeof(xmlSaveCtxt));
if (encoding != NULL) {
ret->handler = xmlFindCharEncodingHandler(encoding);
int res;
res = xmlOpenCharEncodingHandler(encoding, /* output */ 1,
&ret->handler);
if (ret->handler == NULL) {
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
if (res < 0)
xmlSaveErrMemory();
else
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
xmlFreeSaveCtxt(ret);
return(NULL);
}
@ -488,7 +494,7 @@ static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
xmlCharEncodingHandler *handler;
int res;
res = xmlOpenCharEncodingHandler(encoding, &handler);
res = xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
if (res != 0) {
if (res < 0)
xmlSaveErrMemory();
@ -2315,10 +2321,16 @@ xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
if (txt_encoding == NULL)
txt_encoding = (const char *) out_doc->encoding;
if (txt_encoding != NULL) {
conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
if ( conv_hdlr == NULL ) {
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, (xmlNodePtr) out_doc,
txt_encoding);
int res;
res = xmlOpenCharEncodingHandler(txt_encoding, /* output */ 1,
&conv_hdlr);
if (conv_hdlr == NULL) {
if (res < 0)
xmlSaveErrMemory();
else
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, (xmlNodePtr) out_doc,
txt_encoding);
return;
}
}
@ -2442,7 +2454,7 @@ xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
encoding = (const char *) cur->encoding;
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
if (handler == NULL) {
xmlFree((char *) cur->encoding);
cur->encoding = NULL;
@ -2579,10 +2591,9 @@ xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur,
encoding = (const char *) cur->encoding;
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL)
return(-1);
xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
if (handler == NULL)
return(-1);
}
#ifdef LIBXML_ZLIB_ENABLED