]> granicus.if.org Git - postgis/commitdiff
Check type of elements added to multi geometries. Fixes #1445.
authorSandro Santilli <strk@keybit.net>
Tue, 10 Jan 2012 11:36:14 +0000 (11:36 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 10 Jan 2012 11:36:14 +0000 (11:36 +0000)
Includes regress testing both at the liblwgeom and postgis levels.

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

liblwgeom/cunit/cu_in_wkb.c
liblwgeom/lwcollection.c
liblwgeom/lwin_wkb.c
regress/tickets.sql
regress/tickets_expected

index 689dd06392a86077c9401f452ef837b508c3b324..c079af8839844de8f3ff87d955ff02716b02c52d 100644 (file)
@@ -48,6 +48,17 @@ static int clean_wkb_in_suite(void)
        return 0;
 }
 
+static void cu_wkb_malformed_in(char *hex)
+{
+       LWGEOM_PARSER_RESULT p;
+       int rv = 0;
+
+       rv = lwgeom_parse_wkt(&p, hex, 0);
+       CU_ASSERT( LW_FAILURE == rv );
+       CU_ASSERT( p.errcode );
+       lwgeom_parser_result_free(&p);
+}
+
 static void cu_wkb_in(char *wkt)
 {
        LWGEOM_PARSER_RESULT pr;
@@ -185,6 +196,15 @@ static void test_wkb_in_multicurve(void) {}
 
 static void test_wkb_in_multisurface(void) {}
 
+static void test_wkb_in_malformed(void)
+{
+       /* See http://trac.osgeo.org/postgis/ticket/1445 */
+       cu_wkb_malformed_in("01060000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
+       cu_wkb_malformed_in("01050000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
+       cu_wkb_malformed_in("01040000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
+       cu_wkb_malformed_in("01030000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F");
+}
+
 
 /*
 ** Used by test harness to register the tests in this file.
@@ -204,6 +224,7 @@ CU_TestInfo wkb_in_tests[] =
        PG_TEST(test_wkb_in_curvpolygon),
        PG_TEST(test_wkb_in_multicurve),
        PG_TEST(test_wkb_in_multisurface),
+       PG_TEST(test_wkb_in_malformed),
        CU_TEST_INFO_NULL
 };
 CU_SuiteInfo wkb_in_suite = {"WKB In Suite",  init_wkb_in_suite,  clean_wkb_in_suite, wkb_in_tests};
index 8b7c2a4cc29bfd9437a71221589f547ce1f87ae3..f86d3906e8a8ffbfcef03b98d08cad9bdc589563 100644 (file)
@@ -174,8 +174,33 @@ LWCOLLECTION* lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
 
        if ( col == NULL || geom == NULL ) return NULL;
 
-       if ( col->geoms == NULL && (col->ngeoms || col->maxgeoms) )
+       if ( col->geoms == NULL && (col->ngeoms || col->maxgeoms) ) {
                lwerror("Collection is in inconsistent state. Null memory but non-zero collection counts.");
+               return NULL;
+       }
+
+       /* Check type compatibility */
+       if ( col->type < 7 ) {
+               if ( geom->type != col->type-3 ) {
+                       lwerror("%s cannot contain %s element", lwtype_name(col->type), lwtype_name(geom->type));
+                       return NULL;
+               }
+       }
+       else if ( col->type == COMPOUNDTYPE ) {
+               /* Allow: linestring, circularstring */
+               if ( geom->type != LINETYPE && geom->type != CIRCSTRINGTYPE ) {
+                       lwerror("%s cannot contain %s element", lwtype_name(col->type), lwtype_name(geom->type));
+                       return NULL;
+               }
+       }
+       else if ( col->type == MULTICURVETYPE ) {
+               /* Allow: linestring, circularstring, compoundcurve */
+               if ( geom->type != LINETYPE && geom->type != CIRCSTRINGTYPE && geom->type != COMPOUNDTYPE ) {
+                       lwerror("%s cannot contain %s element", lwtype_name(col->type), lwtype_name(geom->type));
+                       return NULL;
+               }
+       }
+       /* TODO: I'm probably missing something else here... would be nice to have the +3 invariant always */
 
        /* In case this is a truly empty, make some initial space  */
        if ( col->geoms == NULL )
index 34f2a5392a99ce66435ceaf9f11d8993d39308d4..dcb6a2a0090a5e78898cba685b5daec2c0b4ce16 100644 (file)
@@ -591,8 +591,11 @@ static LWCOLLECTION* lwcollection_from_wkb_state(wkb_parse_state *s)
        for ( i = 0; i < ngeoms; i++ )
        {
                geom = lwgeom_from_wkb_state(s);
-               if ( lwcollection_add_lwgeom(col, geom) == LW_FALSE )
+               if ( lwcollection_add_lwgeom(col, geom) == NULL )
+               {
                        lwerror("Unable to add geometry (%p) to collection (%p)", geom, col);
+                       return NULL;
+               }
        }
        
        return col;
index e01d378a999f3c21d99ac608d486c40397776569..d8a4e7ac8ecab7293947b35d260490c79a2d3c2a 100644 (file)
@@ -494,6 +494,14 @@ WITH pts AS ( SELECT 'POINT(0 45)'::geography AS s, 'POINT(45 45)'::geography AS
 SELECT '#1305.2',abs(ST_Distance(e, ST_Project(s, ST_Distance(s, e), ST_Azimuth(s, e)))) < 0.001 FROM pts;
 SELECT '#1305.3',ST_Azimuth('POINT(0 45)'::geography, 'POINT(0 45)'::geography) IS NULL;
 
+-- #1445
+SELECT '01060000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F'::geometry;
+SELECT '01050000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F'::geometry;
+SELECT '01040000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F'::geometry;
+SELECT '01090000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F'::geometry;
+SELECT '010B0000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F'::geometry;
+SELECT '010C0000400200000001040000400100000001010000400000000000000000000000000000000000000000000000000101000040000000000000F03F000000000000F03F000000000000F03F'::geometry;
+
 
 -- Clean up
 DELETE FROM spatial_ref_sys;
index 704edf461cb78d6ebcc5d06b7f387f3acaf8b25d..f514c5450bf9cdaca5cad7dc24134e8f05d59e5b 100644 (file)
@@ -161,3 +161,9 @@ ERROR:  Geometry type (Polygon) does not match column type (MultiPolygon)
 #1305.1|POINT(10 10)
 #1305.2|t
 #1305.3|t
+ERROR:  MultiPolygon cannot contain MultiPoint element
+ERROR:  MultiLineString cannot contain MultiPoint element
+ERROR:  MultiPoint cannot contain MultiPoint element
+ERROR:  CompoundCurve cannot contain MultiPoint element
+ERROR:  MultiCurve cannot contain MultiPoint element
+ERROR:  Invalid subtype (MultiPoint) for collection type (MultiSurface)