From 9f5d50ef18a56ed2b290044bfc170b9d248583e5 Mon Sep 17 00:00:00 2001 From: rouault Date: Thu, 7 Jan 2016 20:10:03 +0000 Subject: [PATCH] WMS: determine a resolution that will not result in a number that is larger than the maximum size of an integer. Any value that exceeds the maximum size of an integer will raise an invalid dataset dimensions error. (patch by Tim Astle, https://github.com/OSGeo/gdal/pull/89) git-svn-id: https://svn.osgeo.org/gdal/trunk/gdal@32806 f0d54148-0727-0410-94bb-9a71ac55c965 --- frmts/wms/wmsdriver.cpp | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/frmts/wms/wmsdriver.cpp b/frmts/wms/wmsdriver.cpp index 4f8507d0b1..f307f39fb2 100644 --- a/frmts/wms/wmsdriver.cpp +++ b/frmts/wms/wmsdriver.cpp @@ -42,6 +42,8 @@ #include "minidriver_arcgis_server.h" #include "minidriver_iip.h" +#include + /************************************************************************/ /* GDALWMSDatasetGetConfigFromURL() */ /************************************************************************/ @@ -160,6 +162,7 @@ CPLXMLNode * GDALWMSDatasetGetConfigFromURL(GDALOpenInfo *poOpenInfo) nTileSize = 1024; int nXSize, nYSize; + double dXSize, dYSize; int nOverviewCount = (osOverviewCount.size()) ? atoi(osOverviewCount) : 20; @@ -173,30 +176,51 @@ CPLXMLNode * GDALWMSDatasetGetConfigFromURL(GDALOpenInfo *poOpenInfo) dfMinResolution *= 2; } - nXSize = (int) ((dfMaxX - dfMinX) / dfMinResolution + 0.5); - nYSize = (int) ((dfMaxY - dfMinY) / dfMinResolution + 0.5); + // Determine a suitable size that doesn't overflow max int. + dXSize = ((dfMaxX - dfMinX) / dfMinResolution + 0.5); + dYSize = ((dfMaxY - dfMinY) / dfMinResolution + 0.5); + + while (dXSize > (std::numeric_limits::max)() || + dYSize > (std::numeric_limits::max)()) + { + dfMinResolution *= 2; + + dXSize = ((dfMaxX - dfMinX) / dfMinResolution + 0.5); + dYSize = ((dfMaxY - dfMinY) / dfMinResolution + 0.5); + } } else { double dfRatio = (dfMaxX - dfMinX) / (dfMaxY - dfMinY); if (dfRatio > 1) { - nXSize = nTileSize; - nYSize = (int) (nXSize / dfRatio); + dXSize = nTileSize; + dYSize = dXSize / dfRatio; } else { - nYSize = nTileSize; - nXSize = (int) (nYSize * dfRatio); + dYSize = nTileSize; + dXSize = dYSize * dfRatio; } if (nOverviewCount < 0 || nOverviewCount > 20) nOverviewCount = 20; - nXSize = nXSize * (1 << nOverviewCount); - nYSize = nYSize * (1 << nOverviewCount); + dXSize = dXSize * (1 << nOverviewCount); + dYSize = dYSize * (1 << nOverviewCount); + + // Determine a suitable size that doesn't overflow max int. + while (dXSize > (std::numeric_limits::max)() || + dYSize > (std::numeric_limits::max)()) + { + dXSize /= 2; + dYSize /= 2; + } } + nXSize = (int) dXSize; + nYSize = (int) dYSize; + int bTransparent = osTransparent.size() ? CSLTestBoolean(osTransparent) : FALSE; if (osFormat.size() == 0)