From: Paul Ramsey Date: Thu, 23 Apr 2015 22:56:23 +0000 (+0000) Subject: #3098, odd dimension mixes in WKT X-Git-Tag: 2.2.0rc1~550 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a0885952a80ba9d55adfa95893f633540cb38b94;p=postgis #3098, odd dimension mixes in WKT git-svn-id: http://svn.osgeo.org/postgis/trunk@13442 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/lwin_wkt.c b/liblwgeom/lwin_wkt.c index b7262bcbb..ee325030b 100644 --- a/liblwgeom/lwin_wkt.c +++ b/liblwgeom/lwin_wkt.c @@ -96,55 +96,68 @@ static int wkt_parser_set_dims(LWGEOM *geom, uint8_t flags) FLAGS_SET_Z(geom->flags, hasz); FLAGS_SET_M(geom->flags, hasm); - - if( ! lwgeom_is_empty(geom) ) + + switch( geom->type ) { - if( geom->type == POINTTYPE ) + case POINTTYPE: { LWPOINT *pt = (LWPOINT*)geom; - FLAGS_SET_Z(pt->point->flags, hasz); - FLAGS_SET_M(pt->point->flags, hasm); - return LW_SUCCESS; + if ( pt->point ) + { + FLAGS_SET_Z(pt->point->flags, hasz); + FLAGS_SET_M(pt->point->flags, hasm); + } + break; } - else if ( (geom->type == TRIANGLETYPE) || - (geom->type == CIRCSTRINGTYPE) || - (geom->type == LINETYPE) ) + case TRIANGLETYPE: + case CIRCSTRINGTYPE: + case LINETYPE: { LWLINE *ln = (LWLINE*)geom; - FLAGS_SET_Z(ln->points->flags, hasz); - FLAGS_SET_M(ln->points->flags, hasm); - return LW_SUCCESS; + if ( ln->points ) + { + FLAGS_SET_Z(ln->points->flags, hasz); + FLAGS_SET_M(ln->points->flags, hasm); + } + break; } - else if ( geom->type == POLYGONTYPE ) + case POLYGONTYPE: { LWPOLY *poly = (LWPOLY*)geom; for ( i = 0; i < poly->nrings; i++ ) { - FLAGS_SET_Z(poly->rings[i]->flags, hasz); - FLAGS_SET_M(poly->rings[i]->flags, hasm); + if( poly->rings[i] ) + { + FLAGS_SET_Z(poly->rings[i]->flags, hasz); + FLAGS_SET_M(poly->rings[i]->flags, hasm); + } } - return LW_SUCCESS; + break; } - else if ( geom->type == CURVEPOLYTYPE ) + case CURVEPOLYTYPE: { LWCURVEPOLY *poly = (LWCURVEPOLY*)geom; for ( i = 0; i < poly->nrings; i++ ) wkt_parser_set_dims(poly->rings[i], flags); - return LW_SUCCESS; + break; } - else if ( lwtype_is_collection(geom->type) ) + default: { - LWCOLLECTION *col = (LWCOLLECTION*)geom; - for ( i = 0; i < col->ngeoms; i++ ) - wkt_parser_set_dims(col->geoms[i], flags); - return LW_SUCCESS; + if ( lwtype_is_collection(geom->type) ) + { + LWCOLLECTION *col = (LWCOLLECTION*)geom; + for ( i = 0; i < col->ngeoms; i++ ) + wkt_parser_set_dims(col->geoms[i], flags); + return LW_SUCCESS; + } + else + { + LWDEBUGF(2,"Unknown geometry type: %d", geom->type); + return LW_FAILURE; + } } - else - { - LWDEBUGF(2,"Unknown geometry type: %d", geom->type); - return LW_FAILURE; - } } + return LW_SUCCESS; } @@ -687,7 +700,7 @@ LWGEOM* wkt_parser_collection_new(LWGEOM *geom) geoms[0] = geom; /* Make a new collection */ - col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms); + col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms); /* Return the result. */ return lwcollection_as_lwgeom(col); @@ -736,26 +749,17 @@ LWGEOM* wkt_parser_collection_add_geom(LWGEOM *col, LWGEOM *geom) SET_PARSER_ERROR(PARSER_ERROR_OTHER); return NULL; } - - /* 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; - } - + return lwcollection_as_lwgeom(lwcollection_add_lwgeom(lwgeom_as_lwcollection(col), geom)); } -LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensionality) +LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *geom, char *dimensionality) { uint8_t flags = wkt_dimensionality(dimensionality); int flagdims = FLAGS_NDIMS(flags); /* No geometry means it is empty */ - if( ! col ) + if( ! geom ) { return lwcollection_as_lwgeom(lwcollection_construct_empty(lwtype, SRID_UNKNOWN, FLAGS_GET_Z(flags), FLAGS_GET_M(flags))); } @@ -763,37 +767,44 @@ LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensiona /* There are 'Z' or 'M' tokens in the signature */ if ( flagdims > 2 ) { - /* 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; - } - - /* For GEOMETRYCOLLECTION, the exact type of the dimensions must match too */ - if( lwtype == COLLECTIONTYPE && - ( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(col->flags)) || - (FLAGS_GET_M(flags) != FLAGS_GET_M(col->flags)) ) ) + LWCOLLECTION *col = lwgeom_as_lwcollection(geom); + int i; + + for ( i = 0 ; i < col->ngeoms; i++ ) { - lwgeom_free(col); - SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS); - return NULL; + LWGEOM *subgeom = col->geoms[i]; + if ( FLAGS_NDIMS(flags) != FLAGS_NDIMS(subgeom->flags) && + ! lwgeom_is_empty(subgeom) ) + { + lwgeom_free(geom); + SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS); + return NULL; + } + + if ( lwtype == COLLECTIONTYPE && + ( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(subgeom->flags)) || + (FLAGS_GET_M(flags) != FLAGS_GET_M(subgeom->flags)) ) && + ! lwgeom_is_empty(subgeom) ) + { + lwgeom_free(geom); + SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS); + return NULL; + } } /* Harmonize the collection dimensionality */ - if( LW_FAILURE == wkt_parser_set_dims(col, flags) ) + if( LW_FAILURE == wkt_parser_set_dims(geom, flags) ) { - lwgeom_free(col); + lwgeom_free(geom); SET_PARSER_ERROR(PARSER_ERROR_OTHER); return NULL; } } /* Set the collection type */ - col->type=lwtype; + geom->type = lwtype; - return col; + return geom; } void wkt_parser_geometry_new(LWGEOM *geom, int srid)