Skip to content

Commit

Permalink
WMS: determine a resolution that will not result in a number that is …
Browse files Browse the repository at this point in the history
…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, OSGeo/gdal#89)

git-svn-id: https://svn.osgeo.org/gdal/trunk/gdal@32806 f0d54148-0727-0410-94bb-9a71ac55c965
  • Loading branch information
rouault committed Jan 7, 2016
1 parent a4b8a8e commit 9f5d50e
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions frmts/wms/wmsdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include "minidriver_arcgis_server.h"
#include "minidriver_iip.h"

#include <limits>

/************************************************************************/
/* GDALWMSDatasetGetConfigFromURL() */
/************************************************************************/
Expand Down Expand Up @@ -160,6 +162,7 @@ CPLXMLNode * GDALWMSDatasetGetConfigFromURL(GDALOpenInfo *poOpenInfo)
nTileSize = 1024;

int nXSize, nYSize;
double dXSize, dYSize;

int nOverviewCount = (osOverviewCount.size()) ? atoi(osOverviewCount) : 20;

Expand All @@ -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<int>::max)() ||
dYSize > (std::numeric_limits<int>::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<int>::max)() ||
dYSize > (std::numeric_limits<int>::max)())
{
dXSize /= 2;
dYSize /= 2;
}
}

nXSize = (int) dXSize;
nYSize = (int) dYSize;

int bTransparent = osTransparent.size() ? CSLTestBoolean(osTransparent) : FALSE;

if (osFormat.size() == 0)
Expand Down

0 comments on commit 9f5d50e

Please sign in to comment.