From 4c656b32ab86f9980a522e897eeec4c1ce2203b3 Mon Sep 17 00:00:00 2001 From: Bborie Park Date: Mon, 28 Jan 2013 23:01:25 +0000 Subject: [PATCH] Fix function parameter value overflow that caused problems when copying data from a GDAL dataset. Problem first appeared in ST_Resize(). Ticket #2188 git-svn-id: http://svn.osgeo.org/postgis/trunk@11057 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 2 + raster/rt_core/rt_api.c | 64 ++++++++++++++++-------- raster/rt_core/rt_api.h | 2 +- raster/test/regress/rt_gdalwarp.sql | 23 +++++++-- raster/test/regress/rt_gdalwarp_expected | 7 +-- 5 files changed, 69 insertions(+), 29 deletions(-) diff --git a/NEWS b/NEWS index a4cec7ab8..8fdc5265d 100644 --- a/NEWS +++ b/NEWS @@ -138,6 +138,8 @@ PostGIS 2.1.0 - #2100, ST_AsRaster may not return raster with specified pixel type - #2126, Better handling of empty rasters from ST_ConvexHull() - #2182, Fix issue with outdb rasters with no SRID and ST_Resize + - #2188, Fix function parameter value overflow that caused problems + when copying data from a GDAL dataset PostGIS 2.0.3 2013/MM/DD diff --git a/raster/rt_core/rt_api.c b/raster/rt_core/rt_api.c index bd8924fd7..e38c6cd61 100644 --- a/raster/rt_core/rt_api.c +++ b/raster/rt_core/rt_api.c @@ -1985,7 +1985,7 @@ rt_errorstate rt_band_set_pixel_line( rt_band band, int x, int y, - void *vals, uint16_t len + void *vals, uint32_t len ) { rt_pixtype pixtype = PT_END; int size = 0; @@ -1994,6 +1994,8 @@ rt_band_set_pixel_line( assert(NULL != band); + RASTER_DEBUGF(3, "length of values = %d", len); + if (band->offline) { rterror("rt_band_set_pixel_line not implemented yet for OFFDB bands"); return ES_ERROR; @@ -2012,7 +2014,7 @@ rt_band_set_pixel_line( data = rt_band_get_data(band); offset = x + (y * band->width); - RASTER_DEBUGF(5, "offset = %d", offset); + RASTER_DEBUGF(4, "offset = %d", offset); /* make sure len of values to copy don't exceed end of data */ if (len > (band->width * band->height) - offset) { @@ -9013,6 +9015,21 @@ rt_raster_to_gdal_mem( rtwarn("rt_raster_to_gdal_mem: Could not set nodata value for band"); RASTER_DEBUGF(3, "nodata value set to %f", GDALGetRasterNoDataValue(band, NULL)); } + +#if POSTGIS_DEBUG_LEVEL > 3 + { + GDALRasterBandH _grb = NULL; + double _min; + double _max; + double _mean; + double _stddev; + + _grb = GDALGetRasterBand(ds, i + 1); + GDALComputeRasterStatistics(_grb, FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL); + RASTER_DEBUGF(4, "GDAL Band %d stats: %f, %f, %f, %f", i + 1, _min, _max, _mean, _stddev); + } +#endif + } /* necessary??? */ @@ -9089,12 +9106,13 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) { rt_raster_destroy(rast); return NULL; } - RASTER_DEBUGF(3, "Raster geotransform (%f, %f, %f, %f, %f, %f)", - gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]); /* apply raster attributes */ rt_raster_set_geotransform_matrix(rast, gt); + RASTER_DEBUGF(3, "Raster geotransform (%f, %f, %f, %f, %f, %f)", + gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]); + /* srid */ srs = GDALGetProjectionRef(ds); if (srs != NULL && srs[0] != '\0') { @@ -9108,13 +9126,29 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) { pszAuthorityCode != NULL ) { rt_raster_set_srid(rast, atoi(pszAuthorityCode)); + RASTER_DEBUGF(3, "New raster's SRID = %d", rast->srid); } } OSRDestroySpatialReference(hSRS); } - /* copy bands */ numBands = GDALGetRasterCount(ds); + +#if POSTGIS_DEBUG_LEVEL > 3 + for (i = 1; i <= numBands; i++) { + GDALRasterBandH _grb = NULL; + double _min; + double _max; + double _mean; + double _stddev; + + _grb = GDALGetRasterBand(ds, i); + GDALComputeRasterStatistics(_grb, FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL); + RASTER_DEBUGF(4, "GDAL Band %d stats: %f, %f, %f, %f", i, _min, _max, _mean, _stddev); + } +#endif + + /* copy bands */ for (i = 1; i <= numBands; i++) { RASTER_DEBUGF(3, "Processing band %d of %d", i, numBands); gdband = NULL; @@ -9138,7 +9172,7 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) { /* size: width and height */ width = GDALGetRasterBandXSize(gdband); height = GDALGetRasterBandYSize(gdband); - RASTER_DEBUGF(3, "Band dimensions (width x height): %d x %d", width, height); + RASTER_DEBUGF(3, "GDAL band dimensions (width x height): %d x %d", width, height); /* nodata */ nodataval = GDALGetRasterNoDataValue(gdband, &status); @@ -9206,16 +9240,17 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) { rt_raster_destroy(rast); return NULL; } + RASTER_DEBUGF(3, "values len = %d", valueslen); for (iYBlock = 0; iYBlock < nYBlocks; iYBlock++) { for (iXBlock = 0; iXBlock < nXBlocks; iXBlock++) { - memset(values, 0, valueslen); - x = iXBlock * nXBlockSize; y = iYBlock * nYBlockSize; RASTER_DEBUGF(4, "(iXBlock, iYBlock) = (%d, %d)", iXBlock, iYBlock); RASTER_DEBUGF(4, "(x, y) = (%d, %d)", x, y); + memset(values, 0, valueslen); + /* valid block width */ if ((iXBlock + 1) * nXBlockSize > width) nXValid = width - (iXBlock * nXBlockSize); @@ -9239,7 +9274,7 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) { 0, 0 ); if (cplerr != CE_None) { - rterror("rt_raster_from_gdal_dataset: Unable to get data from transformed raster"); + rterror("rt_raster_from_gdal_dataset: Unable to get data from GDAL raster"); rtdealloc(values); rt_raster_destroy(rast); return NULL; @@ -9491,17 +9526,6 @@ rt_raster rt_raster_gdal_warp( return NULL; } RASTER_DEBUG(3, "raster loaded into GDAL MEM dataset"); - { - GDALRasterBandH _grb = NULL; - double _min; - double _max; - double _mean; - double _stddev; - - _grb = GDALGetRasterBand(arg->src.ds, 1); - GDALComputeRasterStatistics(_grb, FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL); - RASTER_DEBUGF(4, "GDAL stats: %f, %f, %f, %f", _min, _max, _mean, _stddev); - } /* set transform options */ if (arg->src.srs != NULL || arg->dst.srs != NULL) { diff --git a/raster/rt_core/rt_api.h b/raster/rt_core/rt_api.h index d1d767481..647b9bfc8 100644 --- a/raster/rt_core/rt_api.h +++ b/raster/rt_core/rt_api.h @@ -638,7 +638,7 @@ rt_errorstate rt_band_get_nodata(rt_band band, double *nodata); rt_errorstate rt_band_set_pixel_line( rt_band band, int x, int y, - void *vals, uint16_t len + void *vals, uint32_t len ); /** diff --git a/raster/test/regress/rt_gdalwarp.sql b/raster/test/regress/rt_gdalwarp.sql index 09477c89b..b755b404d 100644 --- a/raster/test/regress/rt_gdalwarp.sql +++ b/raster/test/regress/rt_gdalwarp.sql @@ -815,7 +815,8 @@ SELECT ST_MakeEmptyRaster(1000, 1000, 0, 0, 1, -1, 0, 0, 0) , 1, '8BUI', 255, 0 ) - , '50%', '500') AS rast + , '50%', '500' + ) AS rast UNION ALL SELECT 2 AS rid, @@ -824,7 +825,8 @@ SELECT ST_MakeEmptyRaster(1000, 1000, 0, 0, 1, -1, 0, 0, 0) , 1, '8BUI', 255, 0 ) - , 500, 100) AS rast + , 500, 100 + ) AS rast UNION ALL SELECT 3 AS rid, @@ -833,8 +835,19 @@ SELECT ST_MakeEmptyRaster(1000, 1000, 0, 0, 1, -1, 0, 0, 0) , 1, '8BUI', 255, 0 ) - , 0.25, 0.9) AS rast + , 0.25, 0.9 + ) AS rast +UNION ALL +SELECT -- ticket #2188 + 4 AS rid, + ST_Resize( + ST_AddBand( + ST_MakeEmptyRaster(1024, 768, 0, 0, 1, -1, 0, 0, 0) + , 1, '8BUI', 255, 0 + ) + , 0.5, 0.5 + ) AS rast ), bar AS ( - SELECT rid, ST_Metadata(rast) AS meta, rast FROM foo + SELECT rid, ST_Metadata(rast) AS meta, ST_SummaryStats(rast) AS stats FROM foo ) -SELECT rid, (meta).* FROM bar +SELECT rid, (meta).*, (stats).* FROM bar diff --git a/raster/test/regress/rt_gdalwarp_expected b/raster/test/regress/rt_gdalwarp_expected index 08cf1eee3..50aaa3cd1 100644 --- a/raster/test/regress/rt_gdalwarp_expected +++ b/raster/test/regress/rt_gdalwarp_expected @@ -114,6 +114,7 @@ NOTICE: Values must be provided for both X and Y when specifying the scale. Re 5.9|992163|10|11|1|1000.000|-1000.000|0.000|0.000|-500000.000|600009.000|t|t|t NOTICE: The rasters (pixel corner coordinates) are not aligned t|f|t -1|0|0|500|500|1|-1|0|0|0|1 -2|0|0|500|100|1|-1|0|0|0|1 -3|0|0|250|900|1|-1|0|0|0|1 +1|0|0|500|500|1|-1|0|0|0|1|250000|63750000|255|0|255|255 +2|0|0|500|100|1|-1|0|0|0|1|50000|12750000|255|0|255|255 +3|0|0|250|900|1|-1|0|0|0|1|225000|57375000|255|0|255|255 +4|0|0|512|384|1|-1|0|0|0|1|196608|50135040|255|0|255|255 -- 2.40.0