]> granicus.if.org Git - postgis/commitdiff
Remove memory leaks when a parse error kicks out in WKT (#1102)
authorPaul Ramsey <pramsey@cleverelephant.ca>
Mon, 4 Jul 2011 22:51:37 +0000 (22:51 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Mon, 4 Jul 2011 22:51:37 +0000 (22:51 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7587 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/cunit/cu_in_wkt.c
liblwgeom/lwgeom.c
liblwgeom/lwin_wkt.c
liblwgeom/ptarray.c

index a24cdca059c22f2821fe58cbee560c68069a37b5..fc6c14fc7dbc76b564f3afd56b21aaab93da8627 100644 (file)
@@ -124,8 +124,14 @@ static void test_wkt_in_linestring(void)
        s = "LINESTRING ZM EMPTY";
        r = cu_wkt_in(s, WKT_ISO);
        CU_ASSERT_STRING_EQUAL(r,s);
+       lwfree(r);
+
+       s = "LINESTRING Z (0 0 0 1, 0 1 0 1)";
+       r = cu_wkt_in(s, WKT_EXTENDED);
+       CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
        //printf("\nIN:  %s\nOUT: %s\n",s,r);
        lwfree(r);
+       
 }
 
 static void test_wkt_in_polygon(void)
@@ -133,6 +139,16 @@ static void test_wkt_in_polygon(void)
        s = "POLYGON((0 0,0 1,1 1,0 0))";
        r = cu_wkt_in(s, WKT_SFSQL);
        CU_ASSERT_STRING_EQUAL(r,s);
+       lwfree(r);
+
+       s = "POLYGON Z ((0 0,0 10,10 10,10 0,0 0),(1 1 1,1 2 1,2 2 1,2 1 1,1 1 1))";
+       r = cu_wkt_in(s, WKT_SFSQL);
+       CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
+       lwfree(r);
+
+       s = "POLYGON Z ((0 0,0 10,10 10,10 0,0 0),(1 1,1 2,2 2,2 1,1 1))";
+       r = cu_wkt_in(s, WKT_SFSQL);
+       CU_ASSERT_STRING_EQUAL(r,"can not mix dimensionality in a geometry");
        //printf("\nIN:  %s\nOUT: %s\n",s,r);
        lwfree(r);
 }
@@ -253,6 +269,20 @@ static void test_wkt_in_multicurve(void)
 
 static void test_wkt_in_multisurface(void)
 {
+       s = "SRID=4326;MULTICURVE(COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1)))";
+       r = cu_wkt_in(s, WKT_EXTENDED);
+       CU_ASSERT_STRING_EQUAL(r,s);
+       //printf("\nIN:  %s\nOUT: %s\n",s,r);
+       lwfree(r);
+}
+
+static void test_wkt_in_tin(void)
+{
+       s = "TIN(((0 1 2,3 4 5,6 7 8,0 1 2)),((0 1 2,3 4 5,6 7 8,9 10 11,0 1 2)))";
+       r = cu_wkt_in(s, WKT_EXTENDED);
+       CU_ASSERT_STRING_EQUAL(r,"triangle must have exactly 4 points");
+       //printf("\nIN:  %s\nOUT: %s\n",s,r);
+       lwfree(r);
 }
 
 static void test_wkt_in_polyhedralsurface(void)
@@ -305,6 +335,7 @@ CU_TestInfo wkt_in_tests[] =
        PG_TEST(test_wkt_in_curvpolygon),
        PG_TEST(test_wkt_in_multicurve),
        PG_TEST(test_wkt_in_multisurface),
+       PG_TEST(test_wkt_in_tin),
        PG_TEST(test_wkt_in_polyhedralsurface),
        PG_TEST(test_wkt_in_errlocation),
        CU_TEST_INFO_NULL
index db93b441ce9cd8d751ea23aea30ff56685f5efec..5cee1b25c8f0f70a2df800573be446a6de013faa 100644 (file)
@@ -1264,6 +1264,8 @@ void lwgeom_free(LWGEOM *lwgeom)
 
        /* There's nothing here to free... */
        if( ! lwgeom ) return;
+
+       LWDEBUGF(5,"freeing a %s",lwtype_name(lwgeom->type));
        
        switch (lwgeom->type)
        {
index 561638b826de04f5861376ac8ffb1912be27faab..882050b20d7f9048f727d0b8044a65dd3eb4eb2d 100644 (file)
@@ -281,6 +281,7 @@ LWGEOM* wkt_parser_point_new(POINTARRAY *pa, char *dimensionality)
        /* If the number of dimensions is not consistent, we have a problem. */
        if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
@@ -288,6 +289,7 @@ LWGEOM* wkt_parser_point_new(POINTARRAY *pa, char *dimensionality)
        /* Only one point allowed in our point array! */        
        if( pa->npoints != 1 )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_LESSPOINTS);
                return NULL;
        }               
