]> granicus.if.org Git - postgis/commitdiff
Fix yet another memory leak in lwgeom_make_valid (#2947)
authorSandro Santilli <strk@keybit.net>
Wed, 1 Oct 2014 14:36:41 +0000 (14:36 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 1 Oct 2014 14:36:41 +0000 (14:36 +0000)
The leak occurs on invalid single-component collection input.

git-svn-id: http://svn.osgeo.org/postgis/trunk@13025 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/liblwgeom_internal.h
liblwgeom/lwgeom.c
liblwgeom/lwgeom_geos_clean.c

index f029cbb07a96b2880e73408e842d5cfeab7f6c57..61a747cd5b1ce214ae9042190340fde64f4d0c71 100644 (file)
@@ -403,5 +403,6 @@ int gbox_centroid(const GBOX* gbox, POINT2D* out);
 /* Utilities */
 extern void trim_trailing_zeros(char *num);
 
+extern uint8_t MULTITYPE[NUMTYPES];
 
 #endif /* _LIBLWGEOM_INTERNAL_H */
index f57593c856b5f42bea0a60e0169a2cc94ea6b3da..ad76eeee98def0337a4d9098ce8fda211242df95 100644 (file)
@@ -261,7 +261,7 @@ LWGEOM *lwpoint_as_lwgeom(const LWPOINT *obj)
 /**
 ** Look-up for the correct MULTI* type promotion for singleton types.
 */
-static uint8_t MULTITYPE[NUMTYPES] =
+uint8_t MULTITYPE[NUMTYPES] =
 {
        0,
        MULTIPOINTTYPE,        /*  1 */
index 3e0b5af878d146498e95829df28d67d5958d9cf7..e7d91613503294a89ba0e70618f00d0b9d202970 100644 (file)
@@ -997,7 +997,7 @@ lwgeom_make_valid(LWGEOM* lwgeom_in)
        int is3d;
        GEOSGeom geosgeom;
        GEOSGeometry* geosout;
-       LWGEOM *lwgeom_out, *lwgeom_tmp;
+       LWGEOM *lwgeom_out;
 
        is3d = FLAGS_GET_Z(lwgeom_in->flags);
 
@@ -1052,12 +1052,19 @@ lwgeom_make_valid(LWGEOM* lwgeom_in)
        GEOSGeom_destroy(geosout);
 
        if ( lwgeom_is_collection(lwgeom_in) && ! lwgeom_is_collection(lwgeom_out) )
-       {
+       {{
+               LWGEOM **ogeoms = lwalloc(sizeof(LWGEOM*));
+               LWGEOM *ogeom;
                LWDEBUG(3, "lwgeom_make_valid: forcing multi");
-               lwgeom_tmp = lwgeom_as_multi(lwgeom_out);
-               lwfree(lwgeom_out); /* note: only frees the wrapper, not the content */
-               lwgeom_out = lwgeom_tmp;
-       }
+               /* NOTE: this is safe because lwgeom_out is surely not lwgeom_in or
+                * otherwise we couldn't have a collection and a non-collection */
+               assert(lwgeom_in != lwgeom_out);
+               ogeoms[0] = lwgeom_out;
+               ogeom = (LWGEOM *)lwcollection_construct(MULTITYPE[lwgeom_out->type],
+                                         lwgeom_out->srid, lwgeom_out->bbox, 1, ogeoms);
+               lwgeom_out->bbox = NULL;
+               lwgeom_out = ogeom;
+       }}
 
        lwgeom_out->srid = lwgeom_in->srid;
        return lwgeom_out;