Skip to content

Commit

Permalink
Error out when file does not start with ?xml and the top node is NULL…
Browse files Browse the repository at this point in the history
… (Issue #256)
  • Loading branch information
michaelrsweet committed Jul 4, 2019
1 parent aec92c4 commit a084198
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 28 deletions.
29 changes: 25 additions & 4 deletions mxml-file.c
Expand Up @@ -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)) &&
Expand Down Expand Up @@ -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...
Expand Down Expand Up @@ -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!
Expand All @@ -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;
}

Expand Down Expand Up @@ -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...
Expand Down
50 changes: 26 additions & 24 deletions testmxml.c
Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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]);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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]);
Expand All @@ -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);
Expand All @@ -558,15 +560,15 @@ 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);
mxmlDelete(tree);
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);
Expand All @@ -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)
{
Expand All @@ -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...
Expand All @@ -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);

Expand All @@ -641,15 +643,15 @@ main(int argc, /* I - Number of command-line args */
* Write the file...
*/

mxmlSaveFd(tree, fd, whitespace_cb);
mxmlSaveFd(xml, fd, whitespace_cb);

close(fd);

/*
* Delete the tree...
*/

mxmlDelete(tree);
mxmlDelete(xml);
}

/*
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit a084198

Please sign in to comment.