[SCM] PostGIS branch stable-3.4 updated. 3.4.1-36-ga3df807e2
git at osgeo.org
git at osgeo.org
Wed Jan 31 12:58:33 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.4 has been updated
via a3df807e2782ec77ee8f5d30e91903d4290f7453 (commit)
from a5d3d35def81606e3866ba3eac51dad892520917 (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 a3df807e2782ec77ee8f5d30e91903d4290f7453
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Wed Jan 31 12:58:23 2024 -0800
Change XML parsing to use default (SAX2) parser, references #5662
diff --git a/NEWS b/NEWS
index fa3fd1e3c..9e199b1db 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ To take advantage of all SFCGAL featurs, SFCGAL 1.4.1+ is needed.
- #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)
* Bug Fixes and Enhancments *
diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index 6fe568eb6..6bdb81998 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -123,6 +123,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.
@@ -172,9 +194,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);
@@ -277,7 +300,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))
@@ -421,7 +444,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)
{
@@ -592,7 +615,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
{
@@ -603,7 +626,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
{
@@ -614,7 +637,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
{
@@ -704,7 +727,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);
@@ -712,7 +735,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);
@@ -720,7 +743,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);
@@ -754,9 +777,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
{
@@ -819,9 +842,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
{
@@ -902,44 +925,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;
@@ -1064,7 +1086,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;
@@ -1079,10 +1101,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"))
@@ -1209,14 +1232,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);
@@ -1240,14 +1264,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));
@@ -1296,7 +1321,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"))
@@ -1311,14 +1336,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);
@@ -1357,11 +1382,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"))
@@ -1375,14 +1400,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);
@@ -1406,13 +1431,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));
@@ -1461,7 +1486,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;
@@ -1474,7 +1499,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,
@@ -1522,8 +1547,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;
@@ -1536,7 +1561,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,
@@ -1572,7 +1597,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)
{
@@ -1581,7 +1606,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,
@@ -1618,7 +1643,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));
@@ -1654,7 +1679,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)
{
@@ -1663,7 +1688,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,
@@ -1700,7 +1725,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));
@@ -1735,7 +1760,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)
{
@@ -1744,7 +1769,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,
@@ -1783,7 +1808,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;
@@ -1796,7 +1821,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));
@@ -1836,10 +1861,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,
@@ -1865,7 +1890,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();
@@ -1917,8 +1942,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);
@@ -1928,50 +1957,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 75ba53833..0185587a3 100644
--- a/postgis/lwgeom_in_kml.c
+++ b/postgis/lwgeom_in_kml.c
@@ -64,6 +64,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.
@@ -88,7 +110,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);
@@ -288,7 +311,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;
@@ -404,14 +427,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);
@@ -440,14 +463,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);
@@ -491,10 +514,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;
@@ -518,16 +541,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/postgis/lwgeom_in_marc21.c b/postgis/lwgeom_in_marc21.c
index 69ba2f975..282db4d56 100644
--- a/postgis/lwgeom_in_marc21.c
+++ b/postgis/lwgeom_in_marc21.c
@@ -64,7 +64,7 @@ Datum ST_GeomFromMARC21(PG_FUNCTION_ARGS) {
xml_size = VARSIZE_ANY_EXHDR(xml_input);
xmlInitParser();
- xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
+ xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, 0);
if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL) {
xmlFreeDoc(xmldoc);
@@ -91,6 +91,26 @@ Datum ST_GeomFromMARC21(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(geom);
}
+static inline bool
+is_xml_element(xmlNodePtr xn, const char *xml_name)
+{
+ char *colon_pos, *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, xml_name) == 0;
+}
+
static int is_literal_valid(const char *literal) {
int num_dec_sep;
@@ -381,7 +401,8 @@ parse_marc21(xmlNodePtr xnode) {
* https://www.loc.gov/standards/marcxml/xml/spy/spy.html
*/
- if (xmlStrcmp(xnode->name, (xmlChar*) "record")) lwpgerror("invalid MARC21/XML document. Root element <record> expected but <%s> found.",xnode->name);
+ if (!is_xml_element(xnode, "record"))
+ lwpgerror("invalid MARC21/XML document. Root element <record> expected but <%s> found.",xnode->name);
result_type = 0;
ngeoms = 0;
@@ -395,18 +416,23 @@ parse_marc21(xmlNodePtr xnode) {
if (datafield->type != XML_ELEMENT_NODE) continue;
- if (xmlStrcmp(datafield->name, (xmlChar*) "datafield") != 0 || xmlStrcmp(xmlGetProp(datafield, (xmlChar*) "tag"),(xmlChar*) "034") != 0) continue;
+ if (!is_xml_element(datafield, "datafield") || xmlStrcmp(xmlGetProp(datafield, (xmlChar*) "tag"),(xmlChar*) "034") != 0) continue;
POSTGIS_DEBUG(3, " datafield found");
for (subfield = datafield->children; subfield != NULL; subfield = subfield->next) {
if (subfield->type != XML_ELEMENT_NODE) continue;
- if (xmlStrcmp(subfield->name, (xmlChar*) "subfield") != 0) continue;
+ if (!is_xml_element(subfield, "subfield"))
+ continue;
code = (char*) xmlGetProp(subfield, (xmlChar*) "code");
- if ((strcmp(code, "d") != 0 && strcmp(code, "e") != 0 && strcmp(code, "f") != 0 && strcmp(code, "g")) != 0) continue;
+ if ((strcmp(code, "d") != 0 &&
+ strcmp(code, "e") != 0 &&
+ strcmp(code, "f") != 0 &&
+ strcmp(code, "g")) != 0)
+ continue;
literal = (char*) xmlNodeGetContent(subfield);
@@ -437,7 +463,8 @@ parse_marc21(xmlNodePtr xnode) {
double s = parse_geo_literal(ls);
geometry_type = 0;
- if (ngeoms > 0) lwgeoms = (LWGEOM**) lwrealloc(lwgeoms, sizeof(LWGEOM*) * (ngeoms + 1));
+ if (ngeoms > 0) lwgeoms = (LWGEOM**)
+ lwrealloc(lwgeoms, sizeof(LWGEOM*) * (ngeoms + 1));
if (fabs(w - e) < 0.0000001f && fabs(n - s) < 0.0000001f) {
diff --git a/regress/core/in_gml.sql b/regress/core/in_gml.sql
index 534e79e7f..cfdb1b5a3 100644
--- a/regress/core/in_gml.sql
+++ b/regress/core/in_gml.sql
@@ -706,7 +706,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 +++++++++----
postgis/lwgeom_in_marc21.c | 39 ++++++++--
regress/core/in_gml.sql | 2 +-
5 files changed, 178 insertions(+), 98 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list