@@ -313,6 +315,7 @@ LWGEOM* wkt_parser_linestring_new(POINTARRAY *pa, char *dimensionality)
        /* If the number of dimensions is not consistent, we have a problem. */
        if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
@@ -320,6 +323,7 @@ LWGEOM* wkt_parser_linestring_new(POINTARRAY *pa, char *dimensionality)
        /* Apply check for not enough points, if requested. */  
        if( (global_parser_result.parser_check_flags & PARSER_CHECK_MINPOINTS) && (pa->npoints < 2) )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
                return NULL;
        }
@@ -345,6 +349,7 @@ LWGEOM* wkt_parser_circularstring_new(POINTARRAY *pa, char *dimensionality)
        /* If the number of dimensions is not consistent, we have a problem. */
        if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
@@ -352,6 +357,7 @@ LWGEOM* wkt_parser_circularstring_new(POINTARRAY *pa, char *dimensionality)
        /* Apply check for not enough points, if requested. */  
        if( (global_parser_result.parser_check_flags & PARSER_CHECK_MINPOINTS) && (pa->npoints < 3) )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
                return NULL;
        }       
@@ -359,6 +365,7 @@ LWGEOM* wkt_parser_circularstring_new(POINTARRAY *pa, char *dimensionality)
        /* Apply check for odd number of points, if requested. */       
        if( (global_parser_result.parser_check_flags & PARSER_CHECK_ODD) && ((pa->npoints % 2) == 0) )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_ODDPOINTS);
                return NULL;
        }
@@ -378,6 +385,7 @@ LWGEOM* wkt_parser_triangle_new(POINTARRAY *pa, char *dimensionality)
        /* If the number of dimensions is not consistent, we have a problem. */
        if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
@@ -385,6 +393,7 @@ LWGEOM* wkt_parser_triangle_new(POINTARRAY *pa, char *dimensionality)
        /* Triangles need four points. */       
        if( (pa->npoints != 4) )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_TRIANGLEPOINTS);
                return NULL;
        }       
@@ -392,6 +401,7 @@ LWGEOM* wkt_parser_triangle_new(POINTARRAY *pa, char *dimensionality)
        /* Triangles need closure. */   
        if( ! ptarray_isclosed(pa) )
        {
+               ptarray_free(pa);
                SET_PARSER_ERROR(PARSER_ERROR_UNCLOSED);
                return NULL;
        }       
@@ -438,6 +448,8 @@ LWGEOM* wkt_parser_polygon_add_ring(LWGEOM *poly, POINTARRAY *pa, char dimcheck)
        /* Rings must agree on dimensionality */
        if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(pa->flags) )
        {
+               ptarray_free(pa);
+               lwgeom_free(poly);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
@@ -445,6 +457,8 @@ LWGEOM* wkt_parser_polygon_add_ring(LWGEOM *poly, POINTARRAY *pa, char dimcheck)
        /* Apply check for minimum number of points, if requested. */   
        if( (global_parser_result.parser_check_flags & PARSER_CHECK_MINPOINTS) && (pa->npoints < 4) )
        {
+               ptarray_free(pa);
+               lwgeom_free(poly);
                SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
                return NULL;
        }
@@ -453,6 +467,8 @@ LWGEOM* wkt_parser_polygon_add_ring(LWGEOM *poly, POINTARRAY *pa, char dimcheck)
        if( (global_parser_result.parser_check_flags & PARSER_CHECK_CLOSURE) && 
            ! (dimcheck == 'Z' ? ptarray_isclosedz(pa) : ptarray_isclosed2d(pa)) )
        {
+               ptarray_free(pa);
+               lwgeom_free(poly);
                SET_PARSER_ERROR(PARSER_ERROR_UNCLOSED);
                return NULL;
        }
@@ -460,6 +476,8 @@ LWGEOM* wkt_parser_polygon_add_ring(LWGEOM *poly, POINTARRAY *pa, char dimcheck)
        /* If something goes wrong adding a ring, error out. */
        if ( LW_FAILURE == lwpoly_add_ring(lwgeom_as_lwpoly(poly), pa) )
        {
+               ptarray_free(pa);
+               lwgeom_free(poly);
                SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                return NULL;    
        }
@@ -481,6 +499,7 @@ LWGEOM* wkt_parser_polygon_finalize(LWGEOM *poly, char *dimensionality)
        {
                if ( flagdims != FLAGS_NDIMS(poly->flags) )
                {
+                       lwgeom_free(poly);
                        SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                        return NULL;
                }
@@ -488,6 +507,7 @@ LWGEOM* wkt_parser_polygon_finalize(LWGEOM *poly, char *dimensionality)
                /* Harmonize the flags in the sub-components with the wkt flags */
                if( LW_FAILURE == wkt_parser_set_dims(poly, flags) )
                {
+                       lwgeom_free(poly);
                        SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                        return NULL;
                }
@@ -529,8 +549,10 @@ LWGEOM* wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring)
        /* All the elements must agree on dimensionality */
        if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(ring->flags) )
        {
-               SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                LWDEBUG(4,"dimensionality does not match");
+               lwgeom_free(ring);
+               lwgeom_free(poly);
+               SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
        
@@ -538,8 +560,10 @@ LWGEOM* wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring)
        if( (global_parser_result.parser_check_flags & PARSER_CHECK_MINPOINTS) && 
            (lwgeom_count_vertices(ring) < 4) )
        {
-               SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
                LWDEBUG(4,"number of points is incorrect");
+               lwgeom_free(ring);
+               lwgeom_free(poly);
+               SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
                return NULL;
        }
        
