Author: jh
Date: Fri Oct 26 12:46:33 2012
New Revision: 242130
URL: http://svn.freebsd.org/changeset/base/242130

Log:
  Improve libgeom XML parsing error handling.
  
  - Abort parsing and return an error if we run out of memory.
  - Return EILSEQ from geom_xml2tree() for XML syntax errors.
  
  Silence on:   freebsd-geom

Modified:
  head/lib/libgeom/geom_xml2tree.c

Modified: head/lib/libgeom/geom_xml2tree.c
==============================================================================
--- head/lib/libgeom/geom_xml2tree.c    Fri Oct 26 12:41:01 2012        
(r242129)
+++ head/lib/libgeom/geom_xml2tree.c    Fri Oct 26 12:46:33 2012        
(r242130)
@@ -56,6 +56,8 @@ struct mystate {
        struct sbuf             *sbuf[20];
        struct gconf            *config;
        int                     nident;
+       XML_Parser              parser;
+       int                     error;
 };
 
 static void
@@ -85,6 +87,8 @@ StartElement(void *userData, const char 
        if (!strcmp(name, "class") && mt->class == NULL) {
                mt->class = calloc(1, sizeof *mt->class);
                if (mt->class == NULL) {
+                       mt->error = errno;
+                       XML_StopParser(mt->parser, 0);
                        warn("Cannot allocate memory during processing of '%s' "
                            "element", name);
                        return;
@@ -98,6 +102,8 @@ StartElement(void *userData, const char 
        if (!strcmp(name, "geom") && mt->geom == NULL) {
                mt->geom = calloc(1, sizeof *mt->geom);
                if (mt->geom == NULL) {
+                       mt->error = errno;
+                       XML_StopParser(mt->parser, 0);
                        warn("Cannot allocate memory during processing of '%s' "
                            "element", name);
                        return;
@@ -116,6 +122,8 @@ StartElement(void *userData, const char 
        if (!strcmp(name, "consumer") && mt->consumer == NULL) {
                mt->consumer = calloc(1, sizeof *mt->consumer);
                if (mt->consumer == NULL) {
+                       mt->error = errno;
+                       XML_StopParser(mt->parser, 0);
                        warn("Cannot allocate memory during processing of '%s' "
                            "element", name);
                        return;
@@ -137,6 +145,8 @@ StartElement(void *userData, const char 
        if (!strcmp(name, "provider") && mt->provider == NULL) {
                mt->provider = calloc(1, sizeof *mt->provider);
                if (mt->provider == NULL) {
+                       mt->error = errno;
+                       XML_StopParser(mt->parser, 0);
                        warn("Cannot allocate memory during processing of '%s' "
                            "element", name);
                        return;
@@ -180,16 +190,19 @@ EndElement(void *userData, const char *n
        char *p;
 
        mt = userData;
-       sbuf_finish(mt->sbuf[mt->level]);
-       p = strdup(sbuf_data(mt->sbuf[mt->level]));
+       p = NULL;
+       if (sbuf_finish(mt->sbuf[mt->level]) == 0)
+               p = strdup(sbuf_data(mt->sbuf[mt->level]));
+       sbuf_delete(mt->sbuf[mt->level]);
+       mt->sbuf[mt->level] = NULL;
+       mt->level--;
        if (p == NULL) {
+               mt->error = errno;
+               XML_StopParser(mt->parser, 0);
                warn("Cannot allocate memory during processing of '%s' "
                    "element", name);
                return;
        }
-       sbuf_delete(mt->sbuf[mt->level]);
-       mt->sbuf[mt->level] = NULL;
-       mt->level--;
        if (strlen(p) == 0) {
                free(p);
                p = NULL;
@@ -249,12 +262,16 @@ EndElement(void *userData, const char *n
        if (mt->config != NULL) {
                gc = calloc(1, sizeof *gc);
                if (gc == NULL) {
+                       mt->error = errno;
+                       XML_StopParser(mt->parser, 0);
                        warn("Cannot allocate memory during processing of '%s' "
                            "element", name);
                        return;
                }
                gc->lg_name = strdup(name);
                if (gc->lg_name == NULL) {
+                       mt->error = errno;
+                       XML_StopParser(mt->parser, 0);
                        warn("Cannot allocate memory during processing of '%s' "
                            "element", name);
                        return;
@@ -334,7 +351,7 @@ geom_xml2tree(struct gmesh *gmp, char *p
        struct ggeom *ge;
        struct gprovider *pr;
        struct gconsumer *co;
-       int i;
+       int error, i;
 
        memset(gmp, 0, sizeof *gmp);
        LIST_INIT(&gmp->lg_class);
@@ -347,14 +364,22 @@ geom_xml2tree(struct gmesh *gmp, char *p
                return (ENOMEM);
        }
        mt->mesh = gmp;
+       mt->parser = parser;
+       error = 0;
        XML_SetUserData(parser, mt);
        XML_SetElementHandler(parser, StartElement, EndElement);
        XML_SetCharacterDataHandler(parser, CharData);
        i = XML_Parse(parser, p, strlen(p), 1);
+       if (mt->error != 0)
+               error = mt->error;
+       else if (i != 1) {
+               error = XML_GetErrorCode(parser) == XML_ERROR_NO_MEMORY ?
+                   ENOMEM : EILSEQ;
+       }
        XML_ParserFree(parser);
-       if (i != 1) {
+       if (error != 0) {
                free(mt);
-               return (-1);
+               return (error);
        }
        gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1);
        free(mt);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to