[postgis-tickets] [SCM] PostGIS branch stable-3.0 updated. 3.0.1-9-gb5cba66

git at osgeo.org git at osgeo.org
Mon Mar 30 03:15:31 PDT 2020


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  b5cba66de3148fd115a92666d890b97a7ddbde41 (commit)
       via  a50f6e42027eb1a19a279b597f5ff14224c7d5f4 (commit)
      from  40e2a6f3b1e177b8bc2ff077bb463867e5af0e8a (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 b5cba66de3148fd115a92666d890b97a7ddbde41
Author: Raúl Marín <git at rmr.ninja>
Date:   Fri Mar 27 20:16:18 2020 +0100

    parse_gml_curve: Fix multiple bugs
    
    - ppa was leaked when lss == 1
    - When lss > 1, was trying to copy an extra point at the end.
    
    References #4652

diff --git a/NEWS b/NEWS
index e386ded..5afd631 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ PostGIS 3.0.2
 2020/XX/XX
 
 * Bug Fixes and Enhancements *
+  - #4652, Fix several memory related bugs in ST_GeomFromGML
 
 
 
diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index aab1185..ef1840e 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -751,7 +751,7 @@ static POINTARRAY* parse_gml_pos(xmlNodePtr xnode, bool *hasz)
 	POINTARRAY *dpa;
 	char *pos, *p;
 	bool digit;
-	POINT4D pt;
+	POINT4D pt = {0, 0, 0, 0};
 
 	/* HasZ, !HasM, 1 Point */
 	dpa = ptarray_construct_empty(1, 0, 1);
@@ -817,7 +817,7 @@ static POINTARRAY* parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
 	char *poslist, *p;
 	int dim, gml_dim;
 	POINTARRAY *dpa;
-	POINT4D pt;
+	POINT4D pt = {0, 0, 0, 0};
 	bool digit;
 
 	/* Retrieve gml:srsDimension attribute if any */
@@ -859,6 +859,7 @@ static POINTARRAY* parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
 			if (gml_dim == dim)
 			{
 				ptarray_append_point(dpa, &pt, LW_FALSE);
+				pt.x = pt.y = pt.z = pt.m = 0.0;
 				gml_dim = 0;
 			}
 			else if (*(poslist+1) == '\0')
@@ -1048,7 +1049,7 @@ static LWGEOM* parse_gml_line(xmlNodePtr xnode, bool *hasz, int *root_srid)
 static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
 {
 	xmlNodePtr xa;
-	int lss, last, i;
+	size_t lss;
 	bool found=false;
 	gmlSrs srs;
 	LWGEOM *geom=NULL;
@@ -1104,37 +1105,45 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
 	/* Most common case, a single segment */
 	if (lss == 1) pa = ppa[0];
 
-	/*
-	 * "The curve segments are connected to one another, with the end point
-	 *  of each segment except the last being the start point of the next
-	 *  segment"  from  ISO 19107:2003 -> 6.3.16.1 (p43)
-	 *
-	 * So we must aggregate all the segments into a single one and avoid
-	 * to copy the redundant points
-	 */
 	if (lss > 1)
 	{
-		pa = ptarray_construct(1, 0, npoints - (lss - 1));
-		for (last = npoints = i = 0; i < lss ; i++)
+		/*
+		 * "The curve segments are connected to one another, with the end point
+		 *  of each segment except the last being the start point of the next
+		 *  segment"  from  ISO 19107:2003 -> 6.3.16.1 (p43)
+		 *
+		 * So we must aggregate all the segments into a single one and avoid
+		 * to copy the redundant points
+		 */
+		size_t cp_point_size = sizeof(POINT3D); /* All internals are done with 3D */
+		size_t final_point_size = *hasz ? sizeof(POINT3D) : sizeof(POINT2D);
+		pa = ptarray_construct(1, 0, npoints - lss + 1);
+
+		/* Copy the first linestring fully */
+		memcpy(getPoint_internal(pa, 0), getPoint_internal(ppa[0], 0), cp_point_size * (ppa[0]->npoints));
+		npoints = ppa[0]->npoints;
+		lwfree(ppa[0]);
+
+		/* For the rest of linestrings, ensure the first point matches the
+		 * last point of the previous one, and copy all points except the
+		 * first one (since it'd be repeated)
+		 */
+		for (size_t i = 1; i < lss; i++)
 		{
-			if (i + 1 == lss) last = 1;
-			/* Check if segments are not disjoints */
-			if (i > 0 && memcmp( getPoint_internal(pa, npoints),
-			                     getPoint_internal(ppa[i], 0),
-			                     *hasz ? sizeof(POINT3D) : sizeof(POINT2D)))
+			if (memcmp(getPoint_internal(pa, npoints - 1), getPoint_internal(ppa[i], 0), final_point_size))
 				gml_lwpgerror("invalid GML representation", 41);
 
-			/* Aggregate stuff */
-			memcpy(	getPoint_internal(pa, npoints),
-			        getPoint_internal(ppa[i], 0),
-			        ptarray_point_size(ppa[i]) * (ppa[i]->npoints + last));
+			memcpy(getPoint_internal(pa, npoints),
+			       getPoint_internal(ppa[i], 1),
+			       cp_point_size * (ppa[i]->npoints - 1));
 
 			npoints += ppa[i]->npoints - 1;
 			lwfree(ppa[i]);
 		}
-		lwfree(ppa);
 	}
 
+	lwfree(ppa);
+
 	parse_gml_srs(xnode, &srs);
 	if (srs.reverse_axis) pa = ptarray_flip_coordinates(pa);
 	if (srs.srid != *root_srid && *root_srid != SRID_UNKNOWN)
diff --git a/regress/core/in_gml.sql b/regress/core/in_gml.sql
index 4ff83a0..19c2f86 100644
--- a/regress/core/in_gml.sql
+++ b/regress/core/in_gml.sql
@@ -1247,3 +1247,6 @@ SELECT 'double_30', ST_AsEWKT(ST_GeomFromGML('<gml:Point><gml:pos>1 -1.23E 2</gm
 
 -- ERROR: Junk
 SELECT 'double_31', ST_AsEWKT(ST_GeomFromGML('<gml:Point><gml:pos>1 $0%@#$^%#</gml:pos></gml:Point>'));
+
+-- #4652
+SELECT '#4652', ST_AsEWKT(ST_GeomFromGML('<gml:Curve id="id-69b216c9-2c07-434d-8664-e321b3697725-0" srsDimension="2" srsName="urn:x-ogc:def:crs:EPSG:28992"> <gml:segments> <gml:LineStringSegment> <gml:posList>119675.91899999976 526436.1209999993 119676.54699999839 526439.4930000007 119676.44299999997 526439.5130000003 119676.03299999982 526439.6220000014 119675.38500000164 526439.868999999</gml:posList> </gml:LineStringSegment> <gml:LineStringSegment> <gml:posList>119675.38500000164 526439.868999999 119675.15500452081 526439.9735735222 119674.92922525379 526440.0869634049 119674.70800000057 526440.2089999989</gml:posList> </gml:LineStringSegment> <gml:LineStringSegment> <gml:posList>119674.70800000057 526440.2089999989 119674.01347910661 526440.6575801083 119673.38748824484 526441.1976901226</gml:posList> </gml:LineStringSegment> </gml:segments> </gml:Curve>',28992));
\ No newline at end of file
diff --git a/regress/core/in_gml_expected b/regress/core/in_gml_expected
index 6fa4e2d..5e0ff9a 100644
--- a/regress/core/in_gml_expected
+++ b/regress/core/in_gml_expected
@@ -432,3 +432,4 @@ ERROR:  invalid GML representation
 ERROR:  invalid GML representation
 ERROR:  invalid GML representation
 ERROR:  invalid GML representation
+#4652|SRID=28992;LINESTRING(119675.919 526436.120999999,119676.546999998 526439.493000001,119676.443 526439.513,119676.033 526439.622000001,119675.385000002 526439.868999999,119675.155004521 526439.973573522,119674.929225254 526440.086963405,119674.708000001 526440.208999999,119674.013479107 526440.657580108,119673.387488245 526441.197690123)

commit a50f6e42027eb1a19a279b597f5ff14224c7d5f4
Author: Raúl Marín <git at rmr.ninja>
Date:   Fri Mar 27 18:05:31 2020 +0100

    lwgeom_from_gml: Only calculate the bbox after the geometry has been uniformized
    
    Since the gserialization will done if (and only if necessary,
    so it's a performance win), we don't do it ourselves in the
    function

diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index c156451..aab1185 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -1883,9 +1883,6 @@ lwgeom_from_gml(const char *xml, int xml_size)
 	if ( root_srid != SRID_UNKNOWN )
 		lwgeom->srid = root_srid;
 
-	/* Should we really do this here ? */
-	lwgeom_add_bbox(lwgeom);
-
 	/* GML geometries could be either 2 or 3D and can be nested mixed.
 	 * Missing Z dimension is even tolerated inside some GML coords
 	 *

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

Summary of changes:
 NEWS                         |  1 +
 postgis/lwgeom_in_gml.c      | 58 ++++++++++++++++++++++++--------------------
 regress/core/in_gml.sql      |  3 +++
 regress/core/in_gml_expected |  1 +
 4 files changed, 37 insertions(+), 26 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list