[SCM] PostGIS branch stable-3.0 updated. 3.0.10-15-g299ac29df

git at osgeo.org git at osgeo.org
Wed Jan 31 14:03:10 PST 2024


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, stable-3.0 has been updated
       via  299ac29df823ad904d627037bf95f8365c6a50cd (commit)
      from  a2b355af9a27987ffb9a273723d594ed7f28f325 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 299ac29df823ad904d627037bf95f8365c6a50cd
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Wed Jan 31 14:03:02 2024 -0800

    Change XML parsing to use default (SAX2) parser, references #5662

diff --git a/NEWS b/NEWS
index 26a3b195f..6c1b49e21 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ xxxx/xx/xx
  - #5646, Crash on collections with empty members (Paul Ramsey)
  - #5580, Handle empty collection components in 3d distance (Paul Ramsey)
  - #5639, ST_DFullyWithin line/poly error case (Paul Ramsey)
+ - #5662, Change XML parsers to SAX2 (Paul Ramsey)
 
 
 PostGIS 3.0.10
diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index 1a5eecf5a..efcbd6b02 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -131,6 +131,28 @@ Datum geom_from_gml(PG_FUNCTION_ARGS)
 }
 
 
+static inline bool
+is_gml_element(xmlNodePtr xn, const char *gml_name)
+{
+	char *colon_pos;
+	char *node_name;
+
+	/* Not an element node, can't do anything */
+	if (!xn || xn->type != XML_ELEMENT_NODE)
+		return false;
+
+	/* If there's a colon in the element name, */
+	/* move past it before checking for equality with */
+	/* the element name we are looking for */
+	node_name = (char*)xn->name;
+	colon_pos = strchr(node_name, ':');
+	if (colon_pos)
+		node_name = colon_pos + 1;
+
+	return strcmp(node_name, gml_name) == 0;
+}
+
+
 /**
  * Return false if current element namespace is not a GML one
  * Return true otherwise.
@@ -180,9 +202,10 @@ static bool is_gml_namespace(xmlNodePtr xnode, bool is_strict)
  * Retrieve a GML property from a node or NULL otherwise
  * Respect namespaces if presents in the node element
  */
