Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 3.8] ODS: fix parsing of large cells on Windows (at least with mingw64) with new expat 2.6.0 release #9210

Merged
merged 8 commits into from
Feb 7, 2024
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
Loading