From: Sandro Santilli Date: Tue, 10 Jan 2012 11:36:14 +0000 (+0000) Subject: Check type of elements added to multi geometries. Fixes #1445. X-Git-Tag: 2.0.0alpha1~134 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=25c22d217e8547cb1b5131512e60b4d1da2557f6;p=postgis Check type of elements added to multi geometries. Fixes #1445. 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 --- diff --git a/liblwgeom/cunit/cu_in_wkb.c b/liblwgeom/cunit/cu_in_wkb.c index 689dd0639..c079af883 100644 --- a/liblwgeom/cunit/cu_in_wkb.c +++ b/liblwgeom/cunit/cu_in_wkb.c @@ -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}; diff --git a/liblwgeom/lwcollection.c b/liblwgeom/lwcollection.c index 8b7c2a4cc..f86d3906e 100644 --- a/liblwgeom/lwcollection.c +++ b/liblwgeom/lwcollection.c @@ -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 ) diff --git a/liblwgeom/lwin_wkb.c b/liblwgeom/lwin_wkb.c index 34f2a5392..dcb6a2a00 100644 --- a/liblwgeom/lwin_wkb.c +++ b/liblwgeom/lwin_wkb.c @@ -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; diff --git a/regress/tickets.sql b/regress/tickets.sql index e01d378a9..d8a4e7ac8 100644 --- a/regress/tickets.sql +++ b/regress/tickets.sql @@ -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; diff --git a/regress/tickets_expected b/regress/tickets_expected index 704edf461..f514c5450 100644 --- a/regress/tickets_expected +++ b/regress/tickets_expected @@ -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)