--- misc/libcdr-0.0.5/src/lib/CDRInternalStream.cpp 2012-03-15 11:30:05.000000000 +0100 +++ misc/build/libcdr-0.0.5/src/lib/CDRInternalStream.cpp 2012-03-22 09:51:18.381882859 +0100 @@ -49,19 +49,19 @@ m_offset(0), m_buffer() { - unsigned long tmpNumBytesRead = 0; - - const unsigned char *tmpBuffer = 0; + if (!size) + return; if (!compressed) { - tmpBuffer = input->read(size, tmpNumBytesRead); + unsigned long tmpNumBytesRead = 0; + const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead); if (size != tmpNumBytesRead) return; m_buffer = std::vector(size); - memcpy(&m_buffer[0], &tmpBuffer[0], size); + memcpy(&m_buffer[0], tmpBuffer, size); } else { @@ -80,7 +80,8 @@ if (ret != Z_OK) return; - tmpBuffer = input->read(size, tmpNumBytesRead); + unsigned long tmpNumBytesRead = 0; + const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead); if (size != tmpNumBytesRead) return; @@ -99,6 +100,7 @@ case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&strm); + m_buffer.clear(); return; } @@ -109,7 +111,7 @@ } while (strm.avail_out == 0); - + (void)inflateEnd(&strm); } } --- misc/libcdr-0.0.5/src/lib/CDRZipStream.cpp 2012-03-16 11:20:15.000000000 +0100 +++ misc/build/libcdr-0.0.5/src/lib/CDRZipStream.cpp 2012-03-22 09:51:00.332335588 +0100 @@ -30,6 +30,7 @@ #include +#include #include "CDRZipStream.h" #include "CDRInternalStream.h" #include "libcdr_utils.h" @@ -231,9 +232,9 @@ return true; } -static bool findCentralDirectoryEnd(WPXInputStream *input, long &startOffset) +static bool findCentralDirectoryEnd(WPXInputStream *input) { - input->seek(startOffset, WPX_SEEK_SET); + input->seek(0, WPX_SEEK_SET); try { while (!input->atEOS()) @@ -242,7 +243,6 @@ if (signature == CDIR_END_SIG) { input->seek(-4, WPX_SEEK_CUR); - startOffset = input->tell(); return true; } else @@ -256,9 +256,9 @@ return false; } -static bool isZipStream(WPXInputStream *input, long &startOffset) +static bool isZipStream(WPXInputStream *input) { - if (!findCentralDirectoryEnd(input, startOffset)) + if (!findCentralDirectoryEnd(input)) return false; CentralDirectoryEnd end; if (!readCentralDirectoryEnd(input, end)) @@ -276,17 +276,16 @@ return true; } -static bool findDataStream(WPXInputStream *input, unsigned &size, bool &compressed, long &startOffset, const char *name) +static bool findDataStream(WPXInputStream *input, CentralDirectoryEntry &entry, const char *name) { unsigned short name_size = strlen(name); - if (!findCentralDirectoryEnd(input, startOffset)) + if (!findCentralDirectoryEnd(input)) return false; CentralDirectoryEnd end; if (!readCentralDirectoryEnd(input, end)) return false; input->seek(end.cdir_offset, WPX_SEEK_SET); - CentralDirectoryEntry entry; - while (!input->atEOS() && input->tell() < startOffset && input->tell() < end.cdir_offset + end.cdir_size) + while (!input->atEOS() && (unsigned)input->tell() < end.cdir_offset + end.cdir_size) { if (!readCentralDirectoryEntry(input, entry)) return false; @@ -303,17 +302,63 @@ return false; if (!areHeadersConsistent(header, entry)) return false; - size = entry.uncompressed_size; - compressed = (entry.compression != 0); return true; } +WPXInputStream *getSubstream(WPXInputStream *input, const char *name) +{ + CentralDirectoryEntry entry; + if (!findDataStream(input, entry, name)) + return 0; + if (!entry.compression) + return new CDRInternalStream(input, entry.compressed_size); + else + { + int ret; + z_stream strm; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm,-MAX_WBITS); + if (ret != Z_OK) + return 0; + + unsigned long numBytesRead = 0; + const unsigned char *compressedData = input->read(entry.compressed_size, numBytesRead); + if (numBytesRead != entry.compressed_size) + return 0; + + strm.avail_in = numBytesRead; + strm.next_in = (Bytef *)compressedData; + + std::vectordata(entry.uncompressed_size); + + strm.avail_out = entry.uncompressed_size; + strm.next_out = reinterpret_cast(&data[0]); + ret = inflate(&strm, Z_FINISH); + switch (ret) + { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + data.clear(); + return 0; + } + (void)inflateEnd(&strm); + return new CDRInternalStream(data); + } +} + } // anonymous namespace libcdr::CDRZipStream::CDRZipStream(WPXInputStream *input) : WPXInputStream(), - m_input(input), - m_cdir_offset(0) + m_input(input) { } @@ -339,16 +384,12 @@ bool libcdr::CDRZipStream::isOLEStream() { - return isZipStream(m_input, m_cdir_offset); + return isZipStream(m_input); } WPXInputStream *libcdr::CDRZipStream::getDocumentOLEStream(const char *name) { - unsigned size = 0; - bool compressed = false; - if (!findDataStream(m_input, size, compressed, m_cdir_offset, name)) - return 0; - return new CDRInternalStream(m_input, size, compressed); + return getSubstream(m_input, name); } /* vim:set shiftwidth=2 softtabstop=2 expandtab: */ --- misc/libcdr-0.0.5/src/lib/CDRZipStream.h 2012-03-16 10:53:24.000000000 +0100 +++ misc/build/libcdr-0.0.5/src/lib/CDRZipStream.h 2012-03-22 09:50:38.852874303 +0100 @@ -58,7 +58,6 @@ CDRZipStream(const CDRZipStream &); CDRZipStream &operator=(const CDRZipStream &); WPXInputStream *m_input; - long m_cdir_offset; }; } // namespace libcdr