[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