many further little changes for OOM problems. Now seems to be getting
* SAX2.c, encoding.c, error.c, parser.c, tree.c, uri.c, xmlIO.c,
xmlreader.c, include/libxml/tree.h: many further little changes
for OOM problems. Now seems to be getting closer to "ok".
* testOOM.c: added code to intercept more errors, found more
problems with library. Changed method of flagging / counting
errors intercepted.
diff --git a/ChangeLog b/ChangeLog
index cd221a9..396acde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Jul 31 09:12:44 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+ * SAX2.c, encoding.c, error.c, parser.c, tree.c, uri.c, xmlIO.c,
+ xmlreader.c, include/libxml/tree.h: many further little changes
+ for OOM problems. Now seems to be getting closer to "ok".
+ * testOOM.c: added code to intercept more errors, found more
+ problems with library. Changed method of flagging / counting
+ errors intercepted.
+
Fri Jul 30 13:57:55 CEST 2004 Daniel Veillard <daniel@veillard.com>
* tree.c: applied a couple of patch one from Oliver Stoeneberg
diff --git a/SAX2.c b/SAX2.c
index b92b1c7..4a1c600 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -50,7 +50,7 @@
* @msg: a string to accompany the error message
*/
static void
-xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, char *msg) {
+xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg);
ctxt->errNo = XML_ERR_NO_MEMORY;
@@ -858,7 +858,7 @@
(ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
ctxt->myDoc->URL = xmlCanonicPath((const xmlChar *) ctxt->input->filename);
if (ctxt->myDoc->URL == NULL)
- ctxt->myDoc->URL = xmlStrdup((const xmlChar *) ctxt->input->filename);
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
}
}
@@ -2268,6 +2268,9 @@
lastChild->doc = ctxt->node->doc;
ctxt->nodelen = len;
ctxt->nodemem = len + 1;
+ } else {
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+ return;
}
} else {
int coalesceText = (lastChild != NULL) &&
diff --git a/encoding.c b/encoding.c
index 58cc8c1..fc768ab 100644
--- a/encoding.c
+++ b/encoding.c
@@ -1263,6 +1263,7 @@
handler = (xmlCharEncodingHandlerPtr)
xmlMalloc(sizeof(xmlCharEncodingHandler));
if (handler == NULL) {
+ xmlFree(up);
xmlGenericError(xmlGenericErrorContext,
"xmlNewCharEncodingHandler : out of memory !\n");
return(NULL);
diff --git a/error.c b/error.c
index a79e214..362851c 100644
--- a/error.c
+++ b/error.c
@@ -900,8 +900,17 @@
*/
int
xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) {
+ char *message, *file, *str1, *str2, *str3;
+
if ((from == NULL) || (to == NULL))
return(-1);
+
+ message = (char *) xmlStrdup((xmlChar *) from->message);
+ file = (char *) xmlStrdup ((xmlChar *) from->file);
+ str1 = (char *) xmlStrdup ((xmlChar *) from->str1);
+ str2 = (char *) xmlStrdup ((xmlChar *) from->str2);
+ str3 = (char *) xmlStrdup ((xmlChar *) from->str3);
+
if (to->message != NULL)
xmlFree(to->message);
if (to->file != NULL)
@@ -921,26 +930,12 @@
to->int2 = from->int2;
to->node = from->node;
to->ctxt = from->ctxt;
- if (from->message != NULL)
- to->message = (char *) xmlStrdup((xmlChar *) from->message);
- else
- to->message = NULL;
- if (from->file != NULL)
- to->file = (char *) xmlStrdup((xmlChar *) from->file);
- else
- to->file = NULL;
- if (from->str1 != NULL)
- to->str1 = (char *) xmlStrdup((xmlChar *) from->str1);
- else
- to->str1 = NULL;
- if (from->str2 != NULL)
- to->str2 = (char *) xmlStrdup((xmlChar *) from->str2);
- else
- to->str2 = NULL;
- if (from->str3 != NULL)
- to->str3 = (char *) xmlStrdup((xmlChar *) from->str3);
- else
- to->str3 = NULL;
- return(0);
+ to->message = message;
+ to->file = file;
+ to->str1 = str1;
+ to->str2 = str2;
+ to->str3 = str3;
+
+ return 0;
}
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 470151d..7615ff2 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -585,18 +585,18 @@
XMLPUBFUN int XMLCALL
xmlBufferDump (FILE *file,
xmlBufferPtr buf);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN int XMLCALL
xmlBufferAdd (xmlBufferPtr buf,
const xmlChar *str,
int len);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN int XMLCALL
xmlBufferAddHead (xmlBufferPtr buf,
const xmlChar *str,
int len);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN int XMLCALL
xmlBufferCat (xmlBufferPtr buf,
const xmlChar *str);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN int XMLCALL
xmlBufferCCat (xmlBufferPtr buf,
const char *str);
XMLPUBFUN int XMLCALL
diff --git a/parser.c b/parser.c
index 4f54794..8ecf44f 100644
--- a/parser.c
+++ b/parser.c
@@ -3474,13 +3474,16 @@
xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
}
if (len + 5 >= size) {
+ xmlChar *new_buf;
size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
+ new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ if (new_buf == NULL) {
+ xmlFree (buf);
xmlErrMemory(ctxt, NULL);
ctxt->instate = state;
return;
}
+ buf = new_buf;
}
COPY_BUF(ql,buf,len,q);
q = r;
@@ -9079,6 +9082,10 @@
ctxt->sax->setDocumentLocator(ctxt->userData,
&xmlDefaultSAXLocator);
ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
+ if (ctxt->version == NULL) {
+ xmlErrMemory(ctxt, NULL);
+ break;
+ }
if ((ctxt->sax) && (ctxt->sax->startDocument) &&
(!ctxt->disableSAX))
ctxt->sax->startDocument(ctxt->userData);
@@ -9737,8 +9744,14 @@
(ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
int base = ctxt->input->base - ctxt->input->buf->buffer->content;
int cur = ctxt->input->cur - ctxt->input->base;
+ int res;
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+ res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+ if (res < 0) {
+ ctxt->errNo = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ return (XML_PARSER_EOF);
+ }
ctxt->input->base = ctxt->input->buf->buffer->content + base;
ctxt->input->cur = ctxt->input->base + cur;
ctxt->input->end =
@@ -9897,9 +9910,15 @@
if (filename == NULL)
inputStream->filename = NULL;
- else
+ else {
inputStream->filename = (char *)
xmlCanonicPath((const xmlChar *) filename);
+ if (inputStream->filename == NULL) {
+ xmlFreeParserCtxt(ctxt);
+ xmlFreeParserInputBuffer(buf);
+ return(NULL);
+ }
+ }
inputStream->buf = buf;
inputStream->base = inputStream->buf->buffer->content;
inputStream->cur = inputStream->buf->buffer->content;
diff --git a/testOOM.c b/testOOM.c
index 717b67d..a6ee685 100644
--- a/testOOM.c
+++ b/testOOM.c
@@ -37,6 +37,8 @@
#define EXIT_OOM 2
+int error = FALSE;
+int errcount = 0;
int noent = 0;
int count = 0;
int valid = 0;
@@ -129,7 +131,7 @@
static void buffer_add_string (struct buffer *b, const char *s)
{
size_t size = strlen(s) + 1;
- int ix;
+ unsigned int ix;
for (ix=0; ix<size-1; ix++) {
if (s[ix] < 0x20)
printf ("binary data [0x%02x]?\n", (unsigned char)s[ix]);
@@ -193,22 +195,22 @@
buffer_add_string (buff, elementNames[type]);
if (type == 1) {
- s = xmlTextReaderConstName (reader);
+ s = (const char *)xmlTextReaderConstName (reader);
if (s == NULL) return FALSE;
buffer_add_string (buff, s);
while ((ret = xmlTextReaderMoveToNextAttribute (reader)) == 1) {
- s = xmlTextReaderConstName (reader);
+ s = (const char *)xmlTextReaderConstName (reader);
if (s == NULL) return FALSE;
buffer_add_string (buff, s);
buffer_add_char (buff, '=');
- s = xmlTextReaderConstValue (reader);
+ s = (const char *)xmlTextReaderConstValue (reader);
if (s == NULL) return FALSE;
buffer_add_string (buff, s);
}
if (ret == -1) return FALSE;
}
else if (type == 3) {
- s = xmlTextReaderConstValue (reader);
+ s = (const char *)xmlTextReaderConstValue (reader);
if (s == NULL) return FALSE;
buffer_add_string (buff, s);
}
@@ -224,14 +226,15 @@
};
static void
-error_func (void *data, xmlErrorPtr err)
+error_func (void *data ATTRIBUTE_UNUSED, xmlErrorPtr err)
{
- int *e = data;
+
+ errcount++;
if (err->level == XML_ERR_ERROR ||
err->level == XML_ERR_FATAL)
- *e = TRUE;
+ error = TRUE;
if (showErrs) {
- printf("line %d: %s\n", err->line, err->message);
+ printf("%3d line %d: %s\n", error, err->line, err->message);
}
}
@@ -241,7 +244,7 @@
struct file_params *p = data;
struct buffer *b;
xmlTextReaderPtr reader;
- int ret, status, first_run, error;
+ int ret, status, first_run;
if (count) {
elem = 0;
@@ -261,7 +264,8 @@
if (reader == NULL)
goto out;
- xmlTextReaderSetStructuredErrorHandler (reader, error_func, &error);
+ xmlTextReaderSetStructuredErrorHandler (reader, error_func, NULL);
+ xmlSetStructuredErrorFunc(NULL, error_func);
if (valid) {
if (xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1) == -1)
@@ -279,7 +283,7 @@
goto out;
if (error) {
- fprintf (stdout, "error handler was called but parse completed successfully\n");
+ fprintf (stdout, "error handler was called but parse completed successfully (last error #%d)\n", errcount);
return FALSE;
}
diff --git a/tree.c b/tree.c
index 253132d..295066b 100644
--- a/tree.c
+++ b/tree.c
@@ -912,12 +912,36 @@
memset(cur, 0, sizeof(xmlDtd));
cur->type = XML_DTD_NODE;
- if (name != NULL)
- cur->name = xmlStrdup(name);
- if (ExternalID != NULL)
+ if (name != NULL) {
+ cur->name = xmlStrdup(name);
+ if (cur->name == NULL) {
+ xmlTreeErrMemory("building internal subset");
+ xmlFree(cur);
+ return(NULL);
+ }
+ }
+ if (ExternalID != NULL) {
cur->ExternalID = xmlStrdup(ExternalID);
- if (SystemID != NULL)
+ if (cur->ExternalID == NULL) {
+ xmlTreeErrMemory("building internal subset");
+ if (cur->name != NULL)
+ xmlFree((char *)cur->name);
+ xmlFree(cur);
+ return(NULL);
+ }
+ }
+ if (SystemID != NULL) {
cur->SystemID = xmlStrdup(SystemID);
+ if (cur->SystemID == NULL) {
+ xmlTreeErrMemory("building internal subset");
+ if (cur->name != NULL)
+ xmlFree((char *)cur->name);
+ if (cur->ExternalID != NULL)
+ xmlFree((char *)cur->ExternalID);
+ xmlFree(cur);
+ return(NULL);
+ }
+ }
if (doc != NULL) {
doc->intSubset = cur;
cur->parent = doc;
@@ -1054,6 +1078,11 @@
cur->type = XML_DOCUMENT_NODE;
cur->version = xmlStrdup(version);
+ if (cur->version == NULL) {
+ xmlTreeErrMemory("building doc");
+ xmlFree(cur);
+ return(NULL);
+ }
cur->standalone = -1;
cur->compression = -1; /* not initialized */
cur->doc = cur;
@@ -6769,8 +6798,11 @@
*
* Add a string range to an XML buffer. if len == -1, the length of
* str is recomputed.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ * and -1 in case of internal or API error.
*/
-void
+int
xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
unsigned int needSize;
@@ -6779,34 +6811,35 @@
xmlGenericError(xmlGenericErrorContext,
"xmlBufferAdd: str == NULL\n");
#endif
- return;
+ return -1;
}
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+ if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
if (len < -1) {
#ifdef DEBUG_BUFFER
xmlGenericError(xmlGenericErrorContext,
"xmlBufferAdd: len < 0\n");
#endif
- return;
+ return -1;
}
- if (len == 0) return;
+ if (len == 0) return 0;
if (len < 0)
len = xmlStrlen(str);
- if (len <= 0) return;
+ if (len <= 0) return -1;
needSize = buf->use + len + 2;
if (needSize > buf->size){
if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer");
- return;
+ return XML_ERR_NO_MEMORY;
}
}
memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
buf->use += len;
buf->content[buf->use] = 0;
+ return 0;
}
/**
@@ -6817,38 +6850,41 @@
*
* Add a string range to the beginning of an XML buffer.
* if len == -1, the length of @str is recomputed.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ * and -1 in case of internal or API error.
*/
-void
+int
xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
unsigned int needSize;
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+ if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
if (str == NULL) {
#ifdef DEBUG_BUFFER
xmlGenericError(xmlGenericErrorContext,
"xmlBufferAddHead: str == NULL\n");
#endif
- return;
+ return -1;
}
if (len < -1) {
#ifdef DEBUG_BUFFER
xmlGenericError(xmlGenericErrorContext,
"xmlBufferAddHead: len < 0\n");
#endif
- return;
+ return -1;
}
- if (len == 0) return;
+ if (len == 0) return 0;
if (len < 0)
len = xmlStrlen(str);
- if (len <= 0) return;
+ if (len <= 0) return -1;
needSize = buf->use + len + 2;
if (needSize > buf->size){
if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer");
- return;
+ return XML_ERR_NO_MEMORY;
}
}
@@ -6856,20 +6892,24 @@
memmove(&buf->content[0], str, len * sizeof(xmlChar));
buf->use += len;
buf->content[buf->use] = 0;
+ return 0;
}
/**
* xmlBufferCat:
- * @buf: the buffer to dump
+ * @buf: the buffer to add to
* @str: the #xmlChar string
*
* Append a zero terminated string to an XML buffer.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ * and -1 in case of internal or API error.
*/
-void
+int
xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
- if (str != NULL)
- xmlBufferAdd(buf, str, -1);
+ if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
+ if (str == NULL) return -1;
+ return xmlBufferAdd(buf, str, -1);
}
/**
@@ -6878,29 +6918,33 @@
* @str: the C char string
*
* Append a zero terminated C string to an XML buffer.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ * and -1 in case of internal or API error.
*/
-void
+int
xmlBufferCCat(xmlBufferPtr buf, const char *str) {
const char *cur;
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+ if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
if (str == NULL) {
#ifdef DEBUG_BUFFER
xmlGenericError(xmlGenericErrorContext,
"xmlBufferCCat: str == NULL\n");
#endif
- return;
+ return -1;
}
for (cur = str;*cur != 0;cur++) {
if (buf->use + 10 >= buf->size) {
if (!xmlBufferResize(buf, buf->use+10)){
xmlTreeErrMemory("growing buffer");
- return;
+ return XML_ERR_NO_MEMORY;
}
}
buf->content[buf->use++] = *cur;
}
buf->content[buf->use] = 0;
+ return 0;
}
/**
diff --git a/uri.c b/uri.c
index d9dc760..10e7db6 100644
--- a/uri.c
+++ b/uri.c
@@ -1409,8 +1409,8 @@
}
path = (char *) xmlMallocAtomic(len + 1);
if (path == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParseURIPathSegments: out of memory\n");
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlParseURIPathSegments: out of memory\n");
*str = cur;
return (-1);
}
@@ -2202,7 +2202,7 @@
p = uri->path + 1;
strncpy(p, path, len + 1);
} else {
- uri->path = xmlStrdup(path);
+ uri->path = xmlStrdup(path); /* FIXME - check alloc! */
p = uri->path;
}
while (*p != '\0') {
@@ -2213,7 +2213,10 @@
#else
uri->path = (char *) xmlStrdup((const xmlChar *) path);
#endif
-
+ if (uri->path == NULL) {
+ xmlFreeURI(uri);
+ return(NULL);
+ }
ret = xmlSaveUri(uri);
xmlFreeURI(uri);
return(ret);
diff --git a/xmlIO.c b/xmlIO.c
index 56d83c1..6447935 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -2452,6 +2452,7 @@
xmlParserInputBufferPtr
xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
xmlParserInputBufferPtr ret;
+ int errcode;
if (size <= 0) return(NULL);
if (mem == NULL) return(NULL);
@@ -2461,7 +2462,11 @@
ret->context = (void *) mem;
ret->readcallback = (xmlInputReadCallback) xmlNop;
ret->closecallback = NULL;
- xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size);
+ errcode = xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size);
+ if (errcode != 0) {
+ xmlFree(ret);
+ return(NULL);
+ }
}
return(ret);
@@ -2659,6 +2664,7 @@
xmlParserInputBufferPush(xmlParserInputBufferPtr in,
int len, const char *buf) {
int nbchars = 0;
+ int ret;
if (len < 0) return(0);
if ((in == NULL) || (in->error)) return(-1);
@@ -2671,7 +2677,9 @@
if (in->raw == NULL) {
in->raw = xmlBufferCreate();
}
- xmlBufferAdd(in->raw, (const xmlChar *) buf, len);
+ ret = xmlBufferAdd(in->raw, (const xmlChar *) buf, len);
+ if (ret != 0)
+ return(-1);
/*
* convert as much as possible to the parser reading buffer.
@@ -2686,7 +2694,9 @@
in->rawconsumed += (use - in->raw->use);
} else {
nbchars = len;
- xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
+ ret = xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
+ if (ret != 0)
+ return(-1);
}
#ifdef DEBUG_INPUT
xmlGenericError(xmlGenericErrorContext,
@@ -2740,7 +2750,7 @@
if (buffree <= 0) {
xmlIOErr(XML_IO_BUFFER_FULL, NULL);
in->error = XML_IO_BUFFER_FULL;
- return(0);
+ return(-1);
}
needSize = in->buffer->use + len + 1;
@@ -2748,7 +2758,7 @@
if (!xmlBufferResize(in->buffer, needSize)){
xmlIOErrMemory("growing input buffer");
in->error = XML_ERR_NO_MEMORY;
- return(0);
+ return(-1);
}
}
buffer = (char *)&in->buffer->content[in->buffer->use];
@@ -2778,7 +2788,9 @@
if (in->raw == NULL) {
in->raw = xmlBufferCreate();
}
- xmlBufferAdd(in->raw, (const xmlChar *) buffer, len);
+ res = xmlBufferAdd(in->raw, (const xmlChar *) buffer, len);
+ if (res != 0)
+ return(-1);
/*
* convert as much as possible to the parser reading buffer.
@@ -2869,7 +2881,9 @@
if (out->conv == NULL) {
out->conv = xmlBufferCreate();
}
- xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
+ ret = xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
+ if (ret != 0)
+ return(-1);
if ((out->buffer->use < MINLEN) && (chunk == len))
goto done;
@@ -2885,7 +2899,9 @@
}
nbchars = out->conv->use;
} else {
- xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
+ ret = xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
+ if (ret != 0)
+ return(-1);
nbchars = out->buffer->use;
}
buf += chunk;
diff --git a/xmlreader.c b/xmlreader.c
index 8985bd9..b075328 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -1878,6 +1878,12 @@
ret->entNr = 0;
ret->input = input;
ret->buffer = xmlBufferCreateSize(100);
+ if (ret->buffer == NULL) {
+ xmlFree(ret);
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlNewTextReader : malloc failed\n");
+ return(NULL);
+ }
ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
if (ret->sax == NULL) {
xmlBufferFree(ret->buffer);
@@ -3908,7 +3914,8 @@
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private;
- if (str != NULL && reader->errorFunc) {
+ if (str != NULL) {
+ if (reader->errorFunc)
reader->errorFunc(reader->errorFuncArg,
str,
severity,