From 348fbfe41049cd642e1e0b6a7f79b454bca1aa08 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 8 May 2019 00:56:42 +0100 Subject: [PATCH] Switch to using safe buffers (fixing a memory leak) --- src/osgPlugins/tga/ReaderWriterTGA.cpp | 76 +++++++++++++++----------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp index dc9825c9a..79e70da55 100644 --- a/src/osgPlugins/tga/ReaderWriterTGA.cpp +++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp @@ -258,6 +258,36 @@ const int rleEntrySize) } } +template +struct SafeArray +{ + SafeArray() { impl = NULL; } + SafeArray(size_t size) { impl = new T[size]; } + ~SafeArray() { delete[] impl; } + + T* release() + { + T* temp = impl; + impl = NULL; + return temp; + } + + void reinitialise(size_t size) + { + delete[] impl; + + impl = new T[size]; + } + + operator T*() { return impl; } + + template + explicit operator U() { return (U)impl; } + +private: + T* impl; +}; + unsigned char * simage_tga_load(std::istream& fin, @@ -272,7 +302,7 @@ int *numComponents_ret) int depth; int flags; int format; - unsigned char *colormap; + SafeArray colormap; int colormapFirst = 0; int colormapLen = 0; int colormapDepth = 0; @@ -280,10 +310,8 @@ int *numComponents_ret) int rleRemaining; int rleEntrySize; unsigned char rleCurrent[4]; - unsigned char *buffer; unsigned char *dest; int bpr; - unsigned char *linebuf; int alphaBPP; tgaerror = ERR_NO_ERROR; /* clear error */ @@ -316,7 +344,6 @@ int *numComponents_ret) if (header[0]) /* skip identification field */ fin.seekg(header[0],std::ios::cur); - colormap = NULL; if (header[1] == 1) /* there is a colormap */ { colormapFirst = getInt16(&header[3]); @@ -328,7 +355,7 @@ int *numComponents_ret) } colormapLen = getInt16(&header[5]); colormapDepth = (header[7] + 7) >> 3; - colormap = new unsigned char[colormapLen*colormapDepth]; + colormap.reinitialise(colormapLen*colormapDepth); fin.read((char*)colormap, colormapLen*colormapDepth); if (colormapDepth == 2) /* 16 bits */ @@ -355,10 +382,10 @@ int *numComponents_ret) rleIsCompressed = 0; rleRemaining = 0; rleEntrySize = depth; - buffer = new unsigned char [width*height*format]; + SafeArray buffer(width*height*format); dest = buffer; bpr = format * width; - linebuf = new unsigned char [width*depth]; + SafeArray linebuf(width * depth); //check the intended image orientation bool bLeftToRight = (flags&0x10)==0; @@ -374,14 +401,9 @@ int *numComponents_ret) if (colormapLen == 0 || colormapDepth == 0) { tgaerror = ERR_UNSUPPORTED; /* colormap missing or empty */ - - if (colormap) delete [] colormap; - delete [] buffer; - delete [] linebuf; - return NULL; } - unsigned char * formattedMap = new unsigned char[colormapLen * format]; + SafeArray formattedMap(colormapLen * format); for (int i = 0; i < colormapLen; i++) { convert_data(colormap, formattedMap, i, colormapDepth, format); @@ -394,7 +416,7 @@ int *numComponents_ret) if (fin.gcount() != (std::streamsize) (width*depth)) { tgaerror = ERR_READ; - break; + return NULL; } for (x = 0; x < width; x++) @@ -416,7 +438,6 @@ int *numComponents_ret) break; default: tgaerror = ERR_UNSUPPORTED; - delete [] formattedMap; return NULL; /* unreachable code - (depth < 1 || depth > 4) rejected by "check for reasonable values in case this is not a tga file" near the start of this function*/ } @@ -426,8 +447,6 @@ int *numComponents_ret) } dest += lineoffset; } - - delete [] formattedMap; } break; case 2: /* RGB, uncompressed */ @@ -439,7 +458,7 @@ int *numComponents_ret) if (fin.gcount() != (std::streamsize) (width*depth)) { tgaerror = ERR_READ; - break; + return NULL; } for (x = 0; x < width; x++) { @@ -455,13 +474,14 @@ int *numComponents_ret) int pos = fin.tellg(); fin.seekg(0,std::ios::end); + // This is the size of the rest of the TGA file, not just the image section size = (int)fin.tellg() - pos; fin.seekg(pos,std::ios::beg); - unsigned char* buf = new unsigned char [size]; + SafeArray buf(size); if (buf == NULL) { tgaerror = ERR_MEM; - break; + return NULL; } unsigned char* src = buf; @@ -483,27 +503,21 @@ int *numComponents_ret) else { tgaerror = ERR_READ; + return NULL; } - if (buf) delete [] buf; } break; default: + { tgaerror = ERR_UNSUPPORTED; - } - - if (linebuf) delete [] linebuf; - if (colormap) delete [] colormap; - - if (tgaerror) - { - if (buffer) delete [] buffer; - return NULL; + return NULL; + } } *width_ret = width; *height_ret = height; *numComponents_ret = format; - return buffer; + return buffer.release(); }