Skip to content

Commit f60076f

Browse files
committed
Various drivers: avoid very unlikely/maybe impossible int overflows
1 parent 83bca98 commit f60076f

File tree

9 files changed

+139
-233
lines changed

9 files changed

+139
-233
lines changed

frmts/ecw/ecwdataset.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,13 +1057,10 @@ CPLErr ECWRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
10571057
CPLErr ECWRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
10581058

10591059
{
1060-
int nXOff = nBlockXOff * nBlockXSize, nYOff = nBlockYOff * nBlockYSize,
1061-
nXSize = nBlockXSize, nYSize = nBlockYSize;
1062-
1063-
if (nXOff + nXSize > nRasterXSize)
1064-
nXSize = nRasterXSize - nXOff;
1065-
if (nYOff + nYSize > nRasterYSize)
1066-
nYSize = nRasterYSize - nYOff;
1060+
const int nXOff = nBlockXOff * nBlockXSize;
1061+
const int nXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
1062+
const int nYOff = nBlockYOff * nBlockYSize;
1063+
const int nYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
10671064

10681065
const GSpacing nPixelSpace = GDALGetDataTypeSizeBytes(eDataType);
10691066
const GSpacing nLineSpace = nPixelSpace * nBlockXSize;

frmts/eeda/eedaidataset.cpp

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -309,25 +309,20 @@ bool GDALEEDAIRasterBand::DecodeNPYArray(const GByte *pabyData, int nDataLen,
309309

310310
for (int iYBlock = 0; iYBlock < nYBlocks; iYBlock++)
311311
{
312-
int nBlockActualYSize = nBlockYSize;
313-
if ((iYBlock + nBlockYOff + 1) * nBlockYSize > nRasterYSize)
314-
{
315-
nBlockActualYSize =
316-
nRasterYSize - (iYBlock + nBlockYOff) * nBlockYSize;
317-
}
312+
const int nYOff = (nBlockYOff + iYBlock) * nBlockYSize;
313+
const int nBlockActualYSize =
314+
std::min(nBlockYSize, nRasterYSize - nYOff);
318315

319316
for (int iXBlock = 0; iXBlock < nXBlocks; iXBlock++)
320317
{
321-
int nBlockActualXSize = nBlockXSize;
322-
if ((iXBlock + nBlockXOff + 1) * nBlockXSize > nRasterXSize)
323-
{
324-
nBlockActualXSize =
325-
nRasterXSize - (iXBlock + nBlockXOff) * nBlockXSize;
326-
}
318+
const int nXOff = (nBlockXOff + iXBlock) * nBlockXSize;
319+
const int nBlockActualXSize =
320+
std::min(nBlockXSize, nRasterXSize - nXOff);
327321

328-
int nOffsetBand =
322+
size_t nOffsetBand =
329323
10 + nHeaderLen +
330-
(iYBlock * nBlockYSize * nReqXSize + iXBlock * nBlockXSize) *
324+
(static_cast<size_t>(iYBlock) * nBlockYSize * nReqXSize +
325+
iXBlock * nBlockXSize) *
331326
nTotalDataTypeSize;
332327

333328
for (int i = 1; i <= poGDS->GetRasterCount(); i++)
@@ -439,21 +434,15 @@ bool GDALEEDAIRasterBand::DecodeGDALDataset(const GByte *pabyData, int nDataLen,
439434

440435
for (int iYBlock = 0; iYBlock < nYBlocks; iYBlock++)
441436
{
442-
int nBlockActualYSize = nBlockYSize;
443-
if ((iYBlock + nBlockYOff + 1) * nBlockYSize > nRasterYSize)
444-
{
445-
nBlockActualYSize =
446-
nRasterYSize - (iYBlock + nBlockYOff) * nBlockYSize;
447-
}
437+
const int nYOff = (nBlockYOff + iYBlock) * nBlockYSize;
438+
const int nBlockActualYSize =
439+
std::min(nBlockYSize, nRasterYSize - nYOff);
448440

449441
for (int iXBlock = 0; iXBlock < nXBlocks; iXBlock++)
450442
{
451-
int nBlockActualXSize = nBlockXSize;
452-
if ((iXBlock + nBlockXOff + 1) * nBlockXSize > nRasterXSize)
453-
{
454-
nBlockActualXSize =
455-
nRasterXSize - (iXBlock + nBlockXOff) * nBlockXSize;
456-
}
443+
const int nXOff = (nBlockXOff + iXBlock) * nBlockXSize;
444+
const int nBlockActualXSize =
445+
std::min(nBlockXSize, nRasterXSize - nXOff);
457446

458447
for (int i = 1; i <= poGDS->GetRasterCount(); i++)
459448
{
@@ -536,16 +525,13 @@ CPLErr GDALEEDAIRasterBand::GetBlocks(int nBlockXOff, int nBlockYOff,
536525
}
537526
json_object_object_add(poReq, "bandIds", poBands);
538527

539-
int nReqXSize = nBlockXSize * nXBlocks;
540-
if ((nBlockXOff + nXBlocks) * nBlockXSize > nRasterXSize)
541-
nReqXSize = nRasterXSize - nBlockXOff * nBlockXSize;
542-
int nReqYSize = nBlockYSize * nYBlocks;
543-
if ((nBlockYOff + nYBlocks) * nBlockYSize > nRasterYSize)
544-
nReqYSize = nRasterYSize - nBlockYOff * nBlockYSize;
545-
const double dfX0 =
546-
poGDS->m_gt[0] + nBlockXOff * nBlockXSize * poGDS->m_gt[1];
547-
const double dfY0 =
548-
poGDS->m_gt[3] + nBlockYOff * nBlockYSize * poGDS->m_gt[5];
528+
const int nXOff = nBlockXOff * nBlockXSize;
529+
const int nReqXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
530+
const int nYOff = nBlockYOff * nBlockYSize;
531+
const int nReqYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
532+
533+
const double dfX0 = poGDS->m_gt[0] + nXOff * poGDS->m_gt[1];
534+
const double dfY0 = poGDS->m_gt[3] + nYOff * poGDS->m_gt[5];
549535
#ifdef DEBUG_VERBOSE
550536
CPLDebug("EEDAI",
551537
"nBlockYOff=%d nBlockYOff=%d "

frmts/kmlsuperoverlay/kmlsuperoverlaydataset.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
#include "cpl_port.h"
1515
#include "kmlsuperoverlaydataset.h"
1616

17-
#include <array>
1817
#include <cmath>
1918
#include <cstring>
2019
#include <algorithm>
20+
#include <array>
2121
#include <fstream>
2222
#include <iostream>
2323
#include <sstream>
@@ -1103,14 +1103,10 @@ KmlSuperOverlayRasterBand::KmlSuperOverlayRasterBand(
11031103
CPLErr KmlSuperOverlayRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff,
11041104
void *pData)
11051105
{
1106-
int nXOff = nBlockXOff * nBlockXSize;
1107-
int nYOff = nBlockYOff * nBlockYSize;
1108-
int nXSize = nBlockXSize;
1109-
int nYSize = nBlockYSize;
1110-
if (nXOff + nXSize > nRasterXSize)
1111-
nXSize = nRasterXSize - nXOff;
1112-
if (nYOff + nYSize > nRasterYSize)
1113-
nYSize = nRasterYSize - nYOff;
1106+
const int nXOff = nBlockXOff * nBlockXSize;
1107+
const int nXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
1108+
const int nYOff = nBlockYOff * nBlockYSize;
1109+
const int nYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
11141110

11151111
GDALRasterIOExtraArg sExtraArg;
11161112
INIT_RASTERIO_EXTRA_ARG(sExtraArg);
@@ -2163,15 +2159,13 @@ CPLErr KmlSingleDocRasterRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff,
21632159
memset(pImage, 0, static_cast<size_t>(nBlockXSize) * nBlockYSize);
21642160
return CE_None;
21652161
}
2166-
int nXSize = poImageDS->GetRasterXSize();
2167-
int nYSize = poImageDS->GetRasterYSize();
2162+
const int nXSize = poImageDS->GetRasterXSize();
2163+
const int nYSize = poImageDS->GetRasterYSize();
21682164

2169-
int nReqXSize = nBlockXSize;
2170-
if (nBlockXOff * nBlockXSize + nReqXSize > nRasterXSize)
2171-
nReqXSize = nRasterXSize - nBlockXOff * nBlockXSize;
2172-
int nReqYSize = nBlockYSize;
2173-
if (nBlockYOff * nBlockYSize + nReqYSize > nRasterYSize)
2174-
nReqYSize = nRasterYSize - nBlockYOff * nBlockYSize;
2165+
const int nXOff = nBlockXOff * nBlockXSize;
2166+
const int nReqXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
2167+
const int nYOff = nBlockYOff * nBlockYSize;
2168+
const int nReqYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
21752169

21762170
if (nXSize != nReqXSize || nYSize != nReqYSize)
21772171
{

frmts/nitf/nitfrasterband.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,42 +1166,23 @@ CPLErr NITFComplexRasterBand::IBlockIO(int nBlockXOff, int nBlockYOff,
11661166
void *pImage, GDALRWFlag rwFlag)
11671167

11681168
{
1169-
int nRequestYSize;
1170-
int nRequestXSize;
1171-
bool bMemset = false;
1172-
11731169
/* -------------------------------------------------------------------- */
11741170
/* If the last strip is partial, we need to avoid */
11751171
/* over-requesting. We also need to initialize the extra part */
11761172
/* of the block to zero. */
11771173
/* -------------------------------------------------------------------- */
1178-
if ((nBlockYOff + 1) * nBlockYSize > nRasterYSize)
1179-
{
1180-
nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize;
1181-
if (rwFlag == GF_Read)
1182-
bMemset = true;
1183-
}
1184-
else
1185-
{
1186-
nRequestYSize = nBlockYSize;
1187-
}
1174+
const int nYOff = nBlockYOff * nBlockYSize;
1175+
const int nRequestYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
11881176

11891177
/*-------------------------------------------------------------------- */
11901178
/* If the input imagery is tiled, also need to avoid over- */
11911179
/* requesting in the X-direction. */
11921180
/* ------------------------------------------------------------------- */
1193-
if ((nBlockXOff + 1) * nBlockXSize > nRasterXSize)
1194-
{
1195-
nRequestXSize = nRasterXSize - nBlockXOff * nBlockXSize;
1196-
if (rwFlag == GF_Read)
1197-
bMemset = true;
1198-
}
1199-
else
1200-
{
1201-
nRequestXSize = nBlockXSize;
1202-
}
1181+
const int nXOff = nBlockXOff * nBlockXSize;
1182+
const int nRequestXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
12031183

1204-
if (bMemset)
1184+
if (rwFlag == GF_Read &&
1185+
(nRequestXSize < nBlockXSize || nRequestYSize < nBlockYSize))
12051186
{
12061187
memset(pImage, 0,
12071188
static_cast<size_t>(GDALGetDataTypeSizeBytes(eDataType)) *

frmts/pdf/pdfdataset.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -666,14 +666,12 @@ CPLErr PDFRasterBand::IReadBlockFromTile(int nBlockXOff, int nBlockYOff,
666666
{
667667
PDFDataset *poGDS = cpl::down_cast<PDFDataset *>(poDS);
668668

669-
int nReqXSize = nBlockXSize;
670-
int nReqYSize = nBlockYSize;
671-
if ((nBlockXOff + 1) * nBlockXSize > nRasterXSize)
672-
nReqXSize = nRasterXSize - nBlockXOff * nBlockXSize;
673-
if ((nBlockYOff + 1) * nBlockYSize > nRasterYSize)
674-
nReqYSize = nRasterYSize - nBlockYOff * nBlockYSize;
675-
676-
int nXBlocks = DIV_ROUND_UP(nRasterXSize, nBlockXSize);
669+
const int nXOff = nBlockXOff * nBlockXSize;
670+
const int nReqXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
671+
const int nYOff = nBlockYOff * nBlockYSize;
672+
const int nReqYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
673+
674+
const int nXBlocks = DIV_ROUND_UP(nRasterXSize, nBlockXSize);
677675
int iTile = poGDS->m_aiTiles[nBlockYOff * nXBlocks + nBlockXOff];
678676
if (iTile < 0)
679677
{
@@ -886,14 +884,10 @@ CPLErr PDFRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
886884
}
887885
}
888886

889-
int nReqXSize = nBlockXSize;
890-
int nReqYSize = nBlockYSize;
891-
if ((nBlockXOff + 1) * nBlockXSize > nRasterXSize)
892-
nReqXSize = nRasterXSize - nBlockXOff * nBlockXSize;
893-
if (nBlockYSize == 1)
894-
nReqYSize = nRasterYSize;
895-
else if ((nBlockYOff + 1) * nBlockYSize > nRasterYSize)
896-
nReqYSize = nRasterYSize - nBlockYOff * nBlockYSize;
887+
const int nXOff = nBlockXOff * nBlockXSize;
888+
const int nReqXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
889+
const int nYOff = nBlockYOff * nBlockYSize;
890+
const int nReqYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
897891

898892
if (!poGDS->m_bTried)
899893
{

frmts/pds/isis3dataset.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ static void FillMask(void *pvBuffer, GByte *pabyDst, int nReqXSize,
11911191
/* IReadBlock() */
11921192
/************************************************************************/
11931193

1194-
CPLErr ISISMaskBand::IReadBlock(int nXBlock, int nYBlock, void *pImage)
1194+
CPLErr ISISMaskBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
11951195

11961196
{
11971197
const GDALDataType eSrcDT = m_poBaseBand->GetRasterDataType();
@@ -1203,14 +1203,10 @@ CPLErr ISISMaskBand::IReadBlock(int nXBlock, int nYBlock, void *pImage)
12031203
return CE_Failure;
12041204
}
12051205

1206-
int nXOff = nXBlock * nBlockXSize;
1207-
int nReqXSize = nBlockXSize;
1208-
if (nXOff + nReqXSize > nRasterXSize)
1209-
nReqXSize = nRasterXSize - nXOff;
1210-
int nYOff = nYBlock * nBlockYSize;
1211-
int nReqYSize = nBlockYSize;
1212-
if (nYOff + nReqYSize > nRasterYSize)
1213-
nReqYSize = nRasterYSize - nYOff;
1206+
const int nXOff = nBlockXOff * nBlockXSize;
1207+
const int nReqXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
1208+
const int nYOff = nBlockYOff * nBlockYSize;
1209+
const int nReqYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
12141210

12151211
if (m_poBaseBand->RasterIO(GF_Read, nXOff, nYOff, nReqXSize, nReqYSize,
12161212
m_pBuffer, nReqXSize, nReqYSize, eSrcDT,

frmts/pds/pds4dataset.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ static void FillMask(void *pvBuffer, GByte *pabyDst, int nReqXSize,
533533
/* IReadBlock() */
534534
/************************************************************************/
535535

536-
CPLErr PDS4MaskBand::IReadBlock(int nXBlock, int nYBlock, void *pImage)
536+
CPLErr PDS4MaskBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
537537

538538
{
539539
const GDALDataType eSrcDT = m_poBaseBand->GetRasterDataType();
@@ -545,14 +545,10 @@ CPLErr PDS4MaskBand::IReadBlock(int nXBlock, int nYBlock, void *pImage)
545545
return CE_Failure;
546546
}
547547

548-
int nXOff = nXBlock * nBlockXSize;
549-
int nReqXSize = nBlockXSize;
550-
if (nXOff + nReqXSize > nRasterXSize)
551-
nReqXSize = nRasterXSize - nXOff;
552-
int nYOff = nYBlock * nBlockYSize;
553-
int nReqYSize = nBlockYSize;
554-
if (nYOff + nReqYSize > nRasterYSize)
555-
nReqYSize = nRasterYSize - nYOff;
548+
const int nXOff = nBlockXOff * nBlockXSize;
549+
const int nReqXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
550+
const int nYOff = nBlockYOff * nBlockYSize;
551+
const int nReqYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
556552

557553
if (m_poBaseBand->RasterIO(GF_Read, nXOff, nYOff, nReqXSize, nReqYSize,
558554
m_pBuffer, nReqXSize, nReqYSize, eSrcDT,

frmts/rs2/rs2dataset.cpp

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -215,50 +215,38 @@ CPLErr RS2RasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
215215
/* over-requesting. We also need to initialize the extra part */
216216
/* of the block to zero. */
217217
/* -------------------------------------------------------------------- */
218-
int nRequestYSize;
219-
if ((nBlockYOff + 1) * nBlockYSize > nRasterYSize)
220-
{
221-
nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize;
222-
memset(pImage, 0,
223-
static_cast<size_t>(GDALGetDataTypeSizeBytes(eDataType)) *
224-
nBlockXSize * nBlockYSize);
225-
}
226-
else
227-
{
228-
nRequestYSize = nBlockYSize;
229-
}
218+
const int nYOff = nBlockYOff * nBlockYSize;
219+
const int nRequestYSize = std::min(nBlockYSize, nRasterYSize - nYOff);
230220

231221
/*-------------------------------------------------------------------- */
232222
/* If the input imagery is tiled, also need to avoid over- */
233223
/* requesting in the X-direction. */
234224
/* ------------------------------------------------------------------- */
235-
int nRequestXSize;
236-
if ((nBlockXOff + 1) * nBlockXSize > nRasterXSize)
225+
const int nXOff = nBlockXOff * nBlockXSize;
226+
const int nRequestXSize = std::min(nBlockXSize, nRasterXSize - nXOff);
227+
228+
if (nRequestXSize < nBlockXSize || nRequestYSize < nBlockYSize)
237229
{
238-
nRequestXSize = nRasterXSize - nBlockXOff * nBlockXSize;
239230
memset(pImage, 0,
240231
static_cast<size_t>(GDALGetDataTypeSizeBytes(eDataType)) *
241232
nBlockXSize * nBlockYSize);
242233
}
243-
else
244-
{
245-
nRequestXSize = nBlockXSize;
246-
}
234+
247235
if (eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 2)
248-
return poBandFile->RasterIO(
249-
GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize,
250-
nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize,
251-
GDT_Int16, 2, nullptr, 4, nBlockXSize * 4, 2, nullptr);
236+
return poBandFile->RasterIO(GF_Read, nXOff, nYOff, nRequestXSize,
237+
nRequestYSize, pImage, nRequestXSize,
238+
nRequestYSize, GDT_Int16, 2, nullptr, 4,
239+
nBlockXSize * 4, 2, nullptr);
252240

253241
/* -------------------------------------------------------------------- */
254242
/* File has one sample marked as sample format void, a 32bits. */
255243
/* -------------------------------------------------------------------- */
256244
else if (eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 1)
257245
{
258246
CPLErr eErr = poBandFile->RasterIO(
259-
GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize,
260-
nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize,
261-
GDT_UInt32, 1, nullptr, 4, nBlockXSize * 4, 0, nullptr);
247+
GF_Read, nXOff, nYOff, nRequestXSize, nRequestYSize, pImage,
248+
nRequestXSize, nRequestYSize, GDT_UInt32, 1, nullptr, 4,
249+
nBlockXSize * 4, 0, nullptr);
262250

263251
#ifdef CPL_LSB
264252
/* First, undo the 32bit swap. */
@@ -276,16 +264,16 @@ CPLErr RS2RasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
276264
/* looks like a 16bit unsigned data too. */
277265
/* -------------------------------------------------------------------- */
278266
else if (eDataType == GDT_UInt16)
279-
return poBandFile->RasterIO(
280-
GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize,
281-
nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize,
282-
GDT_UInt16, 1, nullptr, 2, nBlockXSize * 2, 0, nullptr);
267+
return poBandFile->RasterIO(GF_Read, nXOff, nYOff, nRequestXSize,
268+
nRequestYSize, pImage, nRequestXSize,
269+
nRequestYSize, GDT_UInt16, 1, nullptr, 2,
270+
nBlockXSize * 2, 0, nullptr);
283271
else if (eDataType == GDT_UInt8)
284272
/* Ticket #2104: Support for ScanSAR products */
285-
return poBandFile->RasterIO(
286-
GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize,
287-
nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize,
288-
GDT_UInt8, 1, nullptr, 1, nBlockXSize, 0, nullptr);
273+
return poBandFile->RasterIO(GF_Read, nXOff, nYOff, nRequestXSize,
274+
nRequestYSize, pImage, nRequestXSize,
275+
nRequestYSize, GDT_UInt8, 1, nullptr, 1,
276+
nBlockXSize, 0, nullptr);
289277

290278
CPLAssert(false);
291279
return CE_Failure;

0 commit comments

Comments
 (0)