mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-24 13:33:01 +03:00
html: Report malloc failures
Fix many places where malloc failures aren't reported. Stop checking for ctxt->instate.
This commit is contained in:
507
HTMLparser.c
507
HTMLparser.c
File diff suppressed because it is too large
Load Diff
151
HTMLtree.c
151
HTMLtree.c
@@ -384,6 +384,32 @@ htmlSaveErr(int code, xmlNodePtr node, const char *extra)
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
static xmlCharEncodingHandler *
|
||||||
|
htmlFindOutputEncoder(const char *encoding) {
|
||||||
|
xmlCharEncodingHandler *handler = NULL;
|
||||||
|
|
||||||
|
if (encoding != NULL) {
|
||||||
|
xmlCharEncoding enc;
|
||||||
|
|
||||||
|
enc = xmlParseCharEncoding(encoding);
|
||||||
|
if (enc != XML_CHAR_ENCODING_UTF8) {
|
||||||
|
handler = xmlFindCharEncodingHandler(encoding);
|
||||||
|
if (handler == NULL)
|
||||||
|
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Fallback to HTML or ASCII when the encoding is unspecified
|
||||||
|
*/
|
||||||
|
if (handler == NULL)
|
||||||
|
handler = xmlFindCharEncodingHandler("HTML");
|
||||||
|
if (handler == NULL)
|
||||||
|
handler = xmlFindCharEncodingHandler("ascii");
|
||||||
|
}
|
||||||
|
|
||||||
|
return(handler);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* htmlBufNodeDumpFormat:
|
* htmlBufNodeDumpFormat:
|
||||||
* @buf: the xmlBufPtr output
|
* @buf: the xmlBufPtr output
|
||||||
@@ -479,33 +505,15 @@ int
|
|||||||
htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
|
htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
|
||||||
xmlNodePtr cur, const char *encoding, int format) {
|
xmlNodePtr cur, const char *encoding, int format) {
|
||||||
xmlOutputBufferPtr buf;
|
xmlOutputBufferPtr buf;
|
||||||
xmlCharEncodingHandlerPtr handler = NULL;
|
xmlCharEncodingHandlerPtr handler;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
|
|
||||||
if (encoding != NULL) {
|
|
||||||
xmlCharEncoding enc;
|
|
||||||
|
|
||||||
enc = xmlParseCharEncoding(encoding);
|
|
||||||
if (enc != XML_CHAR_ENCODING_UTF8) {
|
|
||||||
handler = xmlFindCharEncodingHandler(encoding);
|
|
||||||
if (handler == NULL)
|
|
||||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
|
||||||
*/
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("HTML");
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("ascii");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* save the content to a temp buffer.
|
* save the content to a temp buffer.
|
||||||
*/
|
*/
|
||||||
|
handler = htmlFindOutputEncoder(encoding);
|
||||||
buf = xmlOutputBufferCreateFile(out, handler);
|
buf = xmlOutputBufferCreateFile(out, handler);
|
||||||
if (buf == NULL) return(0);
|
if (buf == NULL) return(0);
|
||||||
|
|
||||||
@@ -556,27 +564,7 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
encoding = (const char *) htmlGetMetaEncoding(cur);
|
encoding = (const char *) htmlGetMetaEncoding(cur);
|
||||||
|
handler = htmlFindOutputEncoder(encoding);
|
||||||
if (encoding != NULL) {
|
|
||||||
xmlCharEncoding enc;
|
|
||||||
|
|
||||||
enc = xmlParseCharEncoding(encoding);
|
|
||||||
if (enc != XML_CHAR_ENCODING_UTF8) {
|
|
||||||
handler = xmlFindCharEncodingHandler(encoding);
|
|
||||||
if (handler == NULL)
|
|
||||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
|
||||||
*/
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("HTML");
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("ascii");
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = xmlAllocOutputBufferInternal(handler);
|
buf = xmlAllocOutputBufferInternal(handler);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
*mem = NULL;
|
*mem = NULL;
|
||||||
@@ -712,14 +700,14 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
|
|||||||
xmlBufWriteQuotedString(buf->buffer, escaped);
|
xmlBufWriteQuotedString(buf->buffer, escaped);
|
||||||
xmlFree(escaped);
|
xmlFree(escaped);
|
||||||
} else {
|
} else {
|
||||||
xmlBufWriteQuotedString(buf->buffer, value);
|
buf->error = XML_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xmlBufWriteQuotedString(buf->buffer, value);
|
xmlBufWriteQuotedString(buf->buffer, value);
|
||||||
}
|
}
|
||||||
xmlFree(value);
|
xmlFree(value);
|
||||||
} else {
|
} else {
|
||||||
xmlOutputBufferWriteString(buf, "=\"\"");
|
buf->error = XML_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -860,10 +848,12 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
|||||||
xmlChar *buffer;
|
xmlChar *buffer;
|
||||||
|
|
||||||
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
|
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
|
||||||
if (buffer != NULL) {
|
if (buffer == NULL) {
|
||||||
xmlOutputBufferWriteString(buf, (const char *)buffer);
|
buf->error = XML_ERR_NO_MEMORY;
|
||||||
xmlFree(buffer);
|
return;
|
||||||
}
|
}
|
||||||
|
xmlOutputBufferWriteString(buf, (const char *)buffer);
|
||||||
|
xmlFree(buffer);
|
||||||
} else {
|
} else {
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||||
}
|
}
|
||||||
@@ -1039,26 +1029,7 @@ htmlDocDump(FILE *f, xmlDocPtr cur) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
encoding = (const char *) htmlGetMetaEncoding(cur);
|
encoding = (const char *) htmlGetMetaEncoding(cur);
|
||||||
|
handler = htmlFindOutputEncoder(encoding);
|
||||||
if (encoding != NULL) {
|
|
||||||
xmlCharEncoding enc;
|
|
||||||
|
|
||||||
enc = xmlParseCharEncoding(encoding);
|
|
||||||
if (enc != XML_CHAR_ENCODING_UTF8) {
|
|
||||||
handler = xmlFindCharEncodingHandler(encoding);
|
|
||||||
if (handler == NULL)
|
|
||||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
|
||||||
*/
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("HTML");
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("ascii");
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = xmlOutputBufferCreateFile(f, handler);
|
buf = xmlOutputBufferCreateFile(f, handler);
|
||||||
if (buf == NULL) return(-1);
|
if (buf == NULL) return(-1);
|
||||||
htmlDocContentDumpOutput(buf, cur, NULL);
|
htmlDocContentDumpOutput(buf, cur, NULL);
|
||||||
@@ -1089,29 +1060,7 @@ htmlSaveFile(const char *filename, xmlDocPtr cur) {
|
|||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
|
|
||||||
encoding = (const char *) htmlGetMetaEncoding(cur);
|
encoding = (const char *) htmlGetMetaEncoding(cur);
|
||||||
|
handler = htmlFindOutputEncoder(encoding);
|
||||||
if (encoding != NULL) {
|
|
||||||
xmlCharEncoding enc;
|
|
||||||
|
|
||||||
enc = xmlParseCharEncoding(encoding);
|
|
||||||
if (enc != XML_CHAR_ENCODING_UTF8) {
|
|
||||||
handler = xmlFindCharEncodingHandler(encoding);
|
|
||||||
if (handler == NULL)
|
|
||||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
|
||||||
*/
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("HTML");
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("ascii");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* save the content to a temp buffer.
|
|
||||||
*/
|
|
||||||
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
|
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
|
||||||
if (buf == NULL) return(0);
|
if (buf == NULL) return(0);
|
||||||
|
|
||||||
@@ -1144,28 +1093,12 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
|
|||||||
|
|
||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
|
|
||||||
if (encoding != NULL) {
|
handler = htmlFindOutputEncoder(encoding);
|
||||||
xmlCharEncoding enc;
|
if (handler != NULL)
|
||||||
|
htmlSetMetaEncoding(cur, (const xmlChar *) handler->name);
|
||||||
enc = xmlParseCharEncoding(encoding);
|
else
|
||||||
if (enc != XML_CHAR_ENCODING_UTF8) {
|
|
||||||
handler = xmlFindCharEncodingHandler(encoding);
|
|
||||||
if (handler == NULL)
|
|
||||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
|
||||||
}
|
|
||||||
htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
|
|
||||||
} else {
|
|
||||||
htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
|
htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
|
||||||
|
|
||||||
/*
|
|
||||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
|
||||||
*/
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("HTML");
|
|
||||||
if (handler == NULL)
|
|
||||||
handler = xmlFindCharEncodingHandler("ascii");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* save the content to a temp buffer.
|
* save the content to a temp buffer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
46
error.c
46
error.c
@@ -25,8 +25,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define XML_MAX_ERRORS 100
|
|
||||||
|
|
||||||
#define XML_GET_VAR_STR(msg, str) \
|
#define XML_GET_VAR_STR(msg, str) \
|
||||||
do { \
|
do { \
|
||||||
va_list ap; \
|
va_list ap; \
|
||||||
@@ -500,8 +498,6 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
|||||||
xmlParserCtxtPtr ctxt = NULL;
|
xmlParserCtxtPtr ctxt = NULL;
|
||||||
xmlNodePtr node = (xmlNodePtr) nod;
|
xmlNodePtr node = (xmlNodePtr) nod;
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
xmlParserInputPtr input = NULL;
|
|
||||||
|
|
||||||
/* xmlLastError is a macro retrieving the per-thread global. */
|
/* xmlLastError is a macro retrieving the per-thread global. */
|
||||||
xmlErrorPtr lastError = &xmlLastError;
|
xmlErrorPtr lastError = &xmlLastError;
|
||||||
xmlErrorPtr to = lastError;
|
xmlErrorPtr to = lastError;
|
||||||
@@ -515,25 +511,6 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
|||||||
(domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
|
(domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
|
||||||
(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
|
(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
|
||||||
ctxt = (xmlParserCtxtPtr) ctx;
|
ctxt = (xmlParserCtxtPtr) ctx;
|
||||||
|
|
||||||
if (ctxt != NULL) {
|
|
||||||
if (level == XML_ERR_WARNING) {
|
|
||||||
if (ctxt->nbWarnings >= XML_MAX_ERRORS)
|
|
||||||
return(0);
|
|
||||||
ctxt->nbWarnings += 1;
|
|
||||||
} else {
|
|
||||||
if (ctxt->nbErrors >= XML_MAX_ERRORS)
|
|
||||||
return(0);
|
|
||||||
ctxt->nbErrors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((schannel == NULL) && (ctxt->sax != NULL) &&
|
|
||||||
(ctxt->sax->initialized == XML_SAX2_MAGIC) &&
|
|
||||||
(ctxt->sax->serror != NULL)) {
|
|
||||||
schannel = ctxt->sax->serror;
|
|
||||||
data = ctxt->userData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Check if structured error handler set
|
* Check if structured error handler set
|
||||||
@@ -560,18 +537,10 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
|||||||
/*
|
/*
|
||||||
* specific processing if a parser context is provided
|
* specific processing if a parser context is provided
|
||||||
*/
|
*/
|
||||||
if ((ctxt != NULL) && (ctxt->input != NULL)) {
|
if (ctxt != NULL)
|
||||||
if (file == NULL) {
|
|
||||||
input = ctxt->input;
|
|
||||||
if ((input->filename == NULL) && (ctxt->inputNr > 1)) {
|
|
||||||
input = ctxt->inputTab[ctxt->inputNr - 2];
|
|
||||||
}
|
|
||||||
file = input->filename;
|
|
||||||
line = input->line;
|
|
||||||
col = input->col;
|
|
||||||
}
|
|
||||||
to = &ctxt->lastError;
|
to = &ctxt->lastError;
|
||||||
} else if ((node != NULL) && (file == NULL)) {
|
|
||||||
|
if ((node != NULL) && (file == NULL)) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((node->doc != NULL) && (node->doc->URL != NULL)) {
|
if ((node->doc != NULL) && (node->doc->URL != NULL)) {
|
||||||
@@ -678,14 +647,7 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
|||||||
/*
|
/*
|
||||||
* Find the callback channel if channel param is NULL
|
* Find the callback channel if channel param is NULL
|
||||||
*/
|
*/
|
||||||
if ((ctxt != NULL) && (channel == NULL) &&
|
if ((ctxt == NULL) && (channel == NULL)) {
|
||||||
(xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
|
|
||||||
if (level == XML_ERR_WARNING)
|
|
||||||
channel = ctxt->sax->warning;
|
|
||||||
else
|
|
||||||
channel = ctxt->sax->error;
|
|
||||||
data = ctxt->userData;
|
|
||||||
} else if (channel == NULL) {
|
|
||||||
channel = xmlGenericError;
|
channel = xmlGenericError;
|
||||||
data = xmlGenericErrorContext;
|
data = xmlGenericErrorContext;
|
||||||
}
|
}
|
||||||
|
|||||||
52
fuzz/html.c
52
fuzz/html.c
@@ -24,6 +24,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
int
|
int
|
||||||
LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||||
|
xmlParserCtxtPtr ctxt;
|
||||||
htmlDocPtr doc;
|
htmlDocPtr doc;
|
||||||
const char *docBuffer;
|
const char *docBuffer;
|
||||||
size_t maxAlloc, docSize;
|
size_t maxAlloc, docSize;
|
||||||
@@ -31,7 +32,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
|||||||
|
|
||||||
xmlFuzzDataInit(data, size);
|
xmlFuzzDataInit(data, size);
|
||||||
opts = (int) xmlFuzzReadInt(4);
|
opts = (int) xmlFuzzReadInt(4);
|
||||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||||
|
|
||||||
docBuffer = xmlFuzzReadRemaining(&docSize);
|
docBuffer = xmlFuzzReadRemaining(&docSize);
|
||||||
if (docBuffer == NULL) {
|
if (docBuffer == NULL) {
|
||||||
@@ -42,31 +43,50 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
|||||||
/* Pull parser */
|
/* Pull parser */
|
||||||
|
|
||||||
xmlFuzzMemSetLimit(maxAlloc);
|
xmlFuzzMemSetLimit(maxAlloc);
|
||||||
doc = htmlReadMemory(docBuffer, docSize, NULL, NULL, opts);
|
ctxt = htmlNewParserCtxt();
|
||||||
|
if (ctxt != NULL) {
|
||||||
|
doc = htmlCtxtReadMemory(ctxt, docBuffer, docSize, NULL, NULL, opts);
|
||||||
|
xmlFuzzCheckMallocFailure("htmlCtxtReadMemory",
|
||||||
|
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||||
|
|
||||||
|
if (doc != NULL) {
|
||||||
|
xmlDocPtr copy;
|
||||||
|
|
||||||
#ifdef LIBXML_OUTPUT_ENABLED
|
#ifdef LIBXML_OUTPUT_ENABLED
|
||||||
{
|
xmlOutputBufferPtr out;
|
||||||
xmlOutputBufferPtr out;
|
const xmlChar *content;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also test the serializer. Call htmlDocContentDumpOutput with our
|
* Also test the serializer. Call htmlDocContentDumpOutput with our
|
||||||
* own buffer to avoid encoding the output. The HTML encoding is
|
* own buffer to avoid encoding the output. The HTML encoding is
|
||||||
* excruciatingly slow (see htmlEntityValueLookup).
|
* excruciatingly slow (see htmlEntityValueLookup).
|
||||||
*/
|
*/
|
||||||
out = xmlAllocOutputBuffer(NULL);
|
xmlFuzzResetMallocFailed();
|
||||||
htmlDocContentDumpOutput(out, doc, NULL);
|
out = xmlAllocOutputBuffer(NULL);
|
||||||
xmlOutputBufferClose(out);
|
htmlDocContentDumpOutput(out, doc, NULL);
|
||||||
}
|
content = xmlOutputBufferGetContent(out);
|
||||||
|
xmlFuzzCheckMallocFailure("htmlDocContentDumpOutput",
|
||||||
|
content == NULL);
|
||||||
|
xmlOutputBufferClose(out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xmlFreeDoc(doc);
|
xmlFuzzResetMallocFailed();
|
||||||
|
copy = xmlCopyDoc(doc, 1);
|
||||||
|
xmlFuzzCheckMallocFailure("xmlCopyNode", copy == NULL);
|
||||||
|
xmlFreeDoc(copy);
|
||||||
|
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlFreeParserCtxt(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Push parser */
|
/* Push parser */
|
||||||
|
|
||||||
#ifdef LIBXML_PUSH_ENABLED
|
#ifdef LIBXML_PUSH_ENABLED
|
||||||
{
|
{
|
||||||
static const size_t maxChunkSize = 128;
|
static const size_t maxChunkSize = 128;
|
||||||
xmlParserCtxtPtr ctxt;
|
|
||||||
size_t consumed, chunkSize;
|
size_t consumed, chunkSize;
|
||||||
|
|
||||||
xmlFuzzMemSetLimit(maxAlloc);
|
xmlFuzzMemSetLimit(maxAlloc);
|
||||||
@@ -84,6 +104,8 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
htmlParseChunk(ctxt, NULL, 0, 1);
|
htmlParseChunk(ctxt, NULL, 0, 1);
|
||||||
|
xmlFuzzCheckMallocFailure("htmlParseChunk",
|
||||||
|
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||||
xmlFreeDoc(ctxt->myDoc);
|
xmlFreeDoc(ctxt->myDoc);
|
||||||
htmlFreeParserCtxt(ctxt);
|
htmlFreeParserCtxt(ctxt);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user