From f478559d11237dddf9e33f6ffa2b1469c40a1c7e Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 7 Oct 2009 12:16:04 +0000 Subject: [PATCH] Fix #179: ST_MakeLine and ST_MakeLine_Garry crash server with null arrays again. There was another non-NULL safe array iterator within LWGEOM_makeline_garray. git-svn-id: http://svn.osgeo.org/postgis/trunk@4618 b70326c6-7e19-0410-871a-916f4a2858ee --- postgis/lwgeom_accum.c | 4 ++- postgis/lwgeom_functions_basic.c | 62 +++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/postgis/lwgeom_accum.c b/postgis/lwgeom_accum.c index 05e97d857..cc4ac34dc 100644 --- a/postgis/lwgeom_accum.c +++ b/postgis/lwgeom_accum.c @@ -284,7 +284,9 @@ pgis_geometry_makeline_finalfn(PG_FUNCTION_ARGS) p = (pgis_abs*) PG_GETARG_POINTER(0); geometry_array = pgis_accum_finalfn(p, CurrentMemoryContext, fcinfo); - result = DirectFunctionCall1( LWGEOM_makeline_garray, geometry_array ); + result = PGISDirectFunctionCall1( LWGEOM_makeline_garray, geometry_array ); + if (!result) + PG_RETURN_NULL(); PG_RETURN_DATUM(result); } diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c index 3fd59f6ec..129790fd9 100644 --- a/postgis/lwgeom_functions_basic.c +++ b/postgis/lwgeom_functions_basic.c @@ -2156,6 +2156,9 @@ Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS) size_t offset; int SRID=-1; + bits8 *bitmap; + int bitmask; + POSTGIS_DEBUG(2, "LWGEOM_makeline_garray called."); /* Get input datum */ @@ -2195,34 +2198,51 @@ Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS) lwpoints = palloc(sizeof(LWGEOM *)*nelems); npoints = 0; offset = 0; + bitmap = ARR_NULLBITMAP(array); + bitmask = 1; for (i=0; itype) != POINTTYPE ) continue; - - lwpoints[npoints++] = - lwpoint_deserialize(SERIALIZED_FORM(geom)); - - /* Check SRID homogeneity */ - if ( npoints == 1 ) - { - /* Get first geometry SRID */ - SRID = lwpoints[npoints-1]->SRID; + /* Don't do anything for NULL values */ + if ((bitmap && (*bitmap & bitmask) != 0) || !bitmap) + { + PG_LWGEOM *geom = (PG_LWGEOM *)(ARR_DATA_PTR(array)+offset); + offset += INTALIGN(VARSIZE(geom)); + + if ( TYPE_GETTYPE(geom->type) != POINTTYPE ) continue; + + lwpoints[npoints++] = + lwpoint_deserialize(SERIALIZED_FORM(geom)); + + /* Check SRID homogeneity */ + if ( npoints == 1 ) + { + /* Get first geometry SRID */ + SRID = lwpoints[npoints-1]->SRID; + } + else + { + if ( lwpoints[npoints-1]->SRID != SRID ) + { + elog(ERROR, + "Operation on mixed SRID geometries"); + PG_RETURN_NULL(); + } + } + + POSTGIS_DEBUGF(3, "LWGEOM_makeline_garray: element %d deserialized", + i); } - else + + /* Advance NULL bitmap */ + if (bitmap) { - if ( lwpoints[npoints-1]->SRID != SRID ) + bitmask <<= 1; + if (bitmask == 0x100) { - elog(ERROR, - "Operation on mixed SRID geometries"); - PG_RETURN_NULL(); + bitmap++; + bitmask = 1; } } - - POSTGIS_DEBUGF(3, "LWGEOM_makeline_garray: element %d deserialized", - i); } /* Return null on 0-points input array */ -- 2.50.1