[postgis-tickets] [SCM] PostGIS branch master updated. 3.1.0alpha1-48-g697a9bd

git at osgeo.org git at osgeo.org
Mon Mar 30 03:12:44 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, master has been updated
       via  697a9bd99cb3ebce7ba5bcdb685f35dc18b9a591 (commit)
       via  fd8221fc4430cba613cfe902a22d0263c3108881 (commit)
      from  93bb425c61fbfcef9d830a10b61aa74305114efc (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 697a9bd99cb3ebce7ba5bcdb685f35dc18b9a591
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.
    
    Closes https://github.com/postgis/postgis/pull/550
    References #4652

diff --git a/NEWS b/NEWS
index 184a1ef..f771baf 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,7 @@ Only tickets not included in 3.1.0alpha1
   - #4651: ST_Simplify: Don't copy if nothing is removed
 
 * Bug fixes *
-  -
+  - #4652, Fix several memory related bugs in ST_GeomFromGML
 
 PostGIS 3.1.0alpha1
 2020/02/01
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 fd8221fc4430cba613cfe902a22d0263c3108881
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                         |  2 +-
 postgis/lwgeom_in_gml.c      | 58 ++++++++++++++++++++++++--------------------
 regress/core/in_gml.sql      |  3 +++
 regress/core/in_gml_expected |  1 +
 4 files changed, 37 insertions(+), 27 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list