-static xmlChar *gmlGetProp(xmlNodePtr xnode, xmlChar *prop)
+static xmlChar *gmlGetProp(xmlNodePtr xnode, const char *charProp)
 {
 	xmlChar *value;
+	xmlChar *prop = (xmlChar*)charProp;
 
 	if (!is_gml_namespace(xnode, true))
 		return xmlGetProp(xnode, prop);
@@ -285,7 +308,7 @@ static xmlNodePtr get_xlink_node(xmlNodePtr xnode)
 	for (node = xnode ; node != NULL ; node = node->parent)
 	{
 		if (node->type != XML_ELEMENT_NODE) continue;
-		node_id = gmlGetProp(node, (xmlChar *) "id");
+		node_id = gmlGetProp(node, "id");
 		if (node_id != NULL)
 		{
 			if (!xmlStrcmp(node_id, p))
@@ -432,7 +455,7 @@ static void parse_gml_srs(xmlNodePtr xnode, gmlSrs *srs)
 	char sep = ':';
 
 	node = xnode;
-	srsname = gmlGetProp(node, (xmlChar *) "srsName");
+	srsname = gmlGetProp(node, "srsName");
 	/*printf("srsname %s\n",srsname);*/
 	if (!srsname)
 	{
@@ -601,7 +624,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
 	 */
 
 	/* Retrieve separator between coordinates tuples */
-	gml_ts = gmlGetProp(xnode, (xmlChar *) "ts");
+	gml_ts = gmlGetProp(xnode, "ts");
 	if (gml_ts == NULL) ts = ' ';
 	else
 	{
@@ -612,7 +635,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
 	}
 
 	/* Retrieve separator between each coordinate */
-	gml_cs = gmlGetProp(xnode, (xmlChar *) "cs");
+	gml_cs = gmlGetProp(xnode, "cs");
 	if (gml_cs == NULL) cs = ',';
 	else
 	{
@@ -623,7 +646,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
 	}
 
 	/* Retrieve decimal separator */
-	gml_dec = gmlGetProp(xnode, (xmlChar *) "decimal");
+	gml_dec = gmlGetProp(xnode, "decimal");
 	if (gml_dec == NULL) dec = '.';
 	else
 	{
@@ -713,7 +736,7 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
 		if (xyz->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xyz, false)) continue;
 
-		if (!strcmp((char *) xyz->name, "X"))
+		if (is_gml_element(xyz, "X"))
 		{
 			if (x) gml_lwpgerror("invalid GML representation", 21);
 			c = xmlNodeGetContent(xyz);
@@ -721,7 +744,7 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
 			x = true;
 			xmlFree(c);
 		}
-		else  if (!strcmp((char *) xyz->name, "Y"))
+		else  if (is_gml_element(xyz, "Y"))
 		{
 			if (y) gml_lwpgerror("invalid GML representation", 22);
 			c = xmlNodeGetContent(xyz);
@@ -729,7 +752,7 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
 			y = true;
 			xmlFree(c);
 		}
-		else if (!strcmp((char *) xyz->name, "Z"))
+		else if (is_gml_element(xyz, "Z"))
 		{
 			if (z) gml_lwpgerror("invalid GML representation", 23);
 			c = xmlNodeGetContent(xyz);
@@ -763,9 +786,9 @@ static POINTARRAY* parse_gml_pos(xmlNodePtr xnode, bool *hasz)
 	/* HasZ, !HasM, 1 Point */
 	dpa = ptarray_construct_empty(1, 0, 1);
 
-    dimension = gmlGetProp(xnode, (xmlChar *) "srsDimension");
+    dimension = gmlGetProp(xnode, "srsDimension");
     if (dimension == NULL) /* in GML 3.0.0 it was dimension */
-        dimension = gmlGetProp(xnode, (xmlChar *) "dimension");
+        dimension = gmlGetProp(xnode, "dimension");
     if (dimension == NULL) dim = 2;	/* We assume that we are in 2D */
     else
     {
@@ -828,9 +851,9 @@ static POINTARRAY* parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
 	bool digit;
 
 	/* Retrieve gml:srsDimension attribute if any */
-	dimension = gmlGetProp(xnode, (xmlChar *) "srsDimension");
+	dimension = gmlGetProp(xnode, "srsDimension");
 	if (dimension == NULL) /* in GML 3.0.0 it was dimension */
-		dimension = gmlGetProp(xnode, (xmlChar *) "dimension");
+		dimension = gmlGetProp(xnode, "dimension");
 	if (dimension == NULL) dim = 2;	/* We assume that we are in common 2D */
 	else
 	{
@@ -910,44 +933,43 @@ static POINTARRAY* parse_gml_data(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		if (!is_gml_namespace(xa, false)) continue;
 		if (xa->name == NULL) continue;
 
-		if (!strcmp((char *) xa->name, "pos"))
+		if (is_gml_element(xa, "pos"))
 		{
 			tmp_pa = parse_gml_pos(xa, hasz);
 			if (pa == NULL) pa = tmp_pa;
 			else pa = ptarray_merge(pa, tmp_pa);
 
 		}
-		else if (!strcmp((char *) xa->name, "posList"))
+		else if (is_gml_element(xa, "posList"))
 		{
 			tmp_pa = parse_gml_poslist(xa, hasz);
 			if (pa == NULL) pa = tmp_pa;
 			else pa = ptarray_merge(pa, tmp_pa);
 
 		}
-		else if (!strcmp((char *) xa->name, "coordinates"))
+		else if (is_gml_element(xa, "coordinates"))
 		{
 			tmp_pa = parse_gml_coordinates(xa, hasz);
 			if (pa == NULL) pa = tmp_pa;
 			else pa = ptarray_merge(pa, tmp_pa);
 
 		}
-		else if (!strcmp((char *) xa->name, "coord"))
+		else if (is_gml_element(xa, "coord"))
 		{
 			tmp_pa = parse_gml_coord(xa, hasz);
 			if (pa == NULL) pa = tmp_pa;
 			else pa = ptarray_merge(pa, tmp_pa);
 
 		}
-		else if (!strcmp((char *) xa->name, "pointRep") ||
-		         !strcmp((char *) xa->name, "pointProperty"))
+		else if (is_gml_element(xa, "pointRep") ||
+		         is_gml_element(xa, "pointProperty"))
 		{
-
 			found = false;
 			for (xb = xa->children ; xb != NULL ; xb = xb->next)
 			{
 				if (xb->type != XML_ELEMENT_NODE) continue;
 				if (!is_gml_namespace(xb, false)) continue;
-				if (!strcmp((char *) xb->name, "Point"))
+				if (is_gml_element(xb, "Point"))
 				{
 					found = true;
 					break;
@@ -1072,7 +1094,7 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "segments"))
+		if (is_gml_element(xa, "segments"))
 		{
 			found = true;
 			break;
@@ -1087,10 +1109,11 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "LineStringSegment")) continue;
+
+		if (!is_gml_element(xa, "LineStringSegment")) continue;
 
 		/* GML SF is restricted to linear interpolation  */
-		interpolation = gmlGetProp(xa, (xmlChar *) "interpolation");
+		interpolation = gmlGetProp(xa, "interpolation");
 		if (interpolation != NULL)
 		{
 			if (strcmp((char *) interpolation, "linear"))
@@ -1217,14 +1240,15 @@ static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* Polygon/exterior        -> GML 3.1.1 */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if  (strcmp((char *) xa->name, "outerBoundaryIs") &&
-		        strcmp((char *) xa->name, "exterior")) continue;
+		if (!(is_gml_element(xa, "outerBoundaryIs") ||
+		      is_gml_element(xa, "exterior")))
+			continue;
 
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 			if (xb->type != XML_ELEMENT_NODE) continue;
 			if (!is_gml_namespace(xb, false)) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_gml_element(xb, "LinearRing")) continue;
 
 			ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
 			ppa[0] = parse_gml_data(xb->children, hasz, root_srid);
@@ -1248,14 +1272,15 @@ static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* Polygon/interior        -> GML 3.1.1 */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if  (strcmp((char *) xa->name, "innerBoundaryIs") &&
-		        strcmp((char *) xa->name, "interior")) continue;
+		if (!(is_gml_element(xa, "innerBoundaryIs") ||
+		      is_gml_element(xa, "interior")))
+			continue;
 
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 			if (xb->type != XML_ELEMENT_NODE) continue;
 			if (!is_gml_namespace(xb, false)) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_gml_element(xb, "LinearRing")) continue;
 
 			ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa,
 			                               sizeof(POINTARRAY*) * (ring + 1));
@@ -1304,7 +1329,7 @@ static LWGEOM* parse_gml_triangle(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	/* GML SF is restricted to planar interpolation
 	       NOTA: I know Triangle is not part of SF, but
 	       we have to be consistent with other surfaces */
-	interpolation = gmlGetProp(xnode, (xmlChar *) "interpolation");
+	interpolation = gmlGetProp(xnode, "interpolation");
 	if (interpolation != NULL)
 	{
 		if (strcmp((char *) interpolation, "planar"))
@@ -1319,14 +1344,14 @@ static LWGEOM* parse_gml_triangle(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* Triangle/exterior */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "exterior")) continue;
+		if (!is_gml_element(xa, "exterior")) continue;
 
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 			/* Triangle/exterior/LinearRing */
 			if (xb->type != XML_ELEMENT_NODE) continue;
 			if (!is_gml_namespace(xb, false)) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_gml_element(xb, "LinearRing")) continue;
 
 			pa = (POINTARRAY*) lwalloc(sizeof(POINTARRAY));
 			pa = parse_gml_data(xb->children, hasz, root_srid);
@@ -1365,11 +1390,11 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	gmlSrs srs;
 
 	/* PolygonPatch */
-	if (strcmp((char *) xnode->name, "PolygonPatch"))
+	if (!is_gml_element(xnode, "PolygonPatch"))
 		gml_lwpgerror("invalid GML representation", 48);
 
 	/* GML SF is restricted to planar interpolation  */
-	interpolation = gmlGetProp(xnode, (xmlChar *) "interpolation");
+	interpolation = gmlGetProp(xnode, "interpolation");
 	if (interpolation != NULL)
 	{
 		if (strcmp((char *) interpolation, "planar"))
@@ -1383,14 +1408,14 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	for (xa = xnode->children ; xa != NULL ; xa = xa->next)
 	{
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "exterior")) continue;
+		if (!is_gml_element(xa, "exterior")) continue;
 
 		/* PolygonPatch/exterior/LinearRing */
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 			if (xb->type != XML_ELEMENT_NODE) continue;
 			if (!is_gml_namespace(xb, false)) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_gml_element(xb, "LinearRing")) continue;
 
 			ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
 			ppa[0] = parse_gml_data(xb->children, hasz, root_srid);
@@ -1414,13 +1439,13 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "interior")) continue;
+		if (!is_gml_element(xa, "interior")) continue;
 
 		/* PolygonPatch/interior/LinearRing */
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 			if (xb->type != XML_ELEMENT_NODE) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_gml_element(xb, "LinearRing")) continue;
 
 			ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa,
 			                               sizeof(POINTARRAY*) * (ring + 1));
@@ -1469,7 +1494,7 @@ static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "patches"))
+		if (is_gml_element(xa, "patches"))
 		{
 			found = true;
 			break;
@@ -1482,7 +1507,7 @@ static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "PolygonPatch")) continue;
+		if (!is_gml_element(xa, "PolygonPatch")) continue;
 		patch++;
 
 		/* SQL/MM define ST_CurvePolygon as a single patch only,
@@ -1530,8 +1555,8 @@ static LWGEOM* parse_gml_tin(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "patches") ||
-		        !strcmp((char *) xa->name, "trianglePatches"))
+		if (is_gml_element(xa, "patches") ||
+		    is_gml_element(xa, "trianglePatches"))
 		{
 			found = true;
 			break;
@@ -1544,7 +1569,7 @@ static LWGEOM* parse_gml_tin(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "Triangle")) continue;
+		if (!is_gml_element(xa, "Triangle")) continue;
 
 		if (xa->children != NULL)
 			geom = (LWGEOM*) lwtin_add_lwtriangle((LWTIN *) geom,
@@ -1580,7 +1605,7 @@ static LWGEOM* parse_gml_mpoint(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* MultiPoint/pointMember */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "pointMembers"))
+		if (is_gml_element(xa, "pointMembers"))
 		{
 			for (xb = xa->children ; xb != NULL ; xb = xb->next)
 			{
@@ -1589,7 +1614,7 @@ static LWGEOM* parse_gml_mpoint(xmlNodePtr xnode, bool *hasz, int *root_srid)
 				    (LWPOINT*)parse_gml(xb, hasz, root_srid));
 			}
 		}
