From: Raúl Marín Rodríguez Date: Fri, 9 Mar 2018 17:43:12 +0000 (+0000) Subject: Liblwgeom: Fix memory leaks X-Git-Tag: 2.5.0alpha~73 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b3be4f3db2f1eb75069a57ea1f66087ccc7a338;p=postgis Liblwgeom: Fix memory leaks Closes #4043 Closes #https://github.com/postgis/postgis/pull/230 git-svn-id: http://svn.osgeo.org/postgis/trunk@16454 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index bf4c95da7..27f3044c5 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -466,6 +466,9 @@ int lwline_crossing_direction(const LWLINE *l1, const LWLINE *l2) 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 @@ int lwline_crossing_direction(const LWLINE *l1, const LWLINE *l2) 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); diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c index b137da334..5af1b53ce 100644 --- a/liblwgeom/lwgeodetic.c +++ b/liblwgeom/lwgeodetic.c @@ -307,8 +307,12 @@ gbox_centroid(const GBOX* gbox, POINT2D* out) 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 @@ int lwpoly_covers_point2d(const LWPOLY *poly, const POINT2D *pt_to_test) 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 @@ int lwpoly_covers_point2d(const LWPOLY *poly, const POINT2D *pt_to_test) 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) ) diff --git a/liblwgeom/lwgeom.c b/liblwgeom/lwgeom.c index eaf204bd5..9e213ae34 100644 --- a/liblwgeom/lwgeom.c +++ b/liblwgeom/lwgeom.c @@ -2254,7 +2254,7 @@ static int 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,15 +2263,11 @@ lwgeom_subdivide_recursive(const LWGEOM *geom, uint32_t maxvertices, uint32_t de double pivot = DBL_MAX; double center = DBL_MAX; LWPOLY *lwpoly = NULL; - - GBOX *subbox1; - GBOX *subbox2; LWGEOM *clipped; - if (!clip) return 0; - - width = clip->xmax - clip->xmin; - height = clip->ymax - clip->ymin; + gbox_duplicate(lwgeom_get_bbox(geom), &clip); + 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 @@ lwgeom_subdivide_recursive(const LWGEOM *geom, uint32_t maxvertices, uint32_t de 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 @@ lwgeom_subdivide_recursive(const LWGEOM *geom, uint32_t maxvertices, uint32_t de 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,26 +2378,26 @@ lwgeom_subdivide_recursive(const LWGEOM *geom, uint32_t maxvertices, uint32_t de } } - 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); 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); diff --git a/liblwgeom/lwgeom_geos.c b/liblwgeom/lwgeom_geos.c index 2c9a4fc12..155da872b 100644 --- a/liblwgeom/lwgeom_geos.c +++ b/liblwgeom/lwgeom_geos.c @@ -882,10 +882,12 @@ lwgeom_union(const LWGEOM* geom1, const LWGEOM* geom2) 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 @@ LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in) 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 @@ LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in) 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) diff --git a/liblwgeom/lwgeom_geos_clean.c b/liblwgeom/lwgeom_geos_clean.c index 30a52b12d..223bbd612 100644 --- a/liblwgeom/lwgeom_geos_clean.c +++ b/liblwgeom/lwgeom_geos_clean.c @@ -335,6 +335,7 @@ LWGEOM_GEOS_nodeLines(const GEOSGeometry* lines) point = LWGEOM_GEOS_getPointN(lines, 0); if (!point) return NULL; unioned = GEOSUnion(noded, point); + GEOSGeom_destroy(point); if (!unioned) return NULL; else @@ -359,13 +360,23 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) 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); 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 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) 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 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) 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 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) 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 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) } 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 @@ LWGEOM_GEOS_makeValid(const GEOSGeometry* gin) { 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 @@ LWGEOM_GEOS_makeValid(const GEOSGeometry* gin) } 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 diff --git a/liblwgeom/lwlinearreferencing.c b/liblwgeom/lwlinearreferencing.c index 4306eba3a..a09e170f7 100644 --- a/liblwgeom/lwlinearreferencing.c +++ b/liblwgeom/lwlinearreferencing.c @@ -557,6 +557,9 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do 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 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do 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) ) diff --git a/liblwgeom/lwtree.c b/liblwgeom/lwtree.c index 010f33bca..a7495b4e8 100644 --- a/liblwgeom/lwtree.c +++ b/liblwgeom/lwtree.c @@ -930,7 +930,13 @@ static int 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)) {