From: José Fonseca Date: Thu, 1 Sep 2011 12:30:53 +0000 (+0100) Subject: Prevent infinite loop reading snappy compressed files. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=8263960b845d1b8fa57465953a00fa7fb85b1d28;p=apitrace Prevent infinite loop reading snappy compressed files. We were still ending up in an infinite loop when flushCache() was called inside the while-loop in rawRead(), because m_cacheSize was never zeroed. --- diff --git a/trace_snappyfile.cpp b/trace_snappyfile.cpp index c161b9d..7678401 100644 --- a/trace_snappyfile.cpp +++ b/trace_snappyfile.cpp @@ -74,6 +74,7 @@ SnappyFile::SnappyFile(const std::string &filename, SnappyFile::~SnappyFile() { delete [] m_compressedCache; + delete [] m_cache; } bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode) @@ -198,33 +199,37 @@ void SnappyFile::flushCache() m_stream.write(m_compressedCache, compressedLength); m_cachePtr = m_cache; } else if (m_mode == File::Read) { - if (m_stream.eof()) - return; //assert(m_cachePtr == m_cache + m_cacheSize); size_t compressedLength; compressedLength = readCompressedLength(); - m_stream.read((char*)m_compressedCache, compressedLength); - /* - * The reason we peek here is because the last read will - * read all the way until the last character, but that will not - * trigger m_stream.eof() to be set, so by calling peek - * we assure that if we in fact have read the entire stream - * then the m_stream.eof() is always set. - */ - m_stream.peek(); - ::snappy::GetUncompressedLength(m_compressedCache, compressedLength, - &m_cacheSize); - if (m_cache) - delete [] m_cache; - createCache(m_cacheSize); - ::snappy::RawUncompress(m_compressedCache, compressedLength, - m_cache); + + if (compressedLength) { + m_stream.read((char*)m_compressedCache, compressedLength); + ::snappy::GetUncompressedLength(m_compressedCache, compressedLength, + &m_cacheSize); + createCache(m_cacheSize); + ::snappy::RawUncompress(m_compressedCache, compressedLength, + m_cache); + } else { + createCache(0); + } } } void SnappyFile::createCache(size_t size) { - m_cache = new char[size]; + // TODO: only re-allocate if the current buffer is not big enough + + if (m_cache) { + delete [] m_cache; + } + + if (size) { + m_cache = new char[size]; + } else { + m_cache = NULL; + } + m_cachePtr = m_cache; m_cacheSize = size; }