-		else if (!strcmp((char *) xa->name, "pointMember"))
+		else if (is_gml_element(xa, "pointMember"))
 		{
 			if (xa->children != NULL)
 				geom = (LWGEOM*)lwmpoint_add_lwpoint((LWMPOINT*)geom,
@@ -1626,7 +1651,7 @@ static LWGEOM* parse_gml_mline(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* MultiLineString/lineStringMember */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "lineStringMember")) continue;
+		if (!is_gml_element(xa, "lineStringMember")) continue;
 		if (xa->children != NULL)
 			geom = (LWGEOM*)lwmline_add_lwline((LWMLINE*)geom,
 			                                   (LWLINE*)parse_gml(xa->children, hasz, root_srid));
@@ -1662,7 +1687,7 @@ static LWGEOM* parse_gml_mcurve(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* MultiCurve/curveMember */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "curveMembers"))
+		if (is_gml_element(xa, "curveMembers"))
 		{
 			for (xb = xa->children ; xb != NULL ; xb = xb->next)
 			{
@@ -1671,7 +1696,7 @@ static LWGEOM* parse_gml_mcurve(xmlNodePtr xnode, bool *hasz, int *root_srid)
 				                                       (LWLINE*)parse_gml(xb, hasz, root_srid));
 			}
 		}
