Skip to content

Commit a3a0066

Browse files
authored
Suppress unsigned-integer-overflow in code using libc++ (#13452)
should fix a number of currently opened (false positive) ossfuzz issues
2 parents 9198fa8 + 4b2beca commit a3a0066

File tree

7 files changed

+81
-34
lines changed

7 files changed

+81
-34
lines changed

frmts/pcidsk/sdk/channel/cpcidskchannel.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,27 @@ void CPCIDSKChannel::InvalidateOverviewInfo()
123123
}
124124

125125
/************************************************************************/
126-
/* SortOverviewComp() */
126+
/* SortOverviews() */
127127
/************************************************************************/
128128

129-
static bool SortOverviewComp(const std::string &first,
130-
const std::string &second)
129+
// recent libc++ std::sort() involve unsigned integer overflow in some
130+
// situation
131+
CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
132+
static void SortOverviews(std::vector<std::string>& keys)
131133
{
132-
if( !STARTS_WITH(first.c_str(), "_Overview_") ||
133-
!STARTS_WITH(second.c_str(), "_Overview_") )
134-
{
135-
return false;
136-
}
137-
int nFirst = atoi(first.c_str() + 10);
138-
int nSecond = atoi(second.c_str() + 10);
139-
return nFirst < nSecond;
134+
std::sort(keys.begin(), keys.end(),
135+
[] (const std::string &first,
136+
const std::string &second)
137+
{
138+
if( !STARTS_WITH(first.c_str(), "_Overview_") ||
139+
!STARTS_WITH(second.c_str(), "_Overview_") )
140+
{
141+
return false;
142+
}
143+
int nFirst = atoi(first.c_str() + 10);
144+
int nSecond = atoi(second.c_str() + 10);
145+
return nFirst < nSecond;
146+
});
140147
}
141148

142149
/************************************************************************/
@@ -151,7 +158,7 @@ void CPCIDSKChannel::EstablishOverviewInfo() const
151158
overviews_initialized = true;
152159

153160
std::vector<std::string> keys = GetMetadataKeys();
154-
std::sort(keys.begin(), keys.end(), SortOverviewComp); // sort overviews
161+
SortOverviews(keys);
155162
size_t i;
156163

157164
for( i = 0; i < keys.size(); i++ )

frmts/pdf/gdal_pdf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ class PDFDataset final : public GDALPamDataset
321321
std::vector<LayerStruct> m_oLayerNameSet{};
322322
CPLStringList m_aosLayerNames{};
323323

324+
void SortLayerList();
325+
324326
struct LayerWithRef
325327
{
326328
CPLString osName{};

frmts/pdf/pdfdataset.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3575,10 +3575,13 @@ void PDFDataset::AddLayer(const std::string &osName, int iPage)
35753575
}
35763576

35773577
/************************************************************************/
3578-
/* CreateLayerList() */
3578+
/* SortLayerList() */
35793579
/************************************************************************/
35803580

3581-
void PDFDataset::CreateLayerList()
3581+
// recent libc++ std::sort() involve unsigned integer overflow in some
3582+
// situation
3583+
CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
3584+
void PDFDataset::SortLayerList()
35823585
{
35833586
// Sort layers by prioritizing page number and then insertion index
35843587
std::sort(m_oLayerNameSet.begin(), m_oLayerNameSet.end(),
@@ -3590,6 +3593,15 @@ void PDFDataset::CreateLayerList()
35903593
return false;
35913594
return a.nInsertIdx < b.nInsertIdx;
35923595
});
3596+
}
3597+
3598+
/************************************************************************/
3599+
/* CreateLayerList() */
3600+
/************************************************************************/
3601+
3602+
void PDFDataset::CreateLayerList()
3603+
{
3604+
SortLayerList();
35933605

35943606
if (m_oLayerNameSet.size() >= 100)
35953607
{

frmts/wcs/wcsutils.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,12 @@ bool SetupCache(std::string &cache, bool clear)
457457
return true;
458458
}
459459

460-
static bool CompareStrings(const std::string &a, const std::string &b)
460+
// recent libc++ std::sort() involve unsigned integer overflow in some
461+
// situation
462+
CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
463+
static void SortStringList(std::vector<std::string> &strList)
461464
{
462-
return a.compare(b) < 0;
465+
std::sort(strList.begin(), strList.end());
463466
}
464467

465468
std::vector<std::string> ReadCache(const std::string &cache)
@@ -483,7 +486,7 @@ std::vector<std::string> ReadCache(const std::string &cache)
483486
}
484487
CSLDestroy(data);
485488
}
486-
std::sort(contents.begin(), contents.end(), CompareStrings);
489+
SortStringList(contents);
487490
return contents;
488491
}
489492

