]> granicus.if.org Git - postgis/commitdiff
Liblwgeom: Fix memory leaks
authorRaúl Marín Rodríguez <rmrodriguez@carto.com>
Fri, 9 Mar 2018 17:43:12 +0000 (17:43 +0000)
committerRaúl Marín Rodríguez <rmrodriguez@carto.com>
Fri, 9 Mar 2018 17:43:12 +0000 (17:43 +0000)
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

liblwgeom/lwalgorithm.c
liblwgeom/lwgeodetic.c
liblwgeom/lwgeom.c
liblwgeom/lwgeom_geos.c
liblwgeom/lwgeom_geos_clean.c
liblwgeom/lwlinearreferencing.c
liblwgeom/lwtree.c

index bf4c95da7970f80b9a95a5805595ffa51c50cbc0..27f3044c5ff7a04406b4daf3809bbdf842168088 100644 (file)
@@ -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);
index b137da334c24624b7d582e8516b16a8410b7027e..5af1b53ce88f6568bde9e21e5f926b8a856b2f59 100644 (file)
@@ -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) )
index eaf204bd57a3df5b1ad9c5bc7e1b39abcb862d90..9e213ae3497f412b398e068f48f4479238b64284 100644 (file)
@@ -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);
index 2c9a4fc12226a8d2f33aa666be1d7e98eb55a3a9..155da872b89052dcc0f90bd4e19db3c8d84b6102 100644 (file)
@@ -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)
 {
-       LWGEOMresult;
+       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)
index 30a52b12d1ba585b2fa3846154be375196b63502..223bbd612fd688fd4e24127fedd96d3fb399b032 100644 (file)
@@ -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
index 4306eba3aa101d926a12dffd80c278c6b7177989..a09e170f7199c5636649d40c6fefa6c832298746 100644 (file)
@@ -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) )
index 010f33bca38074b0c99b38d75f8d4aa01a5a8a6c..a7495b4e8810a060af0987674878507d5c90acc0 100644 (file)
@@ -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))
        {