Error out when file does not start with ?xml and the top node is NULL (Issue #256)

This commit is contained in:
Michael R Sweet 2019-07-03 22:27:11 -04:00
parent aec92c493d
commit a084198be8
No known key found for this signature in database
GPG Key ID: 999559A027815955
2 changed files with 51 additions and 28 deletions

View File

@ -1416,7 +1416,17 @@ mxml_load_data(
else
type = MXML_IGNORE;
while ((ch = (*getc_cb)(p, &encoding)) != EOF)
if ((ch = (*getc_cb)(p, &encoding)) == EOF)
{
return (NULL);
}
else if (ch != '<' && !top)
{
mxml_error("XML does not start with '<?xml' (saw '%c').", ch);
return (NULL);
}
do
{
if ((ch == '<' ||
(mxml_isspace(ch) && type != MXML_OPAQUE && type != MXML_CUSTOM)) &&
@ -1575,7 +1585,12 @@ mxml_load_data(
*bufptr = '\0';
if (!strcmp(buffer, "!--"))
if (!top && !parent && buffer[0] != '?')
{
mxml_error("XML does not start with '<?xml' (saw '<%s').", buffer);
return (NULL);
}
else if (!strcmp(buffer, "!--"))
{
/*
* Gather rest of comment...
@ -1758,7 +1773,12 @@ mxml_load_data(
*bufptr = '\0';
if (!parent && first)
if (!top && !parent && strncmp(buffer, "?xml ", 5))
{
mxml_error("XML does not start with '<?xml' (saw '<%s>').", buffer);
return (NULL);
}
else if (!parent && first)
{
/*
* There can only be one root element!
@ -1782,7 +1802,7 @@ mxml_load_data(
{
(*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data);
if (!mxmlRelease(node))
if (strncmp(node->value.element.name, "?xml ", 5) && !mxmlRelease(node))
node = NULL;
}
@ -2032,6 +2052,7 @@ mxml_load_data(
goto error;
}
}
while ((ch = (*getc_cb)(p, &encoding)) != EOF);
/*
* Free the string buffer - we don't need it anymore...

View File

@ -56,7 +56,8 @@ main(int argc, /* I - Number of command-line args */
int i; /* Looping var */
FILE *fp; /* File to read */
int fd; /* File descriptor */
mxml_node_t *tree, /* XML tree */
mxml_node_t *xml, /* <?xml ...?> node */
*tree, /* Element tree */
*node; /* Node which should be in test.xml */
mxml_index_t *ind; /* XML index */
char buffer[16384]; /* Save string */
@ -84,7 +85,8 @@ main(int argc, /* I - Number of command-line args */
* Test the basic functionality...
*/
tree = mxmlNewElement(MXML_NO_PARENT, "element");
xml = mxmlNewXML("1.0");
tree = mxmlNewElement(xml, "element");
if (!tree)
{
@ -459,14 +461,14 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
mxmlDelete(tree);
mxmlDelete(xml);
/*
* Open the file/string using the default (MXML_NO_CALLBACK) callback...
*/
if (argv[1][0] == '<')
tree = mxmlLoadString(NULL, argv[1], MXML_NO_CALLBACK);
xml = mxmlLoadString(NULL, argv[1], MXML_NO_CALLBACK);
else if ((fp = fopen(argv[1], "rb")) == NULL)
{
perror(argv[1]);
@ -478,12 +480,12 @@ main(int argc, /* I - Number of command-line args */
* Read the file...
*/
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
xml = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
fclose(fp);
}
if (!tree)
if (!xml)
{
fputs("Unable to read XML file with default callback.\n", stderr);
return (1);
@ -498,7 +500,7 @@ main(int argc, /* I - Number of command-line args */
* properly...
*/
if ((node = mxmlFindPath(tree, "group/option/keyword")) == NULL)
if ((node = mxmlFindPath(xml, "group/option/keyword")) == NULL)
{
fputs("Unable to find group/option/keyword element in XML tree.\n", stderr);
mxmlDelete(tree);
@ -508,27 +510,27 @@ main(int argc, /* I - Number of command-line args */
if (node->type != MXML_TEXT)
{
fputs("No child node of group/option/keyword.\n", stderr);
mxmlSaveFile(tree, stderr, MXML_NO_CALLBACK);
mxmlDelete(tree);
mxmlSaveFile(xml, stderr, MXML_NO_CALLBACK);
mxmlDelete(xml);
return (1);
}
if ((text = mxmlGetText(node, NULL)) == NULL || strcmp(text, "InputSlot"))
{
fprintf(stderr, "Child node of group/option/value has value \"%s\" instead of \"InputSlot\".\n", text ? text : "(null)");
mxmlDelete(tree);
mxmlDelete(xml);
return (1);
}
}
mxmlDelete(tree);
mxmlDelete(xml);
/*
* Open the file...
*/
if (argv[1][0] == '<')
tree = mxmlLoadString(NULL, argv[1], type_cb);
xml = mxmlLoadString(NULL, argv[1], type_cb);
else if ((fp = fopen(argv[1], "rb")) == NULL)
{
perror(argv[1]);
@ -540,12 +542,12 @@ main(int argc, /* I - Number of command-line args */
* Read the file...
*/
tree = mxmlLoadFile(NULL, fp, type_cb);
xml = mxmlLoadFile(NULL, fp, type_cb);
fclose(fp);
}
if (!tree)
if (!xml)
{
fputs("Unable to read XML file.\n", stderr);
return (1);
@ -558,7 +560,7 @@ main(int argc, /* I - Number of command-line args */
* properly...
*/
if ((node = mxmlFindElement(tree, tree, "choice", NULL, NULL,
if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL,
MXML_DESCEND)) == NULL)
{
fputs("Unable to find first <choice> element in XML tree.\n", stderr);
@ -566,7 +568,7 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
if (!mxmlFindElement(node, tree, "choice", NULL, NULL, MXML_NO_DESCEND))
if (!mxmlFindElement(node, xml, "choice", NULL, NULL, MXML_NO_DESCEND))
{
fputs("Unable to find second <choice> element in XML tree.\n", stderr);
mxmlDelete(tree);
@ -578,13 +580,13 @@ main(int argc, /* I - Number of command-line args */
* Print the XML tree...
*/
mxmlSaveFile(tree, stdout, whitespace_cb);
mxmlSaveFile(xml, stdout, whitespace_cb);
/*
* Save the XML tree to a string and print it...
*/
if (mxmlSaveString(tree, buffer, sizeof(buffer), whitespace_cb) > 0)
if (mxmlSaveString(xml, buffer, sizeof(buffer), whitespace_cb) > 0)
{
if (argc == 3)
{
@ -598,7 +600,7 @@ main(int argc, /* I - Number of command-line args */
* Delete the tree...
*/
mxmlDelete(tree);
mxmlDelete(xml);
/*
* Read from/write to file descriptors...
@ -620,7 +622,7 @@ main(int argc, /* I - Number of command-line args */
* Read the file...
*/
tree = mxmlLoadFd(NULL, fd, type_cb);
xml = mxmlLoadFd(NULL, fd, type_cb);
close(fd);
@ -641,7 +643,7 @@ main(int argc, /* I - Number of command-line args */
* Write the file...
*/
mxmlSaveFd(tree, fd, whitespace_cb);
mxmlSaveFd(xml, fd, whitespace_cb);
close(fd);
@ -649,7 +651,7 @@ main(int argc, /* I - Number of command-line args */
* Delete the tree...
*/
mxmlDelete(tree);
mxmlDelete(xml);
}
/*
@ -692,9 +694,9 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
if (event_counts[MXML_SAX_DATA] != 60)
if (event_counts[MXML_SAX_DATA] != 61)
{
fprintf(stderr, "MXML_SAX_DATA seen %d times, expected 60 times.\n",
fprintf(stderr, "MXML_SAX_DATA seen %d times, expected 61 times.\n",
event_counts[MXML_SAX_DATA]);
return (1);
}