-		else if (!strcmp((char *) xa->name, "curveMember"))
+		else if (is_gml_element(xa, "curveMember"))
 		{
 			if (xa->children != NULL)
 				geom = (LWGEOM*)lwmline_add_lwline((LWMLINE*)geom,
@@ -1708,7 +1733,7 @@ static LWGEOM* parse_gml_mpoly(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* MultiPolygon/polygonMember */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "polygonMember")) continue;
+		if (!is_gml_element(xa, "polygonMember")) continue;
 		if (xa->children != NULL)
 			geom = (LWGEOM*)lwmpoly_add_lwpoly((LWMPOLY*)geom,
 			                                   (LWPOLY*)parse_gml(xa->children, hasz, root_srid));
@@ -1743,7 +1768,7 @@ static LWGEOM* parse_gml_msurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* MultiSurface/surfaceMember */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "surfaceMembers"))
+		if (is_gml_element(xa, "surfaceMembers"))
 		{
 			for (xb = xa->children ; xb != NULL ; xb = xb->next)
 			{
@@ -1752,7 +1777,7 @@ static LWGEOM* parse_gml_msurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
 				                                       (LWPOLY*)parse_gml(xb, hasz, root_srid));
 			}
 		}
-		else if (!strcmp((char *) xa->name, "surfaceMember"))
+		else if (is_gml_element(xa, "surfaceMember"))
 		{
 			if (xa->children != NULL)
 				geom = (LWGEOM*)lwmpoly_add_lwpoly((LWMPOLY*)geom,
@@ -1791,7 +1816,7 @@ static LWGEOM* parse_gml_psurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	{
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (!strcmp((char *) xa->name, "polygonPatches"))
+		if (is_gml_element(xa, "polygonPatches"))
 		{
 			found = true;
 			break;
@@ -1804,7 +1829,7 @@ static LWGEOM* parse_gml_psurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		/* PolyhedralSurface/polygonPatches/PolygonPatch */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_gml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "PolygonPatch")) continue;
+		if (!is_gml_element(xa, "PolygonPatch")) continue;
 
 		geom = (LWGEOM*)lwpsurface_add_lwpoly((LWPSURFACE*)geom,
 		                                      (LWPOLY*)parse_gml_patch(xa, hasz, root_srid));
@@ -1844,10 +1869,10 @@ static LWGEOM* parse_gml_coll(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		 * polygonMember are parts of geometryMember
 		 * substitution group
 		 */
-		if (	   !strcmp((char *) xa->name, "pointMember")
-		        || !strcmp((char *) xa->name, "lineStringMember")
-		        || !strcmp((char *) xa->name, "polygonMember")
-		        || !strcmp((char *) xa->name, "geometryMember"))
+		if (	   is_gml_element(xa, "pointMember")
+		        || is_gml_element(xa, "lineStringMember")
+		        || is_gml_element(xa, "polygonMember")
+		        || is_gml_element(xa, "geometryMember"))
 		{
 			if (xa->children == NULL) break;
 			geom = (LWGEOM*)lwcollection_add_lwgeom((LWCOLLECTION *)geom,
@@ -1873,7 +1898,7 @@ lwgeom_from_gml(const char *xml, int xml_size)
 	/* Begin to Parse XML doc */
 	xmlInitParser();
 
-	xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
+	xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, 0);
 	if (!xmldoc)
 	{
 		xmlCleanupParser();
@@ -1925,8 +1950,12 @@ static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	xmlNodePtr xa = xnode;
 	gmlSrs srs;
 
-	while (xa != NULL && (xa->type != XML_ELEMENT_NODE
-	                      || !is_gml_namespace(xa, false))) xa = xa->next;
+	/* Scroll forward to the root node */
+	while (xa != NULL &&
+	      (xa->type != XML_ELEMENT_NODE || !is_gml_namespace(xa, false)))
+	{
+		xa = xa->next;
+	}
 
 	if (xa == NULL) gml_lwpgerror("invalid GML representation", 55);
 
@@ -1936,50 +1965,50 @@ static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		*root_srid = srs.srid;
 	}
 
-	if (!strcmp((char *) xa->name, "Point"))
+	if (is_gml_element(xa, "Point"))
 		return parse_gml_point(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "LineString"))
+	if (is_gml_element(xa, "LineString"))
 		return parse_gml_line(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "Curve"))
+	if (is_gml_element(xa, "Curve"))
 		return parse_gml_curve(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "LinearRing"))
+	if (is_gml_element(xa, "LinearRing"))
 		return parse_gml_linearring(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "Polygon"))
