Skip to content

Commit

Permalink
Merge pull request #9210 from rouault/backport_9207
Browse files Browse the repository at this point in the history
[Backport 3.8] ODS: fix parsing of large cells on Windows (at least with mingw64) with new expat 2.6.0 release
  • Loading branch information
rouault authored Feb 7, 2024
2 parents a1d8d1f + 0711a96 commit e7b3d86
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 108 deletions.
2 changes: 2 additions & 0 deletions ogr/ogrsf_frmts/georss/ogr_georss.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include "ogr_expat.h"
#endif

constexpr int PARSER_BUF_SIZE = 8192;

class OGRGeoRSSDataSource;

typedef enum
Expand Down
21 changes: 11 additions & 10 deletions ogr/ogrsf_frmts/georss/ogrgeorssdatasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void OGRGeoRSSDataSource::dataHandlerValidateCbk(const char * /* data */,
int /* nLen */)
{
nDataHandlerCounter++;
if (nDataHandlerCounter >= BUFSIZ)
if (nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down Expand Up @@ -270,7 +270,7 @@ int OGRGeoRSSDataSource::Open(const char *pszFilename, int bUpdateIn)
XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
oCurrentParser = oParser;

char aBuf[BUFSIZ];
std::vector<char> aBuf(PARSER_BUF_SIZE);
int nDone = 0;
unsigned int nLen = 0;
int nCount = 0;
Expand All @@ -282,18 +282,19 @@ int OGRGeoRSSDataSource::Open(const char *pszFilename, int bUpdateIn)
do
{
nDataHandlerCounter = 0;
nLen = static_cast<unsigned int>(VSIFReadL(aBuf, 1, sizeof(aBuf), fp));
nLen = static_cast<unsigned int>(
VSIFReadL(aBuf.data(), 1, aBuf.size(), fp));
nDone = VSIFEofL(fp);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
if (nLen <= BUFSIZ - 1)
if (nLen <= PARSER_BUF_SIZE - 1)
aBuf[nLen] = 0;
else
aBuf[BUFSIZ - 1] = 0;
aBuf[PARSER_BUF_SIZE - 1] = 0;

if (strstr(aBuf, "<?xml") &&
(strstr(aBuf, "<rss") || strstr(aBuf, "<feed") ||
strstr(aBuf, "<atom:feed")))
if (strstr(aBuf.data(), "<?xml") &&
(strstr(aBuf.data(), "<rss") || strstr(aBuf.data(), "<feed") ||
strstr(aBuf.data(), "<atom:feed")))
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of GeoRSS file failed: "
Expand All @@ -315,7 +316,7 @@ int OGRGeoRSSDataSource::Open(const char *pszFilename, int bUpdateIn)
}
else
{
// After reading 50 * BUFSIZ bytes, and not finding whether the file
// After reading 50 * PARSER_BUF_SIZE bytes, and not finding whether the file
// is GeoRSS or not, we give up and fail silently.
nCount++;
if (nCount == 50)
Expand Down
15 changes: 8 additions & 7 deletions ogr/ogrsf_frmts/georss/ogrgeorsslayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,13 +977,13 @@ OGRFeature *OGRGeoRSSLayer::GetNextFeature()
nFeatureTabIndex = 0;

int nDone = 0;
char aBuf[BUFSIZ];
std::vector<char> aBuf(PARSER_BUF_SIZE);
do
{
unsigned int nLen = static_cast<unsigned int>(
VSIFReadL(aBuf, 1, sizeof(aBuf), fpGeoRSS));
VSIFReadL(aBuf.data(), 1, aBuf.size(), fpGeoRSS));
nDone = VSIFEofL(fpGeoRSS);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of GeoRSS file failed : %s "
Expand Down Expand Up @@ -1785,15 +1785,16 @@ void OGRGeoRSSLayer::LoadSchema()
nTotalFeatureCount = 0;
setOfFoundFields = nullptr;

char aBuf[BUFSIZ] = {};
std::vector<char> aBuf(PARSER_BUF_SIZE);
int nDone = 0;
do
{
nDataHandlerCounter = 0;
unsigned int nLen =
(unsigned int)VSIFReadL(aBuf, 1, sizeof(aBuf), fpGeoRSS);
(unsigned int)VSIFReadL(aBuf.data(), 1, aBuf.size(), fpGeoRSS);
nDone = VSIFEofL(fpGeoRSS);
if (XML_Parse(oSchemaParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oSchemaParser, aBuf.data(), nLen, nDone) ==
XML_STATUS_ERROR)
{
CPLError(
CE_Failure, CPLE_AppDefined,
Expand Down Expand Up @@ -2209,7 +2210,7 @@ void OGRGeoRSSLayer::dataHandlerLoadSchemaCbk(const char *data, int nLen)
return;

nDataHandlerCounter++;
if (nDataHandlerCounter >= BUFSIZ)
if (nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down
2 changes: 2 additions & 0 deletions ogr/ogrsf_frmts/gpx/ogr_gpx.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ typedef enum
GPX_TRACK_POINT,
} GPXGeometryType;

constexpr int PARSER_BUF_SIZE = 8192;

/************************************************************************/
/* OGRGPXLayer */
/************************************************************************/
Expand Down
17 changes: 9 additions & 8 deletions ogr/ogrsf_frmts/gpx/ogrgpxdatasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ void OGRGPXDataSource::dataHandlerValidateCbk(const char *data, int nLen)
}

nDataHandlerCounter++;
if (nDataHandlerCounter >= BUFSIZ)
if (nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down Expand Up @@ -509,7 +509,7 @@ int OGRGPXDataSource::Open(const char *pszFilename, int bUpdateIn)
::endElementValidateCbk);
XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);

char aBuf[BUFSIZ];
std::vector<char> aBuf(PARSER_BUF_SIZE);
int nDone = 0;
unsigned int nLen = 0;
int nCount = 0;
Expand All @@ -522,16 +522,17 @@ int OGRGPXDataSource::Open(const char *pszFilename, int bUpdateIn)
do
{
nDataHandlerCounter = 0;
nLen = static_cast<unsigned int>(VSIFReadL(aBuf, 1, sizeof(aBuf), fp));
nLen = static_cast<unsigned int>(
VSIFReadL(aBuf.data(), 1, aBuf.size(), fp));
nTotalBytesRead += nLen;
nDone = VSIFEofL(fp);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
if (nLen <= BUFSIZ - 1)
if (nLen <= PARSER_BUF_SIZE - 1)
aBuf[nLen] = 0;
else
aBuf[BUFSIZ - 1] = 0;
if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
aBuf[PARSER_BUF_SIZE - 1] = 0;
if (strstr(aBuf.data(), "<?xml") && strstr(aBuf.data(), "<gpx"))
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of GPX file failed : %s at line %d, "
Expand Down Expand Up @@ -559,7 +560,7 @@ int OGRGPXDataSource::Open(const char *pszFilename, int bUpdateIn)
}
else
{
// After reading 50 * BUFSIZE bytes, and not finding whether the
// After reading 50 * PARSER_BUF_SIZE bytes, and not finding whether the
// file is GPX or not, we give up and fail silently.
nCount++;
if (nCount == 50)
Expand Down
22 changes: 11 additions & 11 deletions ogr/ogrsf_frmts/gpx/ogrgpxlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ void OGRGPXLayer::dataHandlerCbk(const char *data, int nLen)
return;

nDataHandlerCounter++;
if (nDataHandlerCounter >= BUFSIZ)
if (nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down Expand Up @@ -1102,8 +1102,7 @@ OGRFeature *OGRGPXLayer::GetNextFeature()
if (VSIFEofL(fpGPX))
return nullptr;

char aBuf[BUFSIZ];

std::vector<char> aBuf(PARSER_BUF_SIZE);
CPLFree(ppoFeatureTab);
ppoFeatureTab = nullptr;
nFeatureTabLength = 0;
Expand All @@ -1114,10 +1113,10 @@ OGRFeature *OGRGPXLayer::GetNextFeature()
do
{
nDataHandlerCounter = 0;
unsigned int nLen =
static_cast<unsigned int>(VSIFReadL(aBuf, 1, sizeof(aBuf), fpGPX));
unsigned int nLen = static_cast<unsigned int>(
VSIFReadL(aBuf.data(), 1, aBuf.size(), fpGPX));
nDone = VSIFEofL(fpGPX);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of GPX file failed : "
Expand Down Expand Up @@ -1960,15 +1959,16 @@ void OGRGPXLayer::LoadExtensionsSchema()
nWithoutEventCounter = 0;
bStopParsing = false;

char aBuf[BUFSIZ];
std::vector<char> aBuf(PARSER_BUF_SIZE);
int nDone = 0;
do
{
nDataHandlerCounter = 0;
unsigned int nLen =
static_cast<unsigned int>(VSIFReadL(aBuf, 1, sizeof(aBuf), fpGPX));
unsigned int nLen = static_cast<unsigned int>(
VSIFReadL(aBuf.data(), 1, aBuf.size(), fpGPX));
nDone = VSIFEofL(fpGPX);
if (XML_Parse(oSchemaParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oSchemaParser, aBuf.data(), nLen, nDone) ==
XML_STATUS_ERROR)
{
CPLError(
CE_Failure, CPLE_AppDefined,
Expand Down Expand Up @@ -2218,7 +2218,7 @@ void OGRGPXLayer::dataHandlerLoadSchemaCbk(const char *data, int nLen)
return;

nDataHandlerCounter++;
if (nDataHandlerCounter >= BUFSIZ)
if (nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down
19 changes: 11 additions & 8 deletions ogr/ogrsf_frmts/jml/ogrjmllayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "ogr_jml.h"
#include "ogr_p.h"

constexpr int PARSER_BUF_SIZE = 8192;

#ifdef HAVE_EXPAT

/************************************************************************/
Expand Down Expand Up @@ -397,7 +399,7 @@ void OGRJMLLayer::dataHandlerCbk(const char *data, int nLen)
return;

nDataHandlerCounter++;
if (nDataHandlerCounter >= BUFSIZ)
if (nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down Expand Up @@ -434,7 +436,7 @@ OGRFeature *OGRJMLLayer::GetNextFeature()
if (VSIFEofL(fp))
return nullptr;

char aBuf[BUFSIZ];
std::vector<char> aBuf(PARSER_BUF_SIZE);

nFeatureTabLength = 0;
nFeatureTabIndex = 0;
Expand All @@ -445,9 +447,10 @@ OGRFeature *OGRJMLLayer::GetNextFeature()
do
{
nDataHandlerCounter = 0;
unsigned int nLen = (unsigned int)VSIFReadL(aBuf, 1, sizeof(aBuf), fp);
unsigned int nLen =
(unsigned int)VSIFReadL(aBuf.data(), 1, aBuf.size(), fp);
nDone = VSIFEofL(fp);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of JML file failed : %s "
Expand Down Expand Up @@ -505,15 +508,15 @@ void OGRJMLLayer::LoadSchema()

VSIFSeekL(fp, 0, SEEK_SET);

char aBuf[BUFSIZ];
std::vector<char> aBuf(PARSER_BUF_SIZE);
int nDone = 0;
do
{
nDataHandlerCounter = 0;
const unsigned int nLen =
static_cast<unsigned int>(VSIFReadL(aBuf, 1, sizeof(aBuf), fp));
const unsigned int nLen = static_cast<unsigned int>(
VSIFReadL(aBuf.data(), 1, aBuf.size(), fp));
nDone = VSIFEofL(fp);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of JML file failed : %s at line %d, "
Expand Down
32 changes: 18 additions & 14 deletions ogr/ogrsf_frmts/kml/kml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include "expat.h"
#endif

constexpr int PARSER_BUF_SIZE = 8192;

KML::KML()
: poTrunk_(nullptr), nNumLayers_(-1), papoLayers_(nullptr), nDepth_(0),
validity(KML_VALIDITY_UNKNOWN), pKMLFile_(nullptr), poCurrent_(nullptr),
Expand Down Expand Up @@ -95,15 +97,15 @@ bool KML::parse()

int nDone = 0;
int nLen = 0;
char aBuf[BUFSIZ] = {0};
std::vector<char> aBuf(PARSER_BUF_SIZE);
bool bError = false;

do
{
nDataHandlerCounter = 0;
nLen = (int)VSIFReadL(aBuf, 1, sizeof(aBuf), pKMLFile_);
nLen = (int)VSIFReadL(aBuf.data(), 1, aBuf.size(), pKMLFile_);
nDone = VSIFEofL(pKMLFile_);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
CPLError(CE_Failure, CPLE_AppDefined,
"XML parsing of KML file failed : %s at line %d, "
Expand Down Expand Up @@ -184,23 +186,25 @@ void KML::checkValidity()

int nDone = 0;
int nLen = 0;
char aBuf[BUFSIZ] = {0};
std::vector<char> aBuf(PARSER_BUF_SIZE);

// Parses the file until we find the first element.
do
{
nDataHandlerCounter = 0;
nLen = static_cast<int>(VSIFReadL(aBuf, 1, sizeof(aBuf), pKMLFile_));
nLen =
static_cast<int>(VSIFReadL(aBuf.data(), 1, aBuf.size(), pKMLFile_));
nDone = VSIFEofL(pKMLFile_);
if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
if (XML_Parse(oParser, aBuf.data(), nLen, nDone) == XML_STATUS_ERROR)
{
if (nLen <= BUFSIZ - 1)
if (nLen <= PARSER_BUF_SIZE - 1)
aBuf[nLen] = 0;
else
aBuf[BUFSIZ - 1] = 0;
if (strstr(aBuf, "<?xml") &&
(strstr(aBuf, "<kml") ||
(strstr(aBuf, "<Document") && strstr(aBuf, "/kml/2."))))
aBuf[PARSER_BUF_SIZE - 1] = 0;
if (strstr(aBuf.data(), "<?xml") &&
(strstr(aBuf.data(), "<kml") ||
(strstr(aBuf.data(), "<Document") &&
strstr(aBuf.data(), "/kml/2."))))
{
CPLError(
CE_Failure, CPLE_AppDefined,
Expand All @@ -217,7 +221,7 @@ void KML::checkValidity()
}

nCount++;
/* After reading 50 * BUFSIZE bytes, and not finding whether the file */
/* After reading 50 * PARSER_BUF_SIZE bytes, and not finding whether the file */
/* is KML or not, we give up and fail silently */
} while (!nDone && nLen > 0 && validity == KML_VALIDITY_UNKNOWN &&
nCount < 50);
Expand Down Expand Up @@ -370,7 +374,7 @@ void XMLCALL KML::dataHandlerValidate(void *pUserData,
KML *poKML = static_cast<KML *>(pUserData);

poKML->nDataHandlerCounter++;
if (poKML->nDataHandlerCounter >= BUFSIZ)
if (poKML->nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down Expand Up @@ -535,7 +539,7 @@ void XMLCALL KML::dataHandler(void *pUserData, const char *pszData, int nLen)
return;

poKML->nDataHandlerCounter++;
if (poKML->nDataHandlerCounter >= BUFSIZ)
if (poKML->nDataHandlerCounter >= PARSER_BUF_SIZE)
{
CPLError(CE_Failure, CPLE_AppDefined,
"File probably corrupted (million laugh pattern)");
Expand Down
3 changes: 2 additions & 1 deletion ogr/ogrsf_frmts/lvbag/ogr_lvbag.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ using LayerVector = std::vector<std::pair<LayerType, OGRLayerUniquePtr>>;
/************************************************************************/
/* OGRLVBAGLayer */
/************************************************************************/
constexpr int PARSER_BUF_SIZE = 8192;

class OGRLVBAGLayer final : public OGRAbstractProxiedLayer,
public OGRGetNextFeatureThroughRaw<OGRLVBAGLayer>
Expand Down Expand Up @@ -103,7 +104,7 @@ class OGRLVBAGLayer final : public OGRAbstractProxiedLayer,
CPLString osAttributeString;
bool bCollectData;

char aBuf[BUFSIZ];
std::vector<char> aBuf = std::vector<char>(PARSER_BUF_SIZE);

void AddSpatialRef(OGRwkbGeometryType eTypeIn);
void AddOccurrenceFieldDefn();
Expand Down
Loading

0 comments on commit e7b3d86

Please sign in to comment.