diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | SAX2.c | 31 | ||||
-rw-r--r-- | error.c | 2 | ||||
-rw-r--r-- | parser.c | 4 | ||||
-rw-r--r-- | testOOM.c | 86 | ||||
-rw-r--r-- | tree.c | 2 | ||||
-rw-r--r-- | xmlreader.c | 12 |
7 files changed, 103 insertions, 42 deletions
@@ -1,3 +1,11 @@ +Tue Jul 27 00:34:07 PDT 2004 William Brack <wbrack@mmm.com.hk> + + * SAX2.c, error.c, parser.c, tree.c, xmlreader.c: + implemented patches supplied by Olivier Andrieu + (bug 148588), plus made some further enhancements, to + correct some problems with out of memory conditions. + * testOOM.c: improved with patches from Olivier Andrieu + Mon Jul 26 11:03:18 PDT 2004 William Brack <wbrack@mmm.com.hk> * tree.c: put in patch for Windows buffer re-allocation @@ -1705,9 +1705,15 @@ skip: ret->type = XML_TEXT_NODE; ret->name = xmlStringText; - if (intern == NULL) + if (intern == NULL) { ret->content = xmlStrndup(str, len); - else + if (ret->content == NULL) { + ctxt->errNo = XML_ERR_NO_MEMORY; + ctxt->instate = XML_PARSER_EOF; + ctxt->disableSAX = 1; + return(NULL); + } + } else ret->content = (xmlChar *) intern; if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) @@ -2033,9 +2039,15 @@ xmlSAX2StartElementNs(void *ctx, if (ctxt->dictNames) ret->name = localname; - else + else { ret->name = xmlStrdup(localname); - + if (ret->name == NULL) { + ctxt->errNo = XML_ERR_NO_MEMORY; + ctxt->instate = XML_PARSER_EOF; + ctxt->disableSAX = 1; + return; + } + } if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) xmlRegisterNodeDefaultValue(ret); } else { @@ -2124,9 +2136,18 @@ xmlSAX2StartElementNs(void *ctx, * Search the namespace if it wasn't already found */ if ((URI != NULL) && (ret->ns == NULL)) { - ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); + if (prefix != NULL) + ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); + else + ret->ns = xmlSearchNsByHref(ctxt->myDoc, parent, URI); if (ret->ns == NULL) { ns = xmlNewNs(ret, NULL, prefix); + if (ns == NULL) { + ctxt->errNo = XML_ERR_NO_MEMORY; + ctxt->instate = XML_PARSER_EOF; + ctxt->disableSAX = 1; + return; + } if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) ctxt->sax->warning(ctxt->userData, "Namespace prefix %s was not found\n", prefix); @@ -552,7 +552,7 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel, /* * Find the callback channel if channel param is NULL */ - if ((ctxt != NULL) && (channel == NULL) && (xmlStructuredError == NULL)) { + if ((ctxt != NULL) && (channel == NULL) && (xmlStructuredError == NULL) && (ctxt->sax != NULL)) { if (level == XML_ERR_WARNING) channel = ctxt->sax->warning; else @@ -605,6 +605,10 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) { ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); + if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || + (ctxt->str_xml_ns == NULL)) { + xmlErrMemory(ctxt, NULL); + } } typedef struct _xmlDefAttrs xmlDefAttrs; @@ -54,7 +54,7 @@ static void usage(const char *progname) { printf("\t --valid: validate the document\n"); exit(1); } -static int elem, attrs; +static unsigned int elem, attrs, chars; static int processNode(xmlTextReaderPtr reader) { int type; @@ -64,12 +64,25 @@ static int processNode(xmlTextReaderPtr reader) { if (type == 1) { elem++; attrs += xmlTextReaderAttributeCount(reader); + } else if (type == 3) { + const xmlChar *txt; + txt = xmlTextReaderConstValue(reader); + if (txt != NULL) + chars += xmlStrlen (txt); + else + return FALSE; } } return TRUE; } + +struct file_params { + const char *filename; + unsigned int elem, attrs, chars; +}; + /* This always returns TRUE since we don't validate the results of * parsing a particular document vs. the expected results of parsing * that document. The idea is that such a failure would return FALSE. @@ -77,54 +90,57 @@ static int processNode(xmlTextReaderPtr reader) { static int check_load_file_memory_func (void *data) { - const char *filename = data; + struct file_params *p = data; xmlTextReaderPtr reader; - int ret; + int ret, status; if (count) { elem = 0; attrs = 0; + chars = 0; } - reader = xmlNewTextReaderFilename(filename); - + status = TRUE; + reader = xmlNewTextReaderFilename(p->filename); + if (reader != NULL) { if (valid) { - if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1) { - xmlFreeTextReader (reader); - return TRUE; - } + if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1) + goto out; } /* * Process all nodes in sequence */ - ret = xmlTextReaderRead (reader); - - while (TRUE) { - if (ret == -1) { - xmlFreeTextReader (reader); - return TRUE; - } else if (ret != 1) - break; - - if (!processNode(reader)) { - xmlFreeTextReader (reader); - return FALSE; - } - - ret = xmlTextReaderRead(reader); + while ((ret = xmlTextReaderRead(reader)) == 1) { + if (!processNode(reader)) + goto out; } + if (ret == -1) + goto out; /* * Done, cleanup and status */ - xmlFreeTextReader (reader); - - return TRUE; - } else { - return TRUE; + if (count) + { + if (p->elem == (unsigned int)-1) { + p->elem = elem; + p->attrs = attrs; + p->chars = chars; + } + else { + status = (elem == p->elem && attrs == p->attrs && chars == p->chars); + fprintf (stderr, "# %s: %u elems, %u attrs, %u chars %s\n", + p->filename, elem, attrs, chars, + status ? "ok" : "wrong"); + } + } } + out: + if (reader) + xmlFreeTextReader (reader); + return status; } int main(int argc, char **argv) { @@ -159,8 +175,18 @@ int main(int argc, char **argv) { xmlSubstituteEntitiesDefault(1); for (i = 1; i < argc ; i++) { if (argv[i][0] != '-') { + struct file_params p; + p.filename = argv[i]; + p.elem = -1; + + /* Run once to count */ + check_load_file_memory_func (&p); + if (count) { + fprintf (stderr, "# %s: %u elems, %u attrs, %u chars\n", + p.filename, p.elem, p.attrs, p.chars); + } if (!test_oom_handling (check_load_file_memory_func, - argv[i])) { + &p)) { fprintf (stderr, "Failed!\n"); return (1); } @@ -1861,7 +1861,6 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name, cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { xmlTreeErrMemory("building attribute"); - xmlFree(name); return(NULL); } memset(cur, 0, sizeof(xmlAttr)); @@ -2172,7 +2171,6 @@ xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) { cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { xmlTreeErrMemory("building node"); - xmlFree(name); return(NULL); } memset(cur, 0, sizeof(xmlNode)); diff --git a/xmlreader.c b/xmlreader.c index 8c5bba18..923104c1 100644 --- a/xmlreader.c +++ b/xmlreader.c @@ -825,7 +825,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) { (const char *) &inbuf->content[reader->cur], CHUNK_SIZE, 0); reader->cur += CHUNK_SIZE; - if ((val != 0) && (reader->ctxt->wellFormed == 0)) + if ((val != 0) || (reader->ctxt->wellFormed == 0)) return(-1); } else { s = inbuf->use - reader->cur; @@ -833,7 +833,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) { (const char *) &inbuf->content[reader->cur], s, 0); reader->cur += s; - if ((val != 0) && (reader->ctxt->wellFormed == 0)) + if ((val != 0) || (reader->ctxt->wellFormed == 0)) return(-1); break; } @@ -866,7 +866,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) { s, 1); reader->cur = inbuf->use; reader->mode = XML_TEXTREADER_DONE; - if ((val != 0) && (reader->ctxt->wellFormed == 0)) + if ((val != 0) || (reader->ctxt->wellFormed == 0)) return(-1); } } @@ -1343,6 +1343,8 @@ get_next_node: if (reader->mode != XML_TEXTREADER_DONE) { val = xmlParseChunk(reader->ctxt, "", 0, 1); reader->mode = XML_TEXTREADER_DONE; + if (val != 0) + return(-1); } reader->node = NULL; reader->depth = -1; @@ -3902,7 +3904,7 @@ xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity, char *str) { xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt; xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private; - if (str != NULL) { + if (str != NULL && reader->errorFunc) { reader->errorFunc(reader->errorFuncArg, str, severity, @@ -4002,6 +4004,7 @@ xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader, reader->ctxt->sax->warning = xmlTextReaderWarning; reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning; reader->errorFunc = f; + reader->sErrorFunc = NULL; reader->errorFuncArg = arg; } else { @@ -4031,6 +4034,7 @@ xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader, xmlStructuredErrorFunc f, void *arg) { if (f != NULL) { + reader->ctxt->sax->error = NULL; reader->ctxt->sax->serror = xmlTextReaderStructuredError; reader->ctxt->vctxt.error = xmlTextReaderValidityError; reader->ctxt->sax->warning = xmlTextReaderWarning; |