mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-21 22:50:08 +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:
parent
e115194e6f
commit
abd74186f9
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:
|
||||
* @buf: the xmlBufPtr output
|
||||
@ -479,33 +505,15 @@ int
|
||||
htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
|
||||
xmlNodePtr cur, const char *encoding, int format) {
|
||||
xmlOutputBufferPtr buf;
|
||||
xmlCharEncodingHandlerPtr handler = NULL;
|
||||
xmlCharEncodingHandlerPtr handler;
|
||||
int ret;
|
||||
|
||||
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.
|
||||
*/
|
||||
handler = htmlFindOutputEncoder(encoding);
|
||||
buf = xmlOutputBufferCreateFile(out, handler);
|
||||
if (buf == NULL) return(0);
|
||||
|
||||
@ -556,27 +564,7 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
|
||||
}
|
||||
|
||||
encoding = (const char *) htmlGetMetaEncoding(cur);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
handler = htmlFindOutputEncoder(encoding);
|
||||
buf = xmlAllocOutputBufferInternal(handler);
|
||||
if (buf == NULL) {
|
||||
*mem = NULL;
|
||||
@ -712,14 +700,14 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
|
||||
xmlBufWriteQuotedString(buf->buffer, escaped);
|
||||
xmlFree(escaped);
|
||||
} else {
|
||||
xmlBufWriteQuotedString(buf->buffer, value);
|
||||
buf->error = XML_ERR_NO_MEMORY;
|
||||
}
|
||||
} else {
|
||||
xmlBufWriteQuotedString(buf->buffer, value);
|
||||
}
|
||||
xmlFree(value);
|
||||
} else {
|
||||
xmlOutputBufferWriteString(buf, "=\"\"");
|
||||
buf->error = XML_ERR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -860,10 +848,12 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
xmlChar *buffer;
|
||||
|
||||
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
|
||||
if (buffer != NULL) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)buffer);
|
||||
xmlFree(buffer);
|
||||
if (buffer == NULL) {
|
||||
buf->error = XML_ERR_NO_MEMORY;
|
||||
return;
|
||||
}
|
||||
xmlOutputBufferWriteString(buf, (const char *)buffer);
|
||||
xmlFree(buffer);
|
||||
} else {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||
}
|
||||
@ -1039,26 +1029,7 @@ htmlDocDump(FILE *f, xmlDocPtr cur) {
|
||||
}
|
||||
|
||||
encoding = (const char *) htmlGetMetaEncoding(cur);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
handler = htmlFindOutputEncoder(encoding);
|
||||
buf = xmlOutputBufferCreateFile(f, handler);
|
||||
if (buf == NULL) return(-1);
|
||||
htmlDocContentDumpOutput(buf, cur, NULL);
|
||||
@ -1089,29 +1060,7 @@ htmlSaveFile(const char *filename, xmlDocPtr cur) {
|
||||
xmlInitParser();
|
||||
|
||||
encoding = (const char *) htmlGetMetaEncoding(cur);
|
||||
|
||||
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.
|
||||
*/
|
||||
handler = htmlFindOutputEncoder(encoding);
|
||||
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
|
||||
if (buf == NULL) return(0);
|
||||
|
||||
@ -1144,28 +1093,12 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
|
||||
|
||||
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);
|
||||
}
|
||||
htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
|
||||
} else {
|
||||
handler = htmlFindOutputEncoder(encoding);
|
||||
if (handler != NULL)
|
||||
htmlSetMetaEncoding(cur, (const xmlChar *) handler->name);
|
||||
else
|
||||
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.
|
||||
*/
|
||||
|
46
error.c
46
error.c
@ -25,8 +25,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define XML_MAX_ERRORS 100
|
||||
|
||||
#define XML_GET_VAR_STR(msg, str) \
|
||||
do { \
|
||||
va_list ap; \
|
||||
@ -500,8 +498,6 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
||||
xmlParserCtxtPtr ctxt = NULL;
|
||||
xmlNodePtr node = (xmlNodePtr) nod;
|
||||
char *str = NULL;
|
||||
xmlParserInputPtr input = NULL;
|
||||
|
||||
/* xmlLastError is a macro retrieving the per-thread global. */
|
||||
xmlErrorPtr lastError = &xmlLastError;
|
||||
xmlErrorPtr to = lastError;
|
||||
@ -515,25 +511,6 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
||||
(domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
|
||||
(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
|
||||
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
|
||||
@ -560,18 +537,10 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
||||
/*
|
||||
* specific processing if a parser context is provided
|
||||
*/
|
||||
if ((ctxt != NULL) && (ctxt->input != 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;
|
||||
}
|
||||
if (ctxt != NULL)
|
||||
to = &ctxt->lastError;
|
||||
} else if ((node != NULL) && (file == NULL)) {
|
||||
|
||||
if ((node != NULL) && (file == NULL)) {
|
||||
int i;
|
||||
|
||||
if ((node->doc != NULL) && (node->doc->URL != NULL)) {
|
||||
@ -678,14 +647,7 @@ xmlVRaiseError(xmlStructuredErrorFunc schannel,
|
||||
/*
|
||||
* Find the callback channel if channel param is 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) {
|
||||
if ((ctxt == NULL) && (channel == NULL)) {
|
||||
channel = xmlGenericError;
|
||||
data = xmlGenericErrorContext;
|
||||
}
|
||||
|
52
fuzz/html.c
52
fuzz/html.c
@ -24,6 +24,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
xmlParserCtxtPtr ctxt;
|
||||
htmlDocPtr doc;
|
||||
const char *docBuffer;
|
||||
size_t maxAlloc, docSize;
|
||||
@ -31,7 +32,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
|
||||
xmlFuzzDataInit(data, size);
|
||||
opts = (int) xmlFuzzReadInt(4);
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||
|
||||
docBuffer = xmlFuzzReadRemaining(&docSize);
|
||||
if (docBuffer == NULL) {
|
||||
@ -42,31 +43,50 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
/* Pull parser */
|
||||
|
||||
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
|
||||
{
|
||||
xmlOutputBufferPtr out;
|
||||
xmlOutputBufferPtr out;
|
||||
const xmlChar *content;
|
||||
|
||||
/*
|
||||
* Also test the serializer. Call htmlDocContentDumpOutput with our
|
||||
* own buffer to avoid encoding the output. The HTML encoding is
|
||||
* excruciatingly slow (see htmlEntityValueLookup).
|
||||
*/
|
||||
out = xmlAllocOutputBuffer(NULL);
|
||||
htmlDocContentDumpOutput(out, doc, NULL);
|
||||
xmlOutputBufferClose(out);
|
||||
}
|
||||
/*
|
||||
* Also test the serializer. Call htmlDocContentDumpOutput with our
|
||||
* own buffer to avoid encoding the output. The HTML encoding is
|
||||
* excruciatingly slow (see htmlEntityValueLookup).
|
||||
*/
|
||||
xmlFuzzResetMallocFailed();
|
||||
out = xmlAllocOutputBuffer(NULL);
|
||||
htmlDocContentDumpOutput(out, doc, NULL);
|
||||
content = xmlOutputBufferGetContent(out);
|
||||
xmlFuzzCheckMallocFailure("htmlDocContentDumpOutput",
|
||||
content == NULL);
|
||||
xmlOutputBufferClose(out);
|
||||
#endif
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
xmlFuzzResetMallocFailed();
|
||||
copy = xmlCopyDoc(doc, 1);
|
||||
xmlFuzzCheckMallocFailure("xmlCopyNode", copy == NULL);
|
||||
xmlFreeDoc(copy);
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
htmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
||||
|
||||
/* Push parser */
|
||||
|
||||
#ifdef LIBXML_PUSH_ENABLED
|
||||
{
|
||||
static const size_t maxChunkSize = 128;
|
||||
xmlParserCtxtPtr ctxt;
|
||||
size_t consumed, chunkSize;
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
@ -84,6 +104,8 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
}
|
||||
|
||||
htmlParseChunk(ctxt, NULL, 0, 1);
|
||||
xmlFuzzCheckMallocFailure("htmlParseChunk",
|
||||
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||
xmlFreeDoc(ctxt->myDoc);
|
||||
htmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user