[postgis-tickets] r16454 - Liblwgeom: Fix memory leaks
Raul
raul at rmr.ninja
Fri Mar 9 09:43:13 PST 2018
Author: algunenano
Date: 2018-03-09 09:43:12 -0800 (Fri, 09 Mar 2018)
New Revision: 16454
Modified:
trunk/liblwgeom/lwalgorithm.c
trunk/liblwgeom/lwgeodetic.c
trunk/liblwgeom/lwgeom.c
trunk/liblwgeom/lwgeom_geos.c
trunk/liblwgeom/lwgeom_geos_clean.c
trunk/liblwgeom/lwlinearreferencing.c
trunk/liblwgeom/lwtree.c
Log:
Liblwgeom: Fix memory leaks
Closes #4043
Closes #https://github.com/postgis/postgis/pull/230
Modified: trunk/liblwgeom/lwalgorithm.c
===================================================================
--- trunk/liblwgeom/lwalgorithm.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwalgorithm.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -466,6 +466,9 @@
int cross_right = 0;
int first_cross = 0;
int this_cross = 0;
+#if POSTGIS_DEBUG_LEVEL >= 4
+ char *geom_ewkt;
+#endif
pa1 = (POINTARRAY*)l1->points;
pa2 = (POINTARRAY*)l2->points;
@@ -474,8 +477,14 @@
if ( pa1->npoints < 2 || pa2->npoints < 2 )
return LINE_NO_CROSS;
- LWDEBUGF(4, "l1 = %s", lwgeom_to_ewkt((LWGEOM*)l1));
- LWDEBUGF(4, "l2 = %s", lwgeom_to_ewkt((LWGEOM*)l2));
+#if POSTGIS_DEBUG_LEVEL >= 4
+ geom_ewkt = lwgeom_to_ewkt((LWGEOM*)l1);
+ LWDEBUGF(4, "l1 = %s", geom_ewkt);
+ lwfree(geom_ewkt);
+ geom_ewkt = lwgeom_to_ewkt((LWGEOM*)l2);
+ LWDEBUGF(4, "l2 = %s", geom_ewkt);
+ lwfree(geom_ewkt);
+#endif
/* Initialize first point of q */
q1 = getPoint2d_cp(pa2, 0);
Modified: trunk/liblwgeom/lwgeodetic.c
===================================================================
--- trunk/liblwgeom/lwgeodetic.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwgeodetic.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -307,8 +307,12 @@
static int gbox_check_poles(GBOX *gbox)
{
int rv = LW_FALSE;
+#if POSTGIS_DEBUG_LEVEL >= 4
+ char *gbox_str = gbox_to_string(gbox);
LWDEBUG(4, "checking poles");
- LWDEBUGF(4, "gbox %s", gbox_to_string(gbox));
+ LWDEBUGF(4, "gbox %s", gbox_str);
+ lwfree(gbox_str);
+#endif
/* Z axis */
if ( gbox->xmin < 0.0 && gbox->xmax > 0.0 &&
gbox->ymin < 0.0 && gbox->ymax > 0.0 )
@@ -2432,6 +2436,9 @@
GEOGRAPHIC_POINT gpt_to_test;
POINT2D pt_outside;
GBOX gbox;
+#if POSTGIS_DEBUG_LEVEL >= 4
+ char *geom_ewkt;
+#endif
gbox.flags = 0;
/* Nulls and empties don't contain anything! */
@@ -2461,8 +2468,14 @@
LWDEBUGF(4, "pt_outside POINT(%.18g %.18g)", pt_outside.x, pt_outside.y);
LWDEBUGF(4, "pt_to_test POINT(%.18g %.18g)", pt_to_test->x, pt_to_test->y);
- LWDEBUGF(4, "polygon %s", lwgeom_to_ewkt((LWGEOM*)poly));
- LWDEBUGF(4, "gbox %s", gbox_to_string(&gbox));
+#if POSTGIS_DEBUG_LEVEL >= 4
+ geom_ewkt = lwgeom_to_ewkt((LWGEOM*)poly);
+ LWDEBUGF(4, "polygon %s", geom_ewkt);
+ lwfree(geom_ewkt);
+ geom_ewkt = gbox_to_string(&gbox);
+ LWDEBUGF(4, "gbox %s", geom_ewkt);
+ lwfree(geom_ewkt);
+#endif
/* Not in outer ring? We're done! */
if ( ! ptarray_contains_point_sphere(poly->rings[0], &pt_outside, pt_to_test) )
Modified: trunk/liblwgeom/lwgeom.c
===================================================================
--- trunk/liblwgeom/lwgeom.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwgeom.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -2254,7 +2254,7 @@
lwgeom_subdivide_recursive(const LWGEOM *geom, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col)
{
const uint32_t maxdepth = 50;
- GBOX *clip = gbox_copy(lwgeom_get_bbox(geom));
+ GBOX clip, subbox1, subbox2;
uint32_t nvertices = 0;
uint32_t i, n = 0;
uint32_t split_ordinate;
@@ -2263,16 +2263,12 @@
double pivot = DBL_MAX;
double center = DBL_MAX;
LWPOLY *lwpoly = NULL;
-
- GBOX *subbox1;
- GBOX *subbox2;
LWGEOM *clipped;
- if (!clip) return 0;
+ gbox_duplicate(lwgeom_get_bbox(geom), &clip);
+ width = clip.xmax - clip.xmin;
+ height = clip.ymax - clip.ymin;
- width = clip->xmax - clip->xmin;
- height = clip->ymax - clip->ymin;
-
if ( geom->type == POLYHEDRALSURFACETYPE || geom->type == TINTYPE )
lwerror("%s: unsupported geometry type '%s'", __func__, lwtype_name(geom->type));
@@ -2289,14 +2285,14 @@
if (width == 0.0)
{
- clip->xmax += FP_TOLERANCE;
- clip->xmin -= FP_TOLERANCE;
+ clip.xmax += FP_TOLERANCE;
+ clip.xmin -= FP_TOLERANCE;
width = 2 * FP_TOLERANCE;
}
if (height == 0.0)
{
- clip->ymax += FP_TOLERANCE;
- clip->ymin -= FP_TOLERANCE;
+ clip.ymax += FP_TOLERANCE;
+ clip.ymin -= FP_TOLERANCE;
height = 2 * FP_TOLERANCE;
}
@@ -2334,9 +2330,9 @@
split_ordinate = (width > height) ? 0 : 1;
if (split_ordinate == 0)
- center = (clip->xmin + clip->xmax) / 2;
+ center = (clip.xmin + clip.xmax) / 2;
else
- center = (clip->ymin + clip->ymax) / 2;
+ center = (clip.ymin + clip.ymax) / 2;
if (geom->type == POLYGONTYPE)
{
@@ -2382,19 +2378,19 @@
}
}
- subbox1 = gbox_copy(clip);
- subbox2 = gbox_copy(clip);
+ gbox_duplicate(&clip, &subbox1);
+ gbox_duplicate(&clip, &subbox2);
if (pivot == DBL_MAX) pivot = center;
if (split_ordinate == 0)
- subbox1->xmax = subbox2->xmin = pivot;
+ subbox1.xmax = subbox2.xmin = pivot;
else
- subbox1->ymax = subbox2->ymin = pivot;
+ subbox1.ymax = subbox2.ymin = pivot;
++depth;
- clipped = lwgeom_clip_by_rect(geom, subbox1->xmin, subbox1->ymin, subbox1->xmax, subbox1->ymax);
+ clipped = lwgeom_clip_by_rect(geom, subbox1.xmin, subbox1.ymin, subbox1.xmax, subbox1.ymax);
if (clipped)
{
n += lwgeom_subdivide_recursive(clipped, maxvertices, depth, col);
@@ -2401,7 +2397,7 @@
lwgeom_free(clipped);
}
- clipped = lwgeom_clip_by_rect(geom, subbox2->xmin, subbox2->ymin, subbox2->xmax, subbox2->ymax);
+ clipped = lwgeom_clip_by_rect(geom, subbox2.xmin, subbox2.ymin, subbox2.xmax, subbox2.ymax);
if (clipped)
{
n += lwgeom_subdivide_recursive(clipped, maxvertices, depth, col);
Modified: trunk/liblwgeom/lwgeom_geos.c
===================================================================
--- trunk/liblwgeom/lwgeom_geos.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwgeom_geos.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -882,10 +882,12 @@
LWGEOM *
lwgeom_clip_by_rect(const LWGEOM *geom1, double x1, double y1, double x2, double y2)
{
- LWGEOM* result;
+ LWGEOM *result;
LWGEOM *tmp;
+ LWGEOM *envelope = (LWGEOM*)lwpoly_construct_envelope(geom1->srid, x1, y1, x2, y2);
- result = lwgeom_intersection(geom1, (LWGEOM *)lwpoly_construct_envelope(geom1->srid, x1, y1, x2, y2));
+ result = lwgeom_intersection(geom1, envelope);
+ lwgeom_free(envelope);
if (!result) return NULL;
@@ -1063,6 +1065,10 @@
uint32_t i, ngeoms;
int srid = GEOSGetSRID(geom_in);
Face** geoms;
+#if POSTGIS_DEBUG_LEVEL >= 3
+ LWGEOM *geos_geom;
+ char *geom_ewkt;
+#endif
vgeoms[0] = geom_in;
geos_result = GEOSPolygonize(vgeoms, 1);
@@ -1084,8 +1090,14 @@
ngeoms = GEOSGetNumGeometries(geos_result);
+#if POSTGIS_DEBUG_LEVEL >= 3
LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms);
- LWDEBUGF(3, "GEOSpolygonize: polygonized:%s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0)));
+ geos_geom = GEOS2LWGEOM(geos_result, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "GEOSpolygonize: polygonized:%s", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
/* No geometries in collection, early out */
if (ngeoms == 0)
Modified: trunk/liblwgeom/lwgeom_geos_clean.c
===================================================================
--- trunk/liblwgeom/lwgeom_geos_clean.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwgeom_geos_clean.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -335,6 +335,7 @@
point = LWGEOM_GEOS_getPointN(lines, 0);
if (!point) return NULL;
unioned = GEOSUnion(noded, point);
+ GEOSGeom_destroy(point);
if (!unioned)
return NULL;
else
@@ -359,6 +360,10 @@
GEOSGeom geos_cut_edges, geos_area, collapse_points;
GEOSGeometry* vgeoms[3]; /* One for area, one for cut-edges */
unsigned int nvgeoms = 0;
+#if POSTGIS_DEBUG_LEVEL >= 3
+ LWGEOM *geos_geom;
+ char *geom_ewkt;
+#endif
assert(GEOSGeomTypeId(gin) == GEOS_POLYGON || GEOSGeomTypeId(gin) == GEOS_MULTIPOLYGON);
@@ -365,7 +370,13 @@
geos_bound = GEOSBoundary(gin);
if (NULL == geos_bound) return NULL;
- LWDEBUGF(3, "Boundaries: %s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_bound, 0)));
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(geos_bound, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "Boundaries: %s", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
/* Use noded boundaries as initial "cut" edges */
@@ -399,7 +410,13 @@
return NULL;
}
- LWDEBUGF(3, "Boundaries input points %s", lwgeom_to_ewkt(GEOS2LWGEOM(pi, 0)));
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(pi, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "Boundaries input points %s", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
#ifdef LWGEOM_PROFILE_MAKEVALID
lwnotice("ST_MakeValid: extracting unique points from cut_edges");
@@ -414,7 +431,13 @@
return NULL;
}
- LWDEBUGF(3, "Boundaries output points %s", lwgeom_to_ewkt(GEOS2LWGEOM(po, 0)));
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(po, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "Boundaries output points %s", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
#ifdef LWGEOM_PROFILE_MAKEVALID
lwnotice("ST_MakeValid: find collapse points");
@@ -430,7 +453,13 @@
return NULL;
}
- LWDEBUGF(3, "Collapse points: %s", lwgeom_to_ewkt(GEOS2LWGEOM(collapse_points, 0)));
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(collapse_points, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "Collapse points: %s", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
#ifdef LWGEOM_PROFILE_MAKEVALID
lwnotice("ST_MakeValid: cleanup(1)");
@@ -441,7 +470,13 @@
}
GEOSGeom_destroy(geos_bound);
- LWDEBUGF(3, "Noded Boundaries: %s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_cut_edges, 0)));
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(geos_cut_edges, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "Noded Boundaries: %s", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
/* And use an empty geometry as initial "area" */
geos_area = GEOSGeom_createEmptyPolygon();
@@ -767,6 +802,10 @@
{
GEOSGeometry* gout;
char ret_char;
+#if POSTGIS_DEBUG_LEVEL >= 3
+ LWGEOM *geos_geom;
+ char *geom_ewkt;
+#endif
/*
* Step 2: return what we got so far if already valid
@@ -781,16 +820,28 @@
}
else if (ret_char)
{
- LWDEBUGF(3, "Geometry [%s] is valid. ", lwgeom_to_ewkt(GEOS2LWGEOM(gin, 0)));
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(gin, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
+ LWDEBUGF(3, "Geometry [%s] is valid. ", geom_ewkt);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
/* It's valid at this step, return what we have */
return GEOSGeom_clone(gin);
}
+#if POSTGIS_DEBUG_LEVEL >= 3
+ geos_geom = GEOS2LWGEOM(gin, 0);
+ geom_ewkt = lwgeom_to_ewkt(geos_geom);
LWDEBUGF(3,
"Geometry [%s] is still not valid: %s. Will try to clean up further.",
- lwgeom_to_ewkt(GEOS2LWGEOM(gin, 0)),
+ geom_ewkt,
lwgeom_geos_errmsg);
+ lwgeom_free(geos_geom);
+ lwfree(geom_ewkt);
+#endif
/*
* Step 3 : make what we got valid
Modified: trunk/liblwgeom/lwlinearreferencing.c
===================================================================
--- trunk/liblwgeom/lwlinearreferencing.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwlinearreferencing.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -557,6 +557,9 @@
double ordinate_value_p = 0.0, ordinate_value_q = 0.0;
char hasz, hasm;
char dims;
+#if POSTGIS_DEBUG_LEVEL >= 4
+ char *geom_ewkt;
+#endif
/* Null input, nothing we can do. */
if ( ! line )
@@ -576,8 +579,12 @@
to = t;
}
+#if POSTGIS_DEBUG_LEVEL >= 4
LWDEBUGF(4, "from = %g, to = %g, ordinate = %c", from, to, ordinate);
- LWDEBUGF(4, "%s", lwgeom_to_ewkt((LWGEOM*)line));
+ geom_ewkt = lwgeom_to_ewkt((LWGEOM*)line);
+ LWDEBUGF(4, "%s", geom_ewkt);
+ lwfree(geom_ewkt);
+#endif
/* Asking for an ordinate we don't have. Error. */
if ( (ordinate == 'Z' && ! hasz) || (ordinate == 'M' && ! hasm) )
Modified: trunk/liblwgeom/lwtree.c
===================================================================
--- trunk/liblwgeom/lwtree.c 2018-03-09 15:37:02 UTC (rev 16453)
+++ trunk/liblwgeom/lwtree.c 2018-03-09 17:43:12 UTC (rev 16454)
@@ -930,7 +930,13 @@
rect_tree_intersects_tree_recursive(RECT_NODE *n1, RECT_NODE *n2)
{
int i, j;
- LWDEBUGF(4,"n1 %s n2 %s", rect_node_to_str(n1), rect_node_to_str(n2));
+#if POSTGIS_DEBUG_LEVEL >= 4
+ char *n1_str = rect_node_to_str(n1);
+ char *n2_str = rect_node_to_str(n2);
+ LWDEBUGF(4,"n1 %s n2 %s", n1, n2);
+ lwfree(n1_str);
+ lwfree(n2_str);
+#endif
/* There can only be an edge intersection if the rectangles overlap */
if (rect_node_intersects(n1, n2))
{
More information about the postgis-tickets
mailing list