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)