From 9f2d1974e5be4c4382c0118ed83bcd24708fa4aa Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Dec 2024 02:44:42 +0100 Subject: [PATCH 1/5] port/: fix cppcheck nullPointerOutOfMemory --- port/cpl_minizip_unzip.cpp | 5 +++ port/cpl_vsisimple.cpp | 90 ++++++++++++++++++++------------------ port/vsipreload.cpp | 5 +++ 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/port/cpl_minizip_unzip.cpp b/port/cpl_minizip_unzip.cpp index 4a5311945016..a0846eae2caf 100644 --- a/port/cpl_minizip_unzip.cpp +++ b/port/cpl_minizip_unzip.cpp @@ -692,6 +692,11 @@ extern unzFile ZEXPORT cpl_unzOpen2(const char *path, us.current_file_ok = 0; s = static_cast(ALLOC(sizeof(unz_s))); + if (!s) + { + ZCLOSE(us.z_filefunc, us.filestream); + return nullptr; + } *s = us; cpl_unzGoToFirstFile(reinterpret_cast(s)); return reinterpret_cast(s); diff --git a/port/cpl_vsisimple.cpp b/port/cpl_vsisimple.cpp index 4ee1216a3fe7..c78a3dd49993 100644 --- a/port/cpl_vsisimple.cpp +++ b/port/cpl_vsisimple.cpp @@ -1406,32 +1406,35 @@ GIntBig CPLGetPhysicalRAM(void) // which seems to be necessary for some container solutions // Cf https://lists.osgeo.org/pipermail/gdal-dev/2023-January/056784.html FILE *f = fopen("/proc/meminfo", "rb"); - char szLine[256]; - while (fgets(szLine, sizeof(szLine), f)) + if (f) { - // Find line like "MemTotal: 32525176 kB" - if (strncmp(szLine, "MemTotal:", strlen("MemTotal:")) == 0) + char szLine[256]; + while (fgets(szLine, sizeof(szLine), f)) { - char *pszVal = szLine + strlen("MemTotal:"); - pszVal += strspn(pszVal, " "); - char *pszEnd = strstr(pszVal, " kB"); - if (pszEnd) + // Find line like "MemTotal: 32525176 kB" + if (strncmp(szLine, "MemTotal:", strlen("MemTotal:")) == 0) { - *pszEnd = 0; - if (CPLGetValueType(pszVal) == CPL_VALUE_INTEGER) + char *pszVal = szLine + strlen("MemTotal:"); + pszVal += strspn(pszVal, " "); + char *pszEnd = strstr(pszVal, " kB"); + if (pszEnd) { - const GUIntBig nLimit = - CPLScanUIntBig(pszVal, - static_cast(strlen(pszVal))) * - 1024; - nVal = static_cast( - std::min(static_cast(nVal), nLimit)); + *pszEnd = 0; + if (CPLGetValueType(pszVal) == CPL_VALUE_INTEGER) + { + const GUIntBig nLimit = + CPLScanUIntBig( + pszVal, static_cast(strlen(pszVal))) * + 1024; + nVal = static_cast( + std::min(static_cast(nVal), nLimit)); + } } + break; } - break; } + fclose(f); } - fclose(f); } char szGroupName[256]; @@ -1439,34 +1442,37 @@ GIntBig CPLGetPhysicalRAM(void) szGroupName[0] = 0; { FILE *f = fopen("/proc/self/cgroup", "rb"); - char szLine[256]; - // Find line like "6:memory:/user.slice/user-1000.slice/user@1000.service" - // and store "/user.slice/user-1000.slice/user@1000.service" in - // szMemoryPath for cgroup V1 or single line "0::/...." for cgroup V2. - while (fgets(szLine, sizeof(szLine), f)) + if (f) { - const char *pszMemory = strstr(szLine, ":memory:"); - if (pszMemory) + char szLine[256]; + // Find line like "6:memory:/user.slice/user-1000.slice/user@1000.service" + // and store "/user.slice/user-1000.slice/user@1000.service" in + // szMemoryPath for cgroup V1 or single line "0::/...." for cgroup V2. + while (fgets(szLine, sizeof(szLine), f)) { - bFromMemory = true; - snprintf(szGroupName, sizeof(szGroupName), "%s", - pszMemory + strlen(":memory:")); - char *pszEOL = strchr(szGroupName, '\n'); - if (pszEOL) - *pszEOL = '\0'; - break; - } - if (strncmp(szLine, "0::", strlen("0::")) == 0) - { - snprintf(szGroupName, sizeof(szGroupName), "%s", - szLine + strlen("0::")); - char *pszEOL = strchr(szGroupName, '\n'); - if (pszEOL) - *pszEOL = '\0'; - break; + const char *pszMemory = strstr(szLine, ":memory:"); + if (pszMemory) + { + bFromMemory = true; + snprintf(szGroupName, sizeof(szGroupName), "%s", + pszMemory + strlen(":memory:")); + char *pszEOL = strchr(szGroupName, '\n'); + if (pszEOL) + *pszEOL = '\0'; + break; + } + if (strncmp(szLine, "0::", strlen("0::")) == 0) + { + snprintf(szGroupName, sizeof(szGroupName), "%s", + szLine + strlen("0::")); + char *pszEOL = strchr(szGroupName, '\n'); + if (pszEOL) + *pszEOL = '\0'; + break; + } } + fclose(f); } - fclose(f); } if (szGroupName[0]) { diff --git a/port/vsipreload.cpp b/port/vsipreload.cpp index 1e8294678a32..cab537f79b3f 100644 --- a/port/vsipreload.cpp +++ b/port/vsipreload.cpp @@ -1597,6 +1597,11 @@ DIR CPL_DLL *opendir(const char *name) { VSIDIRPreload *mydir = static_cast(malloc(sizeof(VSIDIRPreload))); + if (!mydir) + { + CSLDestroy(papszDir); + return nullptr; + } mydir->pszDirname = CPLStrdup(name); mydir->papszDir = papszDir; mydir->nIter = 0; From 13fe7d0ec353fa019143f3543e67523a5e0c76d8 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Dec 2024 02:44:59 +0100 Subject: [PATCH 2/5] northwood: fix cppcheck nullPointerOutOfMemory --- frmts/northwood/grcdataset.cpp | 12 ++++++++++-- frmts/northwood/grddataset.cpp | 19 ++++++++++++++++--- frmts/northwood/northwood.cpp | 28 ++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/frmts/northwood/grcdataset.cpp b/frmts/northwood/grcdataset.cpp index e7a6c4b378d6..fbfcfe83df81 100644 --- a/frmts/northwood/grcdataset.cpp +++ b/frmts/northwood/grcdataset.cpp @@ -241,8 +241,11 @@ NWT_GRCDataset::~NWT_GRCDataset() CSLDestroy(papszCategories); NWT_GRCDataset::FlushCache(true); - pGrd->fp = nullptr; // this prevents nwtCloseGrid from closing the fp - nwtCloseGrid(pGrd); + if (pGrd) + { + pGrd->fp = nullptr; // this prevents nwtCloseGrid from closing the fp + nwtCloseGrid(pGrd); + } if (fp != nullptr) VSIFCloseL(fp); @@ -326,6 +329,11 @@ GDALDataset *NWT_GRCDataset::Open(GDALOpenInfo *poOpenInfo) VSIFSeekL(poDS->fp, 0, SEEK_SET); VSIFReadL(poDS->abyHeader, 1, 1024, poDS->fp); poDS->pGrd = static_cast(malloc(sizeof(NWT_GRID))); + if (!poDS->pGrd) + { + delete poDS; + return nullptr; + } poDS->pGrd->fp = poDS->fp; diff --git a/frmts/northwood/grddataset.cpp b/frmts/northwood/grddataset.cpp index 2c48e99eaf29..6d0a4d0840ea 100644 --- a/frmts/northwood/grddataset.cpp +++ b/frmts/northwood/grddataset.cpp @@ -446,8 +446,11 @@ NWT_GRDDataset::~NWT_GRDDataset() { NWT_GRDDataset::FlushCache(true); } - pGrd->fp = nullptr; // this prevents nwtCloseGrid from closing the fp - nwtCloseGrid(pGrd); + if (pGrd) + { + pGrd->fp = nullptr; // this prevents nwtCloseGrid from closing the fp + nwtCloseGrid(pGrd); + } if (m_poSRS) m_poSRS->Release(); @@ -461,7 +464,7 @@ NWT_GRDDataset::~NWT_GRDDataset() CPLErr NWT_GRDDataset::FlushCache(bool bAtClosing) { // Ensure the header and TAB file are up to date - if (bUpdateHeader) + if (bUpdateHeader && pGrd) { #ifndef NO_MITAB_SUPPORT UpdateHeader(); @@ -625,6 +628,11 @@ GDALDataset *NWT_GRDDataset::Open(GDALOpenInfo *poOpenInfo) VSIFSeekL(poDS->fp, 0, SEEK_SET); VSIFReadL(poDS->abyHeader, 1, 1024, poDS->fp); poDS->pGrd = reinterpret_cast(calloc(1, sizeof(NWT_GRID))); + if (!poDS->pGrd) + { + delete poDS; + return nullptr; + } poDS->pGrd->fp = poDS->fp; @@ -902,6 +910,11 @@ GDALDataset *NWT_GRDDataset::Create(const char *pszFilename, int nXSize, NWT_GRDDataset *poDS = new NWT_GRDDataset(); poDS->eAccess = GA_Update; poDS->pGrd = static_cast(calloc(1, sizeof(NWT_GRID))); + if (!poDS->pGrd) + { + delete poDS; + return nullptr; + } // We currently only support GRD grid types (could potentially support GRC // in the papszParamList). Also only support GDT_Float32 as the data type. diff --git a/frmts/northwood/northwood.cpp b/frmts/northwood/northwood.cpp index 12cac62e8e89..0d344f72dfb0 100644 --- a/frmts/northwood/northwood.cpp +++ b/frmts/northwood/northwood.cpp @@ -171,6 +171,10 @@ int nwt_ParseHeader(NWT_GRID *pGrd, const unsigned char *nwtHeader) CPL_LSBPTR16(&usTmp); pGrd->stClassDict = reinterpret_cast( calloc(1, sizeof(NWT_CLASSIFIED_DICT))); + if (!pGrd->stClassDict) + { + return FALSE; + } pGrd->stClassDict->nNumClassifiedItems = usTmp; @@ -178,6 +182,11 @@ int nwt_ParseHeader(NWT_GRID *pGrd, const unsigned char *nwtHeader) reinterpret_cast( calloc(pGrd->stClassDict->nNumClassifiedItems + 1, sizeof(NWT_CLASSIFIED_ITEM *))); + if (!pGrd->stClassDict->stClassifiedItem) + { + pGrd->stClassDict->nNumClassifiedItems = 0; + return FALSE; + } // load the dictionary for (unsigned int iItem = 0; @@ -187,6 +196,10 @@ int nwt_ParseHeader(NWT_GRID *pGrd, const unsigned char *nwtHeader) pGrd->stClassDict->stClassifiedItem[iItem] = reinterpret_cast( calloc(1, sizeof(NWT_CLASSIFIED_ITEM))); + if (!psItem) + { + return FALSE; + } unsigned char cTmp[256]; if (!VSIFReadL(&cTmp, 9, 1, pGrd->fp)) @@ -404,13 +417,24 @@ NWT_GRID *nwtOpenGrid(char *filename) } if (!VSIFReadL(nwtHeader, 1024, 1, fp)) + { + VSIFCloseL(fp); return nullptr; + } if (nwtHeader[0] != 'H' || nwtHeader[1] != 'G' || nwtHeader[2] != 'P' || nwtHeader[3] != 'C') + { + VSIFCloseL(fp); return nullptr; + } NWT_GRID *pGrd = reinterpret_cast(calloc(1, sizeof(NWT_GRID))); + if (!pGrd) + { + VSIFCloseL(fp); + return nullptr; + } if (nwtHeader[4] == '1') pGrd->cFormat = 0x00; // grd - surface type @@ -420,8 +444,8 @@ NWT_GRID *nwtOpenGrid(char *filename) { CPLError(CE_Failure, CPLE_NotSupported, "Unhandled Northwood format type = %0xd", nwtHeader[4]); - if (pGrd) - free(pGrd); + VSIFCloseL(fp); + free(pGrd); return nullptr; } From 8bea7c75ce310f96a1ce4412c05123cd6e7a8f71 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Dec 2024 02:45:11 +0100 Subject: [PATCH 3/5] iso8211: fix cppcheck nullPointerOutOfMemory --- frmts/iso8211/8211createfromxml.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frmts/iso8211/8211createfromxml.cpp b/frmts/iso8211/8211createfromxml.cpp index 598a116b92e1..d2b801ddfb15 100644 --- a/frmts/iso8211/8211createfromxml.cpp +++ b/frmts/iso8211/8211createfromxml.cpp @@ -262,7 +262,7 @@ int main(int nArgc, char *papszArgv[]) { pszValue += 2; int nDataLen = (int)strlen(pszValue) / 2; - char *pabyData = (char *)malloc(nDataLen); + char *pabyData = (char *)CPLMalloc(nDataLen); for (int i = 0; i < nDataLen; i++) { char c; @@ -281,7 +281,7 @@ int main(int nArgc, char *papszArgv[]) } poRec->SetFieldRaw(poField, nFieldOcc, (const char *)pabyData, nDataLen); - free(pabyData); + CPLFree(pabyData); } else { @@ -330,7 +330,8 @@ int main(int nArgc, char *papszArgv[]) pszSubfieldValue += 2; int nDataLen = (int)strlen(pszSubfieldValue) / 2; - char *pabyData = (char *)malloc(nDataLen); + char *pabyData = + (char *)CPLMalloc(nDataLen); for (int i = 0; i < nDataLen; i++) { int nHigh; @@ -351,7 +352,7 @@ int main(int nArgc, char *papszArgv[]) pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pabyData, nDataLen); - free(pabyData); + CPLFree(pabyData); } } psSubfieldIter = psSubfieldIter->psNext; From 378cda26302049ff4922991cf3befaed762f74c6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Dec 2024 02:45:21 +0100 Subject: [PATCH 4/5] degrib: fix cppcheck nullPointerOutOfMemory --- frmts/grib/degrib/degrib/degrib1.cpp | 5 +++++ frmts/grib/degrib/degrib/metaparse.cpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/frmts/grib/degrib/degrib/degrib1.cpp b/frmts/grib/degrib/degrib/degrib1.cpp index 59bc47d4eb08..f44a7329de4c 100644 --- a/frmts/grib/degrib/degrib/degrib1.cpp +++ b/frmts/grib/degrib/degrib/degrib1.cpp @@ -834,6 +834,11 @@ int GRIB1_RefTime (VSILFILE *fp, uInt4 gribLen, double *refTime) return -1; } pds = (uChar *) malloc (sectLen * sizeof (uChar)); + if(!pds) + { + errSprintf("Out of memory"); + return -1; + } *pds = *temp; pds[1] = temp[1]; pds[2] = temp[2]; diff --git a/frmts/grib/degrib/degrib/metaparse.cpp b/frmts/grib/degrib/degrib/metaparse.cpp index cccc549de05a..b8f9e032ef88 100644 --- a/frmts/grib/degrib/degrib/metaparse.cpp +++ b/frmts/grib/degrib/degrib/metaparse.cpp @@ -475,6 +475,10 @@ static int ParseSect2_Wx (float *rdat, sInt4 nrdat, sInt4 *idat, buffLen = 0; buffer = (char *) malloc ((nidat + 1) * sizeof (char)); + if( !buffer ) { + errSprintf ("Out of memory\n"); + return -1; + } while (groupLen > 0) { for (j = 0; j < groupLen; j++) { buffer[buffLen] = (char) idat[loc]; @@ -600,6 +604,10 @@ static int ParseSect2_Hazard (float *rdat, sInt4 nrdat, sInt4 *idat, buffLen = 0; buffer = (char *) malloc ((nidat + 1) * sizeof (char)); + if (!buffer) { + errSprintf ("Out of memory\n"); + return -1; + } while (groupLen > 0) { for (j = 0; j < groupLen; j++) { buffer[buffLen] = (char) idat[loc]; From 0ceac29509fdae4d3645f3e59a60bae57963b762 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Dec 2024 02:49:14 +0100 Subject: [PATCH 5/5] shapelib: fix cppcheck nullPointerOutOfMemory --- ogr/ogrsf_frmts/shape/dbfopen.c | 238 ++++++++++++++++++++++-------- ogr/ogrsf_frmts/shape/sbnsearch.c | 2 + ogr/ogrsf_frmts/shape/shpopen.c | 122 +++++++++++---- ogr/ogrsf_frmts/shape/shptree.c | 2 + 4 files changed, 276 insertions(+), 88 deletions(-) diff --git a/ogr/ogrsf_frmts/shape/dbfopen.c b/ogr/ogrsf_frmts/shape/dbfopen.c index 8bac07247992..2486875c1941 100644 --- a/ogr/ogrsf_frmts/shape/dbfopen.c +++ b/ogr/ogrsf_frmts/shape/dbfopen.c @@ -355,10 +355,19 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, /* -------------------------------------------------------------------- */ const int nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename); char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + if (!pszFullname) + { + return SHPLIB_NULLPTR; + } memcpy(pszFullname, pszFilename, nLenWithoutExtension); memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5); DBFHandle psDBF = STATIC_CAST(DBFHandle, calloc(1, sizeof(DBFInfo))); + if (!psDBF) + { + free(pszFullname); + return SHPLIB_NULLPTR; + } psDBF->fp = psHooks->FOpen(pszFullname, pszAccess, psHooks->pvUserData); memcpy(&(psDBF->sHooks), psHooks, sizeof(SAHooks)); @@ -396,6 +405,14 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, /* -------------------------------------------------------------------- */ const int nBufSize = 500; unsigned char *pabyBuf = STATIC_CAST(unsigned char *, malloc(nBufSize)); + if (!pabyBuf) + { + psDBF->sHooks.FClose(psDBF->fp); + if (pfCPG) + psHooks->FClose(pfCPG); + free(psDBF); + return SHPLIB_NULLPTR; + } if (psDBF->sHooks.FRead(pabyBuf, XBASE_FILEHDR_SZ, 1, psDBF->fp) != 1) { psDBF->sHooks.FClose(psDBF->fp); @@ -431,6 +448,15 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, /* coverity[tainted_data] */ psDBF->pszCurrentRecord = STATIC_CAST(char *, malloc(psDBF->nRecordLength)); + if (!psDBF->pszCurrentRecord) + { + psDBF->sHooks.FClose(psDBF->fp); + if (pfCPG) + psDBF->sHooks.FClose(pfCPG); + free(pabyBuf); + free(psDBF); + return SHPLIB_NULLPTR; + } /* -------------------------------------------------------------------- */ /* Figure out the code page from the LDID and CPG */ @@ -445,7 +471,8 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, { pabyBuf[n] = '\0'; psDBF->pszCodePage = STATIC_CAST(char *, malloc(n + 1)); - memcpy(psDBF->pszCodePage, pabyBuf, n + 1); + if (psDBF->pszCodePage) + memcpy(psDBF->pszCodePage, pabyBuf, n + 1); } psDBF->sHooks.FClose(pfCPG); } @@ -455,13 +482,26 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, psDBF->iLanguageDriver); psDBF->pszCodePage = STATIC_CAST( char *, malloc(strlen(REINTERPRET_CAST(char *, pabyBuf)) + 1)); - strcpy(psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf)); + if (psDBF->pszCodePage) + strcpy(psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf)); } /* -------------------------------------------------------------------- */ /* Read in Field Definitions */ /* -------------------------------------------------------------------- */ - pabyBuf = STATIC_CAST(unsigned char *, realloc(pabyBuf, nHeadLen)); + + unsigned char *pabyBufNew = + STATIC_CAST(unsigned char *, realloc(pabyBuf, nHeadLen)); + if (!pabyBufNew) + { + psDBF->sHooks.FClose(psDBF->fp); + free(pabyBuf); + free(psDBF->pszCurrentRecord); + free(psDBF->pszCodePage); + free(psDBF); + return SHPLIB_NULLPTR; + } + pabyBuf = pabyBufNew; psDBF->pszHeader = REINTERPRET_CAST(char *, pabyBuf); psDBF->sHooks.FSeek(psDBF->fp, XBASE_FILEHDR_SZ, 0); @@ -480,6 +520,12 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, psDBF->panFieldSize = STATIC_CAST(int *, malloc(sizeof(int) * nFields)); psDBF->panFieldDecimals = STATIC_CAST(int *, malloc(sizeof(int) * nFields)); psDBF->pachFieldType = STATIC_CAST(char *, malloc(sizeof(char) * nFields)); + if (!psDBF->panFieldOffset || !psDBF->panFieldSize || + !psDBF->panFieldDecimals || !psDBF->pachFieldType) + { + DBFClose(psDBF); + return SHPLIB_NULLPTR; + } for (int iField = 0; iField < nFields; iField++) { @@ -627,6 +673,8 @@ DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszFilename, /* -------------------------------------------------------------------- */ const int nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename); char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + if (!pszFullname) + return SHPLIB_NULLPTR; memcpy(pszFullname, pszFilename, nLenWithoutExtension); memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5); @@ -672,6 +720,10 @@ DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszFilename, /* Create the info structure. */ /* -------------------------------------------------------------------- */ DBFHandle psDBF = STATIC_CAST(DBFHandle, calloc(1, sizeof(DBFInfo))); + if (!psDBF) + { + return SHPLIB_NULLPTR; + } memcpy(&(psDBF->sHooks), psHooks, sizeof(SAHooks)); psDBF->fp = fp; @@ -699,7 +751,8 @@ DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszFilename, { psDBF->pszCodePage = STATIC_CAST(char *, malloc(strlen(pszCodePage) + 1)); - strcpy(psDBF->pszCodePage, pszCodePage); + if (psDBF->pszCodePage) + strcpy(psDBF->pszCodePage, pszCodePage); } DBFSetLastModifiedDate(psDBF, 95, 7, 26); /* dummy date */ @@ -806,19 +859,67 @@ int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, /* realloc all the arrays larger to hold the additional field */ /* information. */ /* -------------------------------------------------------------------- */ - psDBF->nFields++; - psDBF->panFieldOffset = STATIC_CAST( - int *, realloc(psDBF->panFieldOffset, sizeof(int) * psDBF->nFields)); + int *panFieldOffsetNew = + STATIC_CAST(int *, realloc(psDBF->panFieldOffset, + sizeof(int) * (psDBF->nFields + 1))); - psDBF->panFieldSize = STATIC_CAST( - int *, realloc(psDBF->panFieldSize, sizeof(int) * psDBF->nFields)); + int *panFieldSizeNew = + STATIC_CAST(int *, realloc(psDBF->panFieldSize, + sizeof(int) * (psDBF->nFields + 1))); - psDBF->panFieldDecimals = STATIC_CAST( - int *, realloc(psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields)); + int *panFieldDecimalsNew = + STATIC_CAST(int *, realloc(psDBF->panFieldDecimals, + sizeof(int) * (psDBF->nFields + 1))); - psDBF->pachFieldType = STATIC_CAST( - char *, realloc(psDBF->pachFieldType, sizeof(char) * psDBF->nFields)); + char *pachFieldTypeNew = + STATIC_CAST(char *, realloc(psDBF->pachFieldType, + sizeof(char) * (psDBF->nFields + 1))); + + char *pszHeaderNew = + STATIC_CAST(char *, realloc(psDBF->pszHeader, + (psDBF->nFields + 1) * XBASE_FLDHDR_SZ)); + + /* -------------------------------------------------------------------- */ + /* Make the current record buffer appropriately larger. */ + /* -------------------------------------------------------------------- */ + char *pszCurrentRecordNew = + STATIC_CAST(char *, realloc(psDBF->pszCurrentRecord, + psDBF->nRecordLength + nWidth)); + + if (panFieldOffsetNew) + psDBF->panFieldOffset = panFieldOffsetNew; + if (panFieldSizeNew) + psDBF->panFieldSize = panFieldSizeNew; + if (panFieldDecimalsNew) + psDBF->panFieldDecimals = panFieldDecimalsNew; + if (pachFieldTypeNew) + psDBF->pachFieldType = pachFieldTypeNew; + if (pszHeaderNew) + psDBF->pszHeader = pszHeaderNew; + if (pszCurrentRecordNew) + psDBF->pszCurrentRecord = pszCurrentRecordNew; + + if (!panFieldOffsetNew || !panFieldSizeNew || !panFieldDecimalsNew || + !pachFieldTypeNew || !pszHeaderNew || !pszCurrentRecordNew) + { + psDBF->sHooks.Error("Out of memory"); + return -1; + } + + /* alloc record */ + char *pszRecord = SHPLIB_NULLPTR; + if (!psDBF->bNoHeader) + { + pszRecord = STATIC_CAST(char *, malloc(psDBF->nRecordLength + nWidth)); + if (!pszRecord) + { + psDBF->sHooks.Error("Out of memory"); + return -1; + } + } + + psDBF->nFields++; /* -------------------------------------------------------------------- */ /* Assign the new field information fields. */ @@ -835,9 +936,6 @@ int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, psDBF->nHeaderLength += XBASE_FLDHDR_SZ; psDBF->bUpdated = FALSE; - psDBF->pszHeader = STATIC_CAST( - char *, realloc(psDBF->pszHeader, psDBF->nFields * XBASE_FLDHDR_SZ)); - char *pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * (psDBF->nFields - 1); for (int i = 0; i < XBASE_FLDHDR_SZ; i++) @@ -858,12 +956,6 @@ int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals); } - /* -------------------------------------------------------------------- */ - /* Make the current record buffer appropriately larger. */ - /* -------------------------------------------------------------------- */ - psDBF->pszCurrentRecord = STATIC_CAST( - char *, realloc(psDBF->pszCurrentRecord, psDBF->nRecordLength)); - /* we're done if dealing with new .dbf */ if (psDBF->bNoHeader) return (psDBF->nFields - 1); @@ -872,10 +964,6 @@ int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, /* For existing .dbf file, shift records */ /* -------------------------------------------------------------------- */ - /* alloc record */ - char *pszRecord = - STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); - const char chFieldFill = DBFGetNullCharacter(chType); SAOffset nRecordOffset; @@ -1783,11 +1871,7 @@ int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape, /* -------------------------------------------------------------------- */ /* Assign value, marking record as dirty if it changes. */ /* -------------------------------------------------------------------- */ - char chNewFlag; - if (bIsDeleted) - chNewFlag = '*'; - else - chNewFlag = ' '; + const char chNewFlag = bIsDeleted ? '*' : ' '; if (psDBF->pszCurrentRecord[0] != chNewFlag) { @@ -1965,6 +2049,31 @@ int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, const int *panMap) STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char))); char *pszHeaderNew = STATIC_CAST( char *, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields)); + char *pszRecord = SHPLIB_NULLPTR; + char *pszRecordNew = SHPLIB_NULLPTR; + if (!(psDBF->bNoHeader && psDBF->nRecords == 0)) + { + /* alloc record */ + pszRecord = + STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); + pszRecordNew = + STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); + } + if (!panFieldOffsetNew || !panFieldSizeNew || !panFieldDecimalsNew || + !pachFieldTypeNew || !pszHeaderNew || + (!(psDBF->bNoHeader && psDBF->nRecords == 0) && + (!pszRecord || !pszRecordNew))) + { + free(panFieldOffsetNew); + free(panFieldSizeNew); + free(panFieldDecimalsNew); + free(pachFieldTypeNew); + free(pszHeaderNew); + free(pszRecord); + free(pszRecordNew); + psDBF->sHooks.Error("Out of memory"); + return FALSE; + } /* shuffle fields definitions */ for (int i = 0; i < psDBF->nFields; i++) @@ -1994,12 +2103,6 @@ int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, const int *panMap) psDBF->bNoHeader = TRUE; DBFUpdateHeader(psDBF); - /* alloc record */ - char *pszRecord = - STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); - char *pszRecordNew = - STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); - /* shuffle fields in records */ for (int iRecord = 0; iRecord < psDBF->nRecords; iRecord++) { @@ -2030,12 +2133,12 @@ int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, const int *panMap) psDBF->sHooks.FWrite(pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp); } - - /* free record */ - free(pszRecord); - free(pszRecordNew); } + /* free record */ + free(pszRecord); + free(pszRecordNew); + if (errorAbort) { free(panFieldOffsetNew); @@ -2098,6 +2201,31 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, if (nWidth > XBASE_FLD_MAX_WIDTH) nWidth = XBASE_FLD_MAX_WIDTH; + char *pszRecord = STATIC_CAST( + char *, malloc(nOldRecordLength + + ((nWidth > nOldWidth) ? nWidth - nOldWidth : 0))); + char *pszOldField = STATIC_CAST(char *, malloc(nOldWidth + 1)); + if (!pszRecord || !pszOldField) + { + free(pszRecord); + free(pszOldField); + return FALSE; + } + + if (nWidth != nOldWidth) + { + char *pszCurrentRecordNew = STATIC_CAST( + char *, realloc(psDBF->pszCurrentRecord, + psDBF->nRecordLength + nWidth - nOldWidth)); + if (!pszCurrentRecordNew) + { + free(pszRecord); + free(pszOldField); + return FALSE; + } + psDBF->pszCurrentRecord = pszCurrentRecordNew; + } + /* -------------------------------------------------------------------- */ /* Assign the new field information fields. */ /* -------------------------------------------------------------------- */ @@ -2136,14 +2264,15 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, for (int i = iField + 1; i < psDBF->nFields; i++) psDBF->panFieldOffset[i] += nWidth - nOldWidth; psDBF->nRecordLength += nWidth - nOldWidth; - - psDBF->pszCurrentRecord = STATIC_CAST( - char *, realloc(psDBF->pszCurrentRecord, psDBF->nRecordLength)); } /* we're done if we're dealing with not yet created .dbf */ if (psDBF->bNoHeader && psDBF->nRecords == 0) + { + free(pszRecord); + free(pszOldField); return TRUE; + } /* force update of header with new header and record length */ psDBF->bNoHeader = TRUE; @@ -2153,11 +2282,6 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType)) { - char *pszRecord = - STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength)); - char *pszOldField = - STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1))); - pszOldField[nOldWidth] = 0; /* move records to their new positions */ @@ -2225,17 +2349,9 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp); } /* TODO: truncate file */ - - free(pszRecord); - free(pszOldField); } else if (nWidth > nOldWidth) { - char *pszRecord = - STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); - char *pszOldField = - STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1))); - pszOldField[nOldWidth] = 0; /* move records to their new positions */ @@ -2298,7 +2414,7 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, if (!errorAbort && psDBF->bWriteEndOfFileChar) { - char ch = END_OF_FILE_CHARACTER; + const char ch = END_OF_FILE_CHARACTER; SAOffset nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nRecords) + @@ -2307,11 +2423,11 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0); psDBF->sHooks.FWrite(&ch, 1, 1, psDBF->fp); } - - free(pszRecord); - free(pszOldField); } + free(pszRecord); + free(pszOldField); + if (errorAbort) { psDBF->nCurrentRecord = -1; diff --git a/ogr/ogrsf_frmts/shape/sbnsearch.c b/ogr/ogrsf_frmts/shape/sbnsearch.c index e5766a4d3492..7ecca02141c3 100644 --- a/ogr/ogrsf_frmts/shape/sbnsearch.c +++ b/ogr/ogrsf_frmts/shape/sbnsearch.c @@ -128,6 +128,8 @@ SBNSearchHandle SBNOpenDiskTree(const char *pszSBNFilename, /* -------------------------------------------------------------------- */ SBNSearchHandle hSBN = STATIC_CAST(SBNSearchHandle, calloc(1, sizeof(struct SBNSearchInfo))); + if (!hSBN) + return SHPLIB_NULLPTR; if (psHooks == SHPLIB_NULLPTR) SASetupDefaultHooks(&(hSBN->sHooks)); diff --git a/ogr/ogrsf_frmts/shape/shpopen.c b/ogr/ogrsf_frmts/shape/shpopen.c index 014e15770c67..042c1a270366 100644 --- a/ogr/ogrsf_frmts/shape/shpopen.c +++ b/ogr/ogrsf_frmts/shape/shpopen.c @@ -280,6 +280,8 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess, /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(1, sizeof(SHPInfo))); + if (!psSHP) + return SHPLIB_NULLPTR; psSHP->bUpdated = FALSE; memcpy(&(psSHP->sHooks), psHooks, sizeof(SAHooks)); @@ -290,6 +292,11 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess, /* -------------------------------------------------------------------- */ const int nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer); char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + if (!pszFullname) + { + free(psSHP); + return SHPLIB_NULLPTR; + } memcpy(pszFullname, pszLayer, nLenWithoutExtension); memcpy(pszFullname + nLenWithoutExtension, ".shp", 5); psSHP->fpSHP = @@ -305,12 +312,15 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess, { const size_t nMessageLen = strlen(pszFullname) * 2 + 256; char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen)); - pszFullname[nLenWithoutExtension] = 0; - snprintf(pszMessage, nMessageLen, - "Unable to open %s.shp or %s.SHP in %s mode.", pszFullname, - pszFullname, pszAccess); - psHooks->Error(pszMessage); - free(pszMessage); + if (pszMessage) + { + pszFullname[nLenWithoutExtension] = 0; + snprintf(pszMessage, nMessageLen, + "Unable to open %s.shp or %s.SHP in %s mode.", pszFullname, + pszFullname, pszAccess); + psHooks->Error(pszMessage); + free(pszMessage); + } free(psSHP); free(pszFullname); @@ -333,13 +343,16 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess, const size_t nMessageLen = 64 + strlen(pszFullname) * 2 + strlen(SHP_RESTORE_SHX_HINT_MESSAGE); char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen)); - pszFullname[nLenWithoutExtension] = 0; - snprintf( - pszMessage, nMessageLen, - "Unable to open %s.shx or %s.SHX." SHP_RESTORE_SHX_HINT_MESSAGE, - pszFullname, pszFullname); - psHooks->Error(pszMessage); - free(pszMessage); + if (pszMessage) + { + pszFullname[nLenWithoutExtension] = 0; + snprintf( + pszMessage, nMessageLen, + "Unable to open %s.shx or %s.SHX." SHP_RESTORE_SHX_HINT_MESSAGE, + pszFullname, pszFullname); + psHooks->Error(pszMessage); + free(pszMessage); + } psSHP->sHooks.FClose(psSHP->fpSHP); free(psSHP); @@ -353,7 +366,7 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess, /* Read the file size from the SHP file. */ /* -------------------------------------------------------------------- */ unsigned char *pabyBuf = STATIC_CAST(unsigned char *, malloc(100)); - if (psSHP->sHooks.FRead(pabyBuf, 100, 1, psSHP->fpSHP) != 1) + if (!pabyBuf || psSHP->sHooks.FRead(pabyBuf, 100, 1, psSHP->fpSHP) != 1) { psSHP->sHooks.Error(".shp file is unreadable, or corrupt."); psSHP->sHooks.FClose(psSHP->fpSHP); @@ -661,6 +674,8 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess, /* -------------------------------------------------------------------- */ const int nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer); char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + if (!pszFullname) + return 0; memcpy(pszFullname, pszLayer, nLenWithoutExtension); memcpy(pszFullname + nLenWithoutExtension, ".shp", 5); SAFile fpSHP = psHooks->FOpen(pszFullname, pszAccess, psHooks->pvUserData); @@ -674,12 +689,15 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess, { const size_t nMessageLen = strlen(pszFullname) * 2 + 256; char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen)); - - pszFullname[nLenWithoutExtension] = 0; - snprintf(pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.", - pszFullname, pszFullname); - psHooks->Error(pszMessage); - free(pszMessage); + if (pszMessage) + { + pszFullname[nLenWithoutExtension] = 0; + snprintf(pszMessage, nMessageLen, + "Unable to open %s.shp or %s.SHP.", pszFullname, + pszFullname); + psHooks->Error(pszMessage); + free(pszMessage); + } free(pszFullname); @@ -717,11 +735,14 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess, { size_t nMessageLen = strlen(pszFullname) * 2 + 256; char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen)); - pszFullname[nLenWithoutExtension] = 0; - snprintf(pszMessage, nMessageLen, - "Error opening file %s.shx for writing", pszFullname); - psHooks->Error(pszMessage); - free(pszMessage); + if (pszMessage) + { + pszFullname[nLenWithoutExtension] = 0; + snprintf(pszMessage, nMessageLen, + "Error opening file %s.shx for writing", pszFullname); + psHooks->Error(pszMessage); + free(pszMessage); + } psHooks->FClose(fpSHP); @@ -736,6 +757,15 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess, /* -------------------------------------------------------------------- */ psHooks->FSeek(fpSHP, 100, 0); char *pabySHXHeader = STATIC_CAST(char *, malloc(100)); + if (!pabySHXHeader) + { + psHooks->FClose(fpSHP); + + free(pabyBuf); + free(pszFullname); + + return (0); + } memcpy(pabySHXHeader, pabyBuf, 100); psHooks->FWrite(pabySHXHeader, 100, 1, fpSHX); free(pabyBuf); @@ -978,11 +1008,21 @@ SHPHandle SHPAPI_CALL SHPCreate(const char *pszLayer, int nShapeType) SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType, const SAHooks *psHooks) { + + SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(1, sizeof(SHPInfo))); + if (!psSHP) + return SHPLIB_NULLPTR; + /* -------------------------------------------------------------------- */ /* Open the two files so we can write their headers. */ /* -------------------------------------------------------------------- */ const int nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer); char *pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + if (!pszFullname) + { + free(psSHP); + return SHPLIB_NULLPTR; + } memcpy(pszFullname, pszLayer, nLenWithoutExtension); memcpy(pszFullname + nLenWithoutExtension, ".shp", 5); SAFile fpSHP = psHooks->FOpen(pszFullname, "w+b", psHooks->pvUserData); @@ -994,6 +1034,7 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType, psHooks->Error(szErrorMsg); free(pszFullname); + free(psSHP); return SHPLIB_NULLPTR; } @@ -1008,6 +1049,7 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType, free(pszFullname); psHooks->FClose(fpSHP); + free(psSHP); return SHPLIB_NULLPTR; } @@ -1062,6 +1104,7 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType, free(pszFullname); psHooks->FClose(fpSHP); psHooks->FClose(fpSHX); + free(psSHP); return SHPLIB_NULLPTR; } @@ -1086,11 +1129,10 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType, free(pszFullname); psHooks->FClose(fpSHP); psHooks->FClose(fpSHX); + free(psSHP); return SHPLIB_NULLPTR; } - SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(1, sizeof(SHPInfo))); - psSHP->bUpdated = FALSE; memcpy(&(psSHP->sHooks), psHooks, sizeof(SAHooks)); @@ -1191,6 +1233,8 @@ SHPObject SHPAPI_CALL1(*) { SHPObject *psObject = STATIC_CAST(SHPObject *, calloc(1, sizeof(SHPObject))); + if (!psObject) + return SHPLIB_NULLPTR; psObject->nSHPType = nSHPType; psObject->nShapeId = nShapeId; psObject->bMeasureIsUsed = FALSE; @@ -1235,6 +1279,13 @@ SHPObject SHPAPI_CALL1(*) STATIC_CAST(int *, calloc(psObject->nParts, sizeof(int))); psObject->panPartType = STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts)); + if (!psObject->panPartStart || !psObject->panPartType) + { + free(psObject->panPartStart); + free(psObject->panPartType); + free(psObject); + return SHPLIB_NULLPTR; + } psObject->panPartStart[0] = 0; psObject->panPartType[0] = SHPP_RING; @@ -1271,6 +1322,18 @@ SHPObject SHPAPI_CALL1(*) psObject->padfM = STATIC_CAST( double *, padfM &&bHasM ? malloc(nSize) : calloc(nVertices, sizeof(double))); + if (!psObject->padfX || !psObject->padfY || !psObject->padfZ || + !psObject->padfM) + { + free(psObject->panPartStart); + free(psObject->panPartType); + free(psObject->padfX); + free(psObject->padfY); + free(psObject->padfZ); + free(psObject->padfM); + free(psObject); + return SHPLIB_NULLPTR; + } if (padfX != SHPLIB_NULLPTR) memcpy(psObject->padfX, padfX, nSize); if (padfY != SHPLIB_NULLPTR) @@ -2123,6 +2186,11 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(const SHPHandle psSHP, int hEntity) else { psShape = STATIC_CAST(SHPObject *, calloc(1, sizeof(SHPObject))); + if (!psShape) + { + psSHP->sHooks.Error("Out of memory."); + return SHPLIB_NULLPTR; + } } psShape->nShapeId = hEntity; psShape->nSHPType = nSHPType; diff --git a/ogr/ogrsf_frmts/shape/shptree.c b/ogr/ogrsf_frmts/shape/shptree.c index ef89e00a8a79..6a7559a1eae4 100644 --- a/ogr/ogrsf_frmts/shape/shptree.c +++ b/ogr/ogrsf_frmts/shape/shptree.c @@ -678,6 +678,8 @@ SHPTreeDiskHandle SHPOpenDiskTree(const char *pszQIXFilename, hDiskTree = STATIC_CAST(SHPTreeDiskHandle, calloc(1, sizeof(struct SHPDiskTreeInfo))); + if (!hDiskTree) + return SHPLIB_NULLPTR; if (psHooks == SHPLIB_NULLPTR) SASetupDefaultHooks(&(hDiskTree->sHooks));