+	if (is_gml_element(xa, "Polygon"))
 		return parse_gml_polygon(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "Triangle"))
+	if (is_gml_element(xa, "Triangle"))
 		return parse_gml_triangle(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "Surface"))
+	if (is_gml_element(xa, "Surface"))
 		return parse_gml_surface(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "MultiPoint"))
+	if (is_gml_element(xa, "MultiPoint"))
 		return parse_gml_mpoint(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "MultiLineString"))
+	if (is_gml_element(xa, "MultiLineString"))
 		return parse_gml_mline(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "MultiCurve"))
+	if (is_gml_element(xa, "MultiCurve"))
 		return parse_gml_mcurve(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "MultiPolygon"))
+	if (is_gml_element(xa, "MultiPolygon"))
 		return parse_gml_mpoly(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "MultiSurface"))
+	if (is_gml_element(xa, "MultiSurface"))
 		return parse_gml_msurface(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "PolyhedralSurface"))
+	if (is_gml_element(xa, "PolyhedralSurface"))
 		return parse_gml_psurface(xa, hasz, root_srid);
 
-	if ((!strcmp((char *) xa->name, "Tin")) ||
-	        !strcmp((char *) xa->name, "TriangulatedSurface" ))
+	if (is_gml_element(xa, "Tin") ||
+	    is_gml_element(xa, "TriangulatedSurface"))
 		return parse_gml_tin(xa, hasz, root_srid);
 