@@ -565,6 +589,8 @@ LWGEOM* wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring)
                if ( ! is_closed )
                {
                        LWDEBUG(4,"ring is not closed");
+                       lwgeom_free(ring);
+                       lwgeom_free(poly);
                        SET_PARSER_ERROR(PARSER_ERROR_UNCLOSED);
                        return NULL;
                }
@@ -572,8 +598,10 @@ LWGEOM* wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring)
                
        if( LW_FAILURE == lwcurvepoly_add_ring(lwgeom_as_lwcurvepoly(poly), ring) )
        {
-               SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                LWDEBUG(4,"failed to add ring");
+               lwgeom_free(ring);
+               lwgeom_free(poly);
+               SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                return NULL;
        }
        
@@ -595,6 +623,7 @@ LWGEOM* wkt_parser_curvepolygon_finalize(LWGEOM *poly, char *dimensionality)
                /* If the number of dimensions are not consistent, we have a problem. */
                if( flagdims != FLAGS_NDIMS(poly->flags) )
                {
+                       lwgeom_free(poly);
                        SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                        return NULL;
                }
@@ -602,6 +631,7 @@ LWGEOM* wkt_parser_curvepolygon_finalize(LWGEOM *poly, char *dimensionality)
                /* Harmonize the flags in the sub-components with the wkt flags */
                if( LW_FAILURE == wkt_parser_set_dims(poly, flags) )
                {
+                       lwgeom_free(poly);
                        SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                        return NULL;
                }
@@ -650,12 +680,16 @@ LWGEOM* wkt_parser_compound_add_geom(LWGEOM *col, LWGEOM *geom)
        /* All the elements must agree on dimensionality */
        if( FLAGS_NDIMS(col->flags) != FLAGS_NDIMS(geom->flags) )
        {
+               lwgeom_free(col);
+               lwgeom_free(geom);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
        
        if( LW_FAILURE == lwcompound_add_lwgeom((LWCOMPOUND*)col, geom) )
        {
+               lwgeom_free(col);
+               lwgeom_free(geom);
                SET_PARSER_ERROR(PARSER_ERROR_INCONTINUOUS);
                return NULL;
        }
@@ -678,6 +712,8 @@ LWGEOM* wkt_parser_collection_add_geom(LWGEOM *col, LWGEOM *geom)
        /* All the elements must agree on dimensionality */
        if( FLAGS_NDIMS(col->flags) != FLAGS_NDIMS(geom->flags) )
        {
+               lwgeom_free(col);
+               lwgeom_free(geom);
                SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                return NULL;
        }
@@ -702,6 +738,7 @@ LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensiona
                /* If the number of dimensions are not consistent, we have a problem. */
                if( flagdims != FLAGS_NDIMS(col->flags) )
                {
+                       lwgeom_free(col);
                        SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                        return NULL;
                }
@@ -711,6 +748,7 @@ LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensiona
                    ( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(col->flags)) ||
                      (FLAGS_GET_M(flags) != FLAGS_GET_M(col->flags)) ) )
                {
+                       lwgeom_free(col);
                        SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
                        return NULL;
                }
@@ -718,6 +756,7 @@ LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensiona
                /* Harmonize the collection dimensionality */
                if( LW_FAILURE == wkt_parser_set_dims(col, flags) )
                {
+                       lwgeom_free(col);
                        SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                        return NULL;
                }
index 9cb1de19e61b909d874869a9d9d870abd2de9c96..f878d173b1c99b1fc011d6a860b471a910a2f8a2 100644 (file)
@@ -271,6 +271,7 @@ void ptarray_free(POINTARRAY *pa)
                if(pa->serialized_pointlist && ( ! FLAGS_GET_READONLY(pa->flags) ) )
                        lwfree(pa->serialized_pointlist);       
                lwfree(pa);
+               LWDEBUG(5,"Freeing a PointArray");
        }
 }