diff --git a/CHANGES b/CHANGES
index a8ad72d..752015b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,10 @@
-CHANGES - 08/10/2005
+CHANGES - 08/16/2005
--------------------
CHANGES IN Mini-XML 2.2.3
+ - The mxmlLoad*() functions could leak a node on an error
+ (STR #27)
- The mxml_vsnprintf() function could get in an infinite
loop on a buffer overflow (STR #25)
- Added new mxmlNewCDATA() and mxmlSetCDATA() functions
diff --git a/doc/relnotes.html b/doc/relnotes.html
index dde266d..7b62276 100644
--- a/doc/relnotes.html
+++ b/doc/relnotes.html
@@ -7,6 +7,9 @@
+ - The mxmlLoad*() functions could leak a node on an
+ error (STR #27)
+
- The mxml_vsnprintf() function could get in an infinite
loop on a buffer overflow (STR #25)
diff --git a/mxml-file.c b/mxml-file.c
index 650b86a..efc685e 100644
--- a/mxml-file.c
+++ b/mxml-file.c
@@ -1453,7 +1453,11 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
if (ch == '<' && whitespace && type == MXML_TEXT)
{
- mxmlNewText(parent, whitespace, "");
+ node = mxmlNewText(parent, whitespace, "");
+
+ if (!first && node)
+ first = node;
+
whitespace = 0;
}
@@ -1521,7 +1525,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
*bufptr = '\0';
- if (!mxmlNewElement(parent, buffer))
+ if ((node = mxmlNewElement(parent, buffer)) == NULL)
{
/*
* Just print error for now...
@@ -1531,6 +1535,9 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
parent ? parent->value.element.name : "null");
break;
}
+
+ if (!first)
+ first = node;
}
else if (!strcmp(buffer, "![CDATA["))
{
@@ -1567,7 +1574,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
*bufptr = '\0';
- if (!mxmlNewElement(parent, buffer))
+ if ((node = mxmlNewElement(parent, buffer)) == NULL)
{
/*
* Print error and return...
@@ -1577,6 +1584,9 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
parent ? parent->value.element.name : "null");
goto error;
}
+
+ if (!first)
+ first = node;
}
else if (buffer[0] == '?')
{
@@ -1613,7 +1623,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
*bufptr = '\0';
- if (!(parent = mxmlNewElement(parent, buffer)))
+ if ((parent = mxmlNewElement(parent, buffer)) == NULL)
{
/*
* Print error and return...
@@ -1624,6 +1634,9 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
goto error;
}
+ if (!first)
+ first = parent;
+
if (cb)
type = (*cb)(parent);
}
@@ -1669,8 +1682,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
*bufptr = '\0';
- node = mxmlNewElement(parent, buffer);
- if (!node)
+ if ((node = mxmlNewElement(parent, buffer)) == NULL)
{
/*
* Print error and return...
@@ -1681,6 +1693,9 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
goto error;
}
+ if (!first)
+ first = node;
+
/*
* Descend into this node, setting the value type as needed...
*/
@@ -1729,9 +1744,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
* Handle open tag...
*/
- node = mxmlNewElement(parent, buffer);
-
- if (!node)
+ if ((node = mxmlNewElement(parent, buffer)) == NULL)
{
/*
* Just print error for now...
@@ -1742,6 +1755,9 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
goto error;
}
+ if (!first)
+ first = node;
+
if (isspace(ch))
ch = mxml_parse_element(node, p, &encoding, getc_cb);
else if (ch == '/')
@@ -1750,6 +1766,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
{
mxml_error("Expected > but got '%c' instead for element <%s/>!",
ch, buffer);
+ mxmlDelete(node);
goto error;
}
diff --git a/mxml-private.c b/mxml-private.c
index e9e067a..3112315 100644
--- a/mxml-private.c
+++ b/mxml-private.c
@@ -47,7 +47,7 @@ mxml_error(const char *format, /* I - Printf-style format string */
...) /* I - Additional arguments as needed */
{
va_list ap; /* Pointer to arguments */
- char *s; /* Message string */
+ char s[1024]; /* Message string */
/*
@@ -63,7 +63,7 @@ mxml_error(const char *format, /* I - Printf-style format string */
va_start(ap, format);
- s = mxml_strdupf(format, ap);
+ vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
@@ -75,12 +75,6 @@ mxml_error(const char *format, /* I - Printf-style format string */
(*mxml_error_cb)(s);
else
fprintf(stderr, "mxml: %s\n", s);
-
- /*
- * Free the string...
- */
-
- free(s);
}