ogr/ogrgeometryfactory.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,17 @@ struct sPolyExtended
15561556
pBounds->maxx = poPolyEx->sEnvelope.MaxX;
15571557
pBounds->maxy = poPolyEx->sEnvelope.MaxY;
15581558
}
1559+
1560+
// recent libc++ std::sort() involve unsigned integer overflow in some
1561+
// situation
1562+
CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
1563+
static void SortByIncreasingEra(const sPolyExtended **pStart,
1564+
const sPolyExtended **pEnd)
1565+
{
1566+
std::sort(pStart, pEnd,
1567+
[](const sPolyExtended *psPoly1, const sPolyExtended *psPoly2)
1568+
{ return psPoly1->dfArea < psPoly2->dfArea; });
1569+
}
15591570
};
15601571

15611572
static bool OGRGeometryFactoryCompareAreaDescending(const sPolyExtended &sPoly1,
@@ -2026,24 +2037,21 @@ OGRGeometry *OGRGeometryFactory::organizePolygons(OGRGeometry **papoPolygons,
20262037
aoi.maxx = thisPoly.sEnvelope.MaxX;
20272038
aoi.maxy = thisPoly.sEnvelope.MaxY;
20282039
int nCandidates = 0;
2029-
std::unique_ptr<void *, decltype(&CPLFree)> aphCandidateShells(
2030-
CPLQuadTreeSearch(poQuadTree.get(), &aoi, &nCandidates), CPLFree);
2040+
std::unique_ptr<const sPolyExtended *, decltype(&CPLFree)>
2041+
aphCandidateShells(
2042+
const_cast<const sPolyExtended **>(
2043+
reinterpret_cast<sPolyExtended **>(CPLQuadTreeSearch(
2044+
poQuadTree.get(), &aoi, &nCandidates))),
2045+
CPLFree);
20312046

20322047
// Sort candidate outer rings by increasing area
2033-
std::sort(
2034-
aphCandidateShells.get(), aphCandidateShells.get() + nCandidates,
2035-
[](void *hFeature1, void *hFeature2)
2036-
{
2037-
const auto &sPoly1 = *(static_cast<sPolyExtended *>(hFeature1));
2038-
const auto &sPoly2 = *(static_cast<sPolyExtended *>(hFeature2));
2039-
return sPoly1.dfArea < sPoly2.dfArea;
2040-
});
2048+
sPolyExtended::SortByIncreasingEra(
2049+
aphCandidateShells.get(), aphCandidateShells.get() + nCandidates);
20412050

20422051
int j = 0;
20432052
for (; bValidTopology && j < nCandidates; j++)
20442053
{
2045-
const auto &otherPoly = *static_cast<const sPolyExtended *>(
2046-
(aphCandidateShells.get())[j]);
2054+
const auto &otherPoly = *(aphCandidateShells.get()[j]);
20472055

20482056
if (method == METHOD_ONLY_CCW && otherPoly.bIsCW == false)
20492057
{

ogr/ogrsf_frmts/geojson/ogrjsoncollectionstreamingparser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ void OGRJSONCollectionStreamingParser::String(std::string_view sValue)
401401
/* Number() */
402402
/************************************************************************/
403403

404+
// recent libc++ std::from_chars() involve unsigned integer overflow
405+
CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
404406
void OGRJSONCollectionStreamingParser::Number(std::string_view sValue)
405407
{
406408
if (m_nMaxObjectSize > 0 && m_nCurObjMemEstimate > m_nMaxObjectSize)

ogr/ogrsf_frmts/openfilegdb/filegdbindex_write.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,23 @@ void FileGDBTable::ComputeOptimalSpatialIndexGridResolution()
420420
}
421421
}
422422

423+
/************************************************************************/
424+
/* SortByAscendingValuesAndOID() */
425+
/************************************************************************/
426+
427+
// recent libc++ std::sort() involve unsigned integer overflow in some
428+
// situation
429+
template <class ValueOIDPair>
430+
CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW static void
431+
SortByAscendingValuesAndOID(std::vector<ValueOIDPair> &asValues)
432+
{
433+
std::sort(asValues.begin(), asValues.end(),
434+
[](const ValueOIDPair &a, const ValueOIDPair &b) {
435+
return a.first < b.first ||
436+
(a.first == b.first && a.second < b.second);
437+
});
438+
}
439+
423440
/************************************************************************/
424441
/* WriteIndex() */
425442
/************************************************************************/
@@ -476,11 +493,7 @@ static bool WriteIndex(
476493
}
477494

478495
// Sort by ascending values, and for same value by ascending OID
479-
std::sort(asValues.begin(), asValues.end(),
480-
[](const ValueOIDPair &a, const ValueOIDPair &b) {
481-
return a.first < b.first ||
482-
(a.first == b.first && a.second < b.second);
483-
});
496+
SortByAscendingValuesAndOID(asValues);
484497

485498
bool bRet = true;
486499
std::vector<GByte> abyPage;

0 commit comments

Comments
 (0)