summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--SAX2.c31
-rw-r--r--error.c2
-rw-r--r--parser.c4
-rw-r--r--testOOM.c86
-rw-r--r--tree.c2
-rw-r--r--xmlreader.c12
7 files changed, 103 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index fa68fc72..6b954b53 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/SAX2.c b/SAX2.c
index cc65e0ad..23ed1a10 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -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);
diff --git a/error.c b/error.c
index 2e903dc4..a79e2142 100644
--- a/error.c
+++ b/error.c
@@ -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
diff --git a/parser.c b/parser.c
index 77a12f50..4f54794c 100644
--- a/parser.c
+++ b/parser.c
@@ -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;
diff --git a/testOOM.c b/testOOM.c
index 8e9a3024..7d9b4116 100644
--- a/testOOM.c
+++ b/testOOM.c
@@ -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);
}
diff --git a/tree.c b/tree.c
index c1d8add9..fc22d52e 100644
--- a/tree.c
+++ b/tree.c
@@ -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;