-	if (!strcmp((char *) xa->name, "MultiGeometry"))
+	if (is_gml_element(xa, "MultiGeometry"))
 		return parse_gml_coll(xa, hasz, root_srid);
 
 	gml_lwpgerror("invalid GML representation", 56);
diff --git a/postgis/lwgeom_in_kml.c b/postgis/lwgeom_in_kml.c
index 068891819..ef32ce5f4 100644
--- a/postgis/lwgeom_in_kml.c
+++ b/postgis/lwgeom_in_kml.c
@@ -66,6 +66,28 @@ static LWGEOM* parse_kml(xmlNodePtr xnode, bool *hasz);
 #define KML_NS		((char *) "http://www.opengis.net/kml/2.2")
 
 
+static inline bool
+is_kml_element(xmlNodePtr xn, const char *kml_name)
+{
+	char *colon_pos;
+	char *node_name;
+
+	/* Not an element node, can't do anything */
+	if (!xn || xn->type != XML_ELEMENT_NODE)
+		return false;
+
+	/* If there's a colon in the element name, */
+	/* move past it before checking for equality with */
+	/* the element name we are looking for */
+	node_name = (char*)xn->name;
+	colon_pos = strchr(node_name, ':');
+	if (colon_pos)
+		node_name = colon_pos + 1;
+
+	return strcmp(node_name, kml_name) == 0;
+}
+
+
 /**
  * Ability to parse KML geometry fragment and to return an LWGEOM
  * or an error message.
@@ -90,7 +112,8 @@ Datum geom_from_kml(PG_FUNCTION_ARGS)
 
 	/* Begin to Parse XML doc */
 	xmlInitParser();
-	xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
+	xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, 0);
+	// xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
 	if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL)
 	{
 		xmlFreeDoc(xmldoc);
@@ -292,7 +315,7 @@ static POINTARRAY* parse_kml_coordinates(xmlNodePtr xnode, bool *hasz)
 	{
 		if (xnode->type != XML_ELEMENT_NODE) continue;
 		if (!is_kml_namespace(xnode, false)) continue;
-		if (strcmp((char *) xnode->name, "coordinates")) continue;
+		if (!is_kml_element(xnode, "coordinates")) continue;
 
 		found = true;
 		break;
@@ -408,14 +431,14 @@ static LWGEOM* parse_kml_polygon(xmlNodePtr xnode, bool *hasz)
 		/* Polygon/outerBoundaryIs */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_kml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "outerBoundaryIs")) continue;
+		if (!is_kml_element(xa, "outerBoundaryIs")) continue;
 
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 
 			if (xb->type != XML_ELEMENT_NODE) continue;
 			if (!is_kml_namespace(xb, false)) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_kml_element(xb, "LinearRing")) continue;
 
 			ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
 			ppa[0] = parse_kml_coordinates(xb->children, hasz);
