Commit 9f797abd authored by William M. Brack's avatar William M. Brack
Browse files

implemented patches supplied by Olivier Andrieu (bug 148588), plus made

* 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
parent 30fe43f6
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> Mon Jul 26 11:03:18 PDT 2004 William Brack <wbrack@mmm.com.hk>
   
* tree.c: put in patch for Windows buffer re-allocation * tree.c: put in patch for Windows buffer re-allocation
......
...@@ -1705,9 +1705,15 @@ skip: ...@@ -1705,9 +1705,15 @@ skip:
ret->type = XML_TEXT_NODE; ret->type = XML_TEXT_NODE;
ret->name = xmlStringText; ret->name = xmlStringText;
if (intern == NULL) if (intern == NULL) {
ret->content = xmlStrndup(str, len); 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; ret->content = (xmlChar *) intern;
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
...@@ -2033,9 +2039,15 @@ xmlSAX2StartElementNs(void *ctx, ...@@ -2033,9 +2039,15 @@ xmlSAX2StartElementNs(void *ctx,
if (ctxt->dictNames) if (ctxt->dictNames)
ret->name = localname; ret->name = localname;
else else {
ret->name = xmlStrdup(localname); 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)) if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue(ret); xmlRegisterNodeDefaultValue(ret);
} else { } else {
...@@ -2124,9 +2136,18 @@ xmlSAX2StartElementNs(void *ctx, ...@@ -2124,9 +2136,18 @@ xmlSAX2StartElementNs(void *ctx,
* Search the namespace if it wasn't already found * Search the namespace if it wasn't already found
*/ */
if ((URI != NULL) && (ret->ns == NULL)) { if ((URI != NULL) && (ret->ns == NULL)) {
if (prefix != NULL)
ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
else
ret->ns = xmlSearchNsByHref(ctxt->myDoc, parent, URI);
if (ret->ns == NULL) { if (ret->ns == NULL) {
ns = xmlNewNs(ret, NULL, prefix); 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)) if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData, ctxt->sax->warning(ctxt->userData,
"Namespace prefix %s was not found\n", prefix); "Namespace prefix %s was not found\n", prefix);
......
...@@ -552,7 +552,7 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel, ...@@ -552,7 +552,7 @@ __xmlRaiseError(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) && (xmlStructuredError == NULL)) { if ((ctxt != NULL) && (channel == NULL) && (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
if (level == XML_ERR_WARNING) if (level == XML_ERR_WARNING)
channel = ctxt->sax->warning; channel = ctxt->sax->warning;
else else
......
...@@ -605,6 +605,10 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) { ...@@ -605,6 +605,10 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); 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; typedef struct _xmlDefAttrs xmlDefAttrs;
......
...@@ -54,7 +54,7 @@ static void usage(const char *progname) { ...@@ -54,7 +54,7 @@ static void usage(const char *progname) {
printf("\t --valid: validate the document\n"); printf("\t --valid: validate the document\n");
exit(1); exit(1);
} }
static int elem, attrs; static unsigned int elem, attrs, chars;
static int processNode(xmlTextReaderPtr reader) { static int processNode(xmlTextReaderPtr reader) {
int type; int type;
...@@ -64,12 +64,25 @@ static int processNode(xmlTextReaderPtr reader) { ...@@ -64,12 +64,25 @@ static int processNode(xmlTextReaderPtr reader) {
if (type == 1) { if (type == 1) {
elem++; elem++;
attrs += xmlTextReaderAttributeCount(reader); attrs += xmlTextReaderAttributeCount(reader);
} else if (type == 3) {
const xmlChar *txt;
txt = xmlTextReaderConstValue(reader);
if (txt != NULL)
chars += xmlStrlen (txt);
else
return FALSE;
} }
} }
return TRUE; 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 /* This always returns TRUE since we don't validate the results of
* parsing a particular document vs. the expected results of parsing * parsing a particular document vs. the expected results of parsing
* that document. The idea is that such a failure would return FALSE. * that document. The idea is that such a failure would return FALSE.
...@@ -77,54 +90,57 @@ static int processNode(xmlTextReaderPtr reader) { ...@@ -77,54 +90,57 @@ static int processNode(xmlTextReaderPtr reader) {
static int static int
check_load_file_memory_func (void *data) check_load_file_memory_func (void *data)
{ {
const char *filename = data; struct file_params *p = data;
xmlTextReaderPtr reader; xmlTextReaderPtr reader;
int ret; int ret, status;
if (count) { if (count) {
elem = 0; elem = 0;
attrs = 0; attrs = 0;
chars = 0;
} }
reader = xmlNewTextReaderFilename(filename); status = TRUE;
reader = xmlNewTextReaderFilename(p->filename);
if (reader != NULL) { if (reader != NULL) {
if (valid) { if (valid) {
if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1) { if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1)
xmlFreeTextReader (reader); goto out;
return TRUE;
}
} }
/* /*
* Process all nodes in sequence * Process all nodes in sequence
*/ */
ret = xmlTextReaderRead (reader); while ((ret = xmlTextReaderRead(reader)) == 1) {
if (!processNode(reader))
while (TRUE) { goto out;
if (ret == -1) {
xmlFreeTextReader (reader);
return TRUE;
} else if (ret != 1)
break;
if (!processNode(reader)) {
xmlFreeTextReader (reader);
return FALSE;
}
ret = xmlTextReaderRead(reader);
} }
if (ret == -1)
goto out;
/* /*
* Done, cleanup and status * Done, cleanup and status
*/ */
xmlFreeTextReader (reader); if (count)
{
return TRUE; if (p->elem == (unsigned int)-1) {
} else { p->elem = elem;
return TRUE; 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) { int main(int argc, char **argv) {
...@@ -159,8 +175,18 @@ int main(int argc, char **argv) { ...@@ -159,8 +175,18 @@ int main(int argc, char **argv) {
xmlSubstituteEntitiesDefault(1); xmlSubstituteEntitiesDefault(1);
for (i = 1; i < argc ; i++) { for (i = 1; i < argc ; i++) {
if (argv[i][0] != '-') { 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, if (!test_oom_handling (check_load_file_memory_func,
argv[i])) { &p)) {
fprintf (stderr, "Failed!\n"); fprintf (stderr, "Failed!\n");
return (1); return (1);
} }
......
...@@ -1861,7 +1861,6 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name, ...@@ -1861,7 +1861,6 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
if (cur == NULL) { if (cur == NULL) {
xmlTreeErrMemory("building attribute"); xmlTreeErrMemory("building attribute");
xmlFree(name);
return(NULL); return(NULL);
} }
memset(cur, 0, sizeof(xmlAttr)); memset(cur, 0, sizeof(xmlAttr));
...@@ -2172,7 +2171,6 @@ xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) { ...@@ -2172,7 +2171,6 @@ xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) {
cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
if (cur == NULL) { if (cur == NULL) {
xmlTreeErrMemory("building node"); xmlTreeErrMemory("building node");
xmlFree(name);
return(NULL); return(NULL);
} }
memset(cur, 0, sizeof(xmlNode)); memset(cur, 0, sizeof(xmlNode));
......
...@@ -825,7 +825,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) { ...@@ -825,7 +825,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
(const char *) &inbuf->content[reader->cur], (const char *) &inbuf->content[reader->cur],
CHUNK_SIZE, 0); CHUNK_SIZE, 0);
reader->cur += CHUNK_SIZE; reader->cur += CHUNK_SIZE;
if ((val != 0) && (reader->ctxt->wellFormed == 0)) if ((val != 0) || (reader->ctxt->wellFormed == 0))
return(-1); return(-1);
} else { } else {
s = inbuf->use - reader->cur; s = inbuf->use - reader->cur;
...@@ -833,7 +833,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) { ...@@ -833,7 +833,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
(const char *) &inbuf->content[reader->cur], (const char *) &inbuf->content[reader->cur],
s, 0); s, 0);
reader->cur += s; reader->cur += s;
if ((val != 0) && (reader->ctxt->wellFormed == 0)) if ((val != 0) || (reader->ctxt->wellFormed == 0))
return(-1); return(-1);
break; break;
} }
...@@ -866,7 +866,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) { ...@@ -866,7 +866,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
s, 1); s, 1);
reader->cur = inbuf->use; reader->cur = inbuf->use;
reader->mode = XML_TEXTREADER_DONE; reader->mode = XML_TEXTREADER_DONE;
if ((val != 0) && (reader->ctxt->wellFormed == 0)) if ((val != 0) || (reader->ctxt->wellFormed == 0))
return(-1); return(-1);
} }
} }
...@@ -1343,6 +1343,8 @@ get_next_node: ...@@ -1343,6 +1343,8 @@ get_next_node:
if (reader->mode != XML_TEXTREADER_DONE) { if (reader->mode != XML_TEXTREADER_DONE) {
val = xmlParseChunk(reader->ctxt, "", 0, 1); val = xmlParseChunk(reader->ctxt, "", 0, 1);
reader->mode = XML_TEXTREADER_DONE; reader->mode = XML_TEXTREADER_DONE;
if (val != 0)
return(-1);
} }
reader->node = NULL; reader->node = NULL;
reader->depth = -1; reader->depth = -1;
...@@ -3902,7 +3904,7 @@ xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity, char *str) { ...@@ -3902,7 +3904,7 @@ xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity, char *str) {
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt; xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private; xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private;
if (str != NULL) { if (str != NULL && reader->errorFunc) {
reader->errorFunc(reader->errorFuncArg, reader->errorFunc(reader->errorFuncArg,
str, str,
severity, severity,
...@@ -4002,6 +4004,7 @@ xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader, ...@@ -4002,6 +4004,7 @@ xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
reader->ctxt->sax->warning = xmlTextReaderWarning; reader->ctxt->sax->warning = xmlTextReaderWarning;
reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning; reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
reader->errorFunc = f; reader->errorFunc = f;
reader->sErrorFunc = NULL;
reader->errorFuncArg = arg; reader->errorFuncArg = arg;
} }
else { else {
...@@ -4031,6 +4034,7 @@ xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader, ...@@ -4031,6 +4034,7 @@ xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
xmlStructuredErrorFunc f, xmlStructuredErrorFunc f,
void *arg) { void *arg) {
if (f != NULL) { if (f != NULL) {
reader->ctxt->sax->error = NULL;
reader->ctxt->sax->serror = xmlTextReaderStructuredError; reader->ctxt->sax->serror = xmlTextReaderStructuredError;
reader->ctxt->vctxt.error = xmlTextReaderValidityError; reader->ctxt->vctxt.error = xmlTextReaderValidityError;
reader->ctxt->sax->warning = xmlTextReaderWarning; reader->ctxt->sax->warning = xmlTextReaderWarning;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment