svn commit: r244208 - stable/9/lib/libgeom

Jaakko Heinonen jh at FreeBSD.org
Fri Dec 14 11:38:16 UTC 2012


Author: jh
Date: Fri Dec 14 11:38:15 2012
New Revision: 244208
URL: http://svnweb.freebsd.org/changeset/base/244208

Log:
  MFC r242130:
  
  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.

Modified:
  stable/9/lib/libgeom/geom_xml2tree.c
Directory Properties:
  stable/9/lib/libgeom/   (props changed)

Modified: stable/9/lib/libgeom/geom_xml2tree.c
==============================================================================
--- stable/9/lib/libgeom/geom_xml2tree.c	Fri Dec 14 09:00:18 2012	(r244207)
+++ stable/9/lib/libgeom/geom_xml2tree.c	Fri Dec 14 11:38:15 2012	(r244208)
@@ -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);


More information about the svn-src-stable-9 mailing list