@@ -444,14 +467,14 @@ static LWGEOM* parse_kml_polygon(xmlNodePtr xnode, bool *hasz)
 		/* Polygon/innerBoundaryIs */
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_kml_namespace(xa, false)) continue;
-		if (strcmp((char *) xa->name, "innerBoundaryIs")) continue;
+		if (!is_kml_element(xa, "innerBoundaryIs")) continue;
 
 		for (xb = xa->children ; xb != NULL ; xb = xb->next)
 		{
 
 			if (xb->type != XML_ELEMENT_NODE) continue;
 			if (!is_kml_namespace(xb, false)) continue;
-			if (strcmp((char *) xb->name, "LinearRing")) continue;
+			if (!is_kml_element(xb, "LinearRing")) continue;
 
 			ppa = (POINTARRAY**) lwrealloc(ppa, sizeof(POINTARRAY*) * (ring + 1));
 			ppa[ring] = parse_kml_coordinates(xb->children, hasz);
@@ -495,10 +518,10 @@ static LWGEOM* parse_kml_multi(xmlNodePtr xnode, bool *hasz)
 		if (xa->type != XML_ELEMENT_NODE) continue;
 		if (!is_kml_namespace(xa, false)) continue;
 
-		if (	   !strcmp((char *) xa->name, "Point")
-		        || !strcmp((char *) xa->name, "LineString")
-		        || !strcmp((char *) xa->name, "Polygon")
-		        || !strcmp((char *) xa->name, "MultiGeometry"))
+		if (	   is_kml_element(xa, "Point")
+		        || is_kml_element(xa, "LineString")
+		        || is_kml_element(xa, "Polygon")
+		        || is_kml_element(xa, "MultiGeometry"))
 		{
 
 			if (xa->children == NULL) break;
@@ -522,16 +545,16 @@ static LWGEOM* parse_kml(xmlNodePtr xnode, bool *hasz)
 
 	if (xa == NULL) lwpgerror("invalid KML representation");
 
-	if (!strcmp((char *) xa->name, "Point"))
+	if (is_kml_element(xa, "Point"))
 		return parse_kml_point(xa, hasz);
 
-	if (!strcmp((char *) xa->name, "LineString"))
+	if (is_kml_element(xa, "LineString"))
 		return parse_kml_line(xa, hasz);
 
-	if (!strcmp((char *) xa->name, "Polygon"))
+	if (is_kml_element(xa, "Polygon"))
 		return parse_kml_polygon(xa, hasz);
 
-	if (!strcmp((char *) xa->name, "MultiGeometry"))
+	if (is_kml_element(xa, "MultiGeometry"))
 		return parse_kml_multi(xa, hasz);
 
 	lwpgerror("invalid KML representation");
diff --git a/regress/core/in_gml.sql b/regress/core/in_gml.sql
index 19c2f86c8..0cba98f6c 100644
--- a/regress/core/in_gml.sql
+++ b/regress/core/in_gml.sql
@@ -666,7 +666,7 @@ SELECT 'ns_8', ST_AsEWKT(ST_GeomFromGML('<gml:Point gml:srsName="EPSG:4326" xmln
 SELECT 'ns_9', ST_AsEWKT(ST_GeomFromGML('<gml:Point gml:srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml/3.2"><gml:coordinates>1,2</gml:coordinates></gml:Point>'));
 
 -- Attribute with explicit prefix but unqualified namespace
-SELECT 'ns_10', ST_AsEWKT(ST_GeomFromGML('<gml:Point foo:srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>1,2</gml:coordinates></gml:Point>'));
+SELECT 'ns_10', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>1,2</gml:coordinates></gml:Point>'));
 
 -- Ignore other namespace attribute
 SELECT 'ns_11', ST_AsEWKT(ST_GeomFromGML('<gml:Point foo:srsName="EPSG:4326" xmlns:foo="http://foo.net" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>1,2</gml:coordinates><foo:coordinates>3,4</foo:coordinates></gml:Point>'));

-----------------------------------------------------------------------

Summary of changes:
 NEWS                    |   1 +
 postgis/lwgeom_in_gml.c | 183 ++++++++++++++++++++++++++++--------------------
 postgis/lwgeom_in_kml.c |  51 ++++++++++----
 regress/core/in_gml.sql |   2 +-
 4 files changed, 145 insertions(+), 92 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list