aboutsummaryrefslogtreecommitdiff
path: root/lib/libgeom/geom_xml2tree.c
diff options
context:
space:
mode:
authorJaakko Heinonen <jh@FreeBSD.org>2012-10-26 12:46:33 +0000
committerJaakko Heinonen <jh@FreeBSD.org>2012-10-26 12:46:33 +0000
commite8f6ee4a99a4fe30cee6a34d07792ba5dc126913 (patch)
tree780551242d01543594dde96b1abcc4efd4b85fbd /lib/libgeom/geom_xml2tree.c
parent76eaf53752fd376ece3368a0eff6c8a149661344 (diff)
downloadsrc-e8f6ee4a99a4fe30cee6a34d07792ba5dc126913.tar.gz
src-e8f6ee4a99a4fe30cee6a34d07792ba5dc126913.zip
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
Notes
Notes: svn path=/head/; revision=242130
Diffstat (limited to 'lib/libgeom/geom_xml2tree.c')
-rw-r--r--lib/libgeom/geom_xml2tree.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/lib/libgeom/geom_xml2tree.c b/lib/libgeom/geom_xml2tree.c
index 24315cda8c25..02be01991c1e 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);