From af7f54bc8b59bd9283a3a91f9bc1f930ad25e123 Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols <federico.montesino-pouzols@stfc.ac.uk> Date: Mon, 19 Oct 2015 20:50:21 +0100 Subject: [PATCH] check potentially large file section sizes read from file, re #14028 --- MantidPlot/src/origin/OPJFile.cpp | 70 +++++++++++++++++++++++++++---- MantidPlot/src/origin/OPJFile.h | 8 ++-- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/MantidPlot/src/origin/OPJFile.cpp b/MantidPlot/src/origin/OPJFile.cpp index 73c397f65f2..b251bfcbde2 100644 --- a/MantidPlot/src/origin/OPJFile.cpp +++ b/MantidPlot/src/origin/OPJFile.cpp @@ -713,6 +713,18 @@ int OPJFile::ParseFormatNew() { char vers[5]; vers[4]=0; + // get file size + int file_size = 0; + { + int rv = fseek(f, 0 , SEEK_END); + if (rv < 0) + fprintf(debug, "Error: could not move to the end of the file\n"); + file_size = ftell(f); + rv = fseek(f, 0, SEEK_SET); + if (rv < 0) + fprintf(debug, "Error: could not move to the beginning of the file\n"); + } + // get version fseek(f,0x7,SEEK_SET); fread(&vers,4,1,f); @@ -1160,13 +1172,13 @@ int OPJFile::ParseFormatNew() { fseek(f,POS,SEEK_SET); if(compareSpreadnames(object_name)!=-1) - readSpreadInfo(f, debug); + readSpreadInfo(f, file_size, debug); else if(compareMatrixnames(object_name)!=-1) - readMatrixInfo(f, debug); + readMatrixInfo(f, file_size, debug); else if(compareExcelnames(object_name)!=-1) - readExcelInfo(f, debug); + readExcelInfo(f, file_size, debug); else - readGraphInfo(f, debug); + readGraphInfo(f, file_size, debug); } @@ -1276,7 +1288,7 @@ int OPJFile::ParseFormatNew() { return 0; } -void OPJFile::readSpreadInfo(FILE *f, FILE *debug) +void OPJFile::readSpreadInfo(FILE *f, int file_size, FILE *debug) { int POS=int(ftell(f)); @@ -1334,6 +1346,12 @@ void OPJFile::readSpreadInfo(FILE *f, FILE *debug) fflush(debug); } + if (file_size < sec_size) { + fprintf(debug, "Error in readSpread: found section size (%d) bigger than total file size: %d\n", sec_size, file_size); + fflush(debug); + return; + } + //section_body_1 LAYER+=0x5; fseek(f,LAYER,SEEK_SET); @@ -1507,7 +1525,7 @@ void OPJFile::readSpreadInfo(FILE *f, FILE *debug) fseek(f,POS,SEEK_SET); } -void OPJFile::readExcelInfo(FILE *f, FILE *debug) +void OPJFile::readExcelInfo(FILE *f, int file_size, FILE *debug) { int POS=int(ftell(f)); @@ -1568,6 +1586,12 @@ void OPJFile::readExcelInfo(FILE *f, FILE *debug) fflush(debug); } + if (file_size < sec_size) { + fprintf(debug, "Error in readExcel: found section size (%d) bigger than total file size: %d\n", sec_size, file_size); + fflush(debug); + return; + } + //section_body_1 LAYER+=0x5; fseek(f,LAYER,SEEK_SET); @@ -1748,7 +1772,7 @@ void OPJFile::readExcelInfo(FILE *f, FILE *debug) fseek(f,POS,SEEK_SET); } -void OPJFile::readMatrixInfo(FILE *f, FILE *debug) +void OPJFile::readMatrixInfo(FILE *f, int file_size, FILE *debug) { int POS=int(ftell(f)); @@ -1824,7 +1848,13 @@ void OPJFile::readMatrixInfo(FILE *f, FILE *debug) fflush(debug); } - //section_body_1 + if (file_size < sec_size) { + fprintf(debug, "Error in readMatrix: found section size (%d) bigger than total file size: %d\n", sec_size, file_size); + fflush(debug); + return; + } + + //section_body_1 LAYER+=0x5; //check if it is a formula if(0==strcmp(sec_name,"MV")) @@ -1909,7 +1939,7 @@ void OPJFile::readMatrixInfo(FILE *f, FILE *debug) } -void OPJFile::readGraphInfo(FILE *f, FILE *debug) +void OPJFile::readGraphInfo(FILE *f, int file_size, FILE *debug) { int POS=int(ftell(f)); @@ -2130,6 +2160,12 @@ void OPJFile::readGraphInfo(FILE *f, FILE *debug) fread(&sec_size,4,1,f); if(IsBigEndian()) SwapBytes(sec_size); + if (file_size < sec_size) { + fprintf(debug, "Error in readGraph: found section size (%d) bigger than total file size: %d\n", sec_size, file_size); + fflush(debug); + return; + } + //section_body_2 LAYER+=0x5; //check if it is a axis or legend @@ -2938,6 +2974,17 @@ void OPJFile::readProjectTreeFolder(FILE *f, FILE *debug, tree<projectNode>::ite { int POS=int(ftell(f)); + int file_size = 0; + { + int rv = fseek(f, 0 , SEEK_END); + if (rv < 0) + fprintf(debug, "Error: could not move to the end of the file\n"); + file_size = ftell(f); + rv = fseek(f, POS, SEEK_SET); + if (rv < 0) + fprintf(debug, "Error: could not move to the beginning of the file\n"); + } + double creation_date, modification_date; POS+=5; @@ -2977,6 +3024,10 @@ void OPJFile::readProjectTreeFolder(FILE *f, FILE *debug, tree<projectNode>::ite if(IsBigEndian()) SwapBytes(objectcount); POS+=5+5; + // there cannot be more objects than bytes + if (objectcount > file_size) + objectcount = 0; + for(int i=0; i<objectcount; ++i) { POS+=5; @@ -2997,6 +3048,7 @@ void OPJFile::readProjectTreeFolder(FILE *f, FILE *debug, tree<projectNode>::ite } fseek(f,POS,SEEK_SET); fread(&objectcount,4,1,f); + if(IsBigEndian()) SwapBytes(objectcount); fseek(f,1,SEEK_CUR); for(int i=0; i<objectcount; ++i) diff --git a/MantidPlot/src/origin/OPJFile.h b/MantidPlot/src/origin/OPJFile.h index 7f4f529ad29..75ffe32caa3 100644 --- a/MantidPlot/src/origin/OPJFile.h +++ b/MantidPlot/src/origin/OPJFile.h @@ -782,10 +782,10 @@ private: int compareFunctionnames(const char *sname) const; //!< returns matching function index std::vector<std::string> findDataByIndex(int index) const; std::string findObjectByIndex(int index); - void readSpreadInfo(FILE *fopj, FILE *fdebug); - void readExcelInfo(FILE *f, FILE *debug); - void readMatrixInfo(FILE *fopj, FILE *fdebug); - void readGraphInfo(FILE *fopj, FILE *fdebug); + void readSpreadInfo(FILE *fopj, int file_size, FILE *fdebug); + void readExcelInfo(FILE *f, int file_size, FILE *debug); + void readMatrixInfo(FILE *fopj, int file_size, FILE *fdebug); + void readGraphInfo(FILE *fopj, int file_size, FILE *fdebug); void readGraphGridInfo(graphGrid &grid, FILE *fopj, int pos); void readGraphAxisBreakInfo(graphAxisBreak &axis_break, FILE *fopj, int pos); void readGraphAxisFormatInfo(graphAxisFormat &format, FILE *fopj, int pos); -- GitLab