diff options
author | jh <jh@FreeBSD.org> | 2012-10-26 12:46:33 +0000 |
---|---|---|
committer | jh <jh@FreeBSD.org> | 2012-10-26 12:46:33 +0000 |
commit | bb7ab7e9bb69ab91778e41d44c29b45f9d2eca4b (patch) | |
tree | 780551242d01543594dde96b1abcc4efd4b85fbd /lib/libgeom | |
parent | 7829c04fcae895bc54db8e99f300e73d85eb7849 (diff) | |
download | FreeBSD-src-bb7ab7e9bb69ab91778e41d44c29b45f9d2eca4b.zip FreeBSD-src-bb7ab7e9bb69ab91778e41d44c29b45f9d2eca4b.tar.gz |
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
Diffstat (limited to 'lib/libgeom')
-rw-r--r-- | lib/libgeom/geom_xml2tree.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/lib/libgeom/geom_xml2tree.c b/lib/libgeom/geom_xml2tree.c index 24315cd..02be019 100644 --- a/lib/libgeom/geom_xml2tree.c +++ b/lib/libgeom/geom_xml2tree.c @@ -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 *name, const char **attr) 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 *name, const char **attr) 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 *name, const char **attr) 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 *name, const char **attr) 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 *name) 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 *name) 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); |