[Libreoffice-commits] .: 2 commits - shell/inc shell/source zlib/prj zlib/zlib-1.2.5.patch

Fridrich Strba fridrich at kemper.freedesktop.org
Mon Mar 19 07:23:55 PDT 2012


 shell/inc/internal/basereader.hxx                         |    2 
 shell/inc/internal/contentreader.hxx                      |    3 
 shell/inc/internal/metainforeader.hxx                     |    2 
 shell/inc/internal/stream_helper.hxx                      |   24 
 shell/inc/internal/types.hxx                              |   17 
 shell/inc/internal/zipfile.hxx                            |   29 
 shell/source/win32/ooofilereader/basereader.cxx           |    4 
 shell/source/win32/ooofilereader/contentreader.cxx        |    4 
 shell/source/win32/ooofilereader/metainforeader.cxx       |    4 
 shell/source/win32/shlxthandler/makefile.mk               |    2 
 shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx       |   11 
 shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx       |    2 
 shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx |  190 ++---
 shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx   |    5 
 shell/source/win32/zipfile/zipfile.cxx                    |  473 +++++++++++---
 zlib/prj/d.lst                                            |    2 
 zlib/zlib-1.2.5.patch                                     |   10 
 17 files changed, 550 insertions(+), 234 deletions(-)

New commits:
commit e515cc938e21dd033d7e36440e20eb7cf561c293
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Mon Mar 19 15:22:04 2012 +0100

    Don't build unnecessary files

diff --git a/zlib/prj/d.lst b/zlib/prj/d.lst
index dc223ae..4f4996b 100644
--- a/zlib/prj/d.lst
+++ b/zlib/prj/d.lst
@@ -3,8 +3,6 @@ mkdir: %_DEST%\lib\x64
 
 ..\%__SRC%\inc\patched\zlib.h %_DEST%\inc\external\zlib\zlib.h
 ..\%__SRC%\inc\unzip.h %_DEST%\inc\external\zlib\unzip.h
-..\%__SRC%\inc\ioapi.h %_DEST%\inc\external\zlib\ioapi.h
-..\%__SRC%\inc\zconf.h %_DEST%\inc\external\zlib\zconf.h
 
 ..\%__SRC%\lib\libzlib.a %_DEST%\lib\libzlib.a
 ..\%__SRC%\slb\zlib.lib %_DEST%\lib\zlib.lib
diff --git a/zlib/zlib-1.2.5.patch b/zlib/zlib-1.2.5.patch
index 7021a2c..3389b88 100644
--- a/zlib/zlib-1.2.5.patch
+++ b/zlib/zlib-1.2.5.patch
@@ -1,6 +1,6 @@
 --- misc/zlib-1.2.5/makefile.mk	Fri Mar 14 10:17:06 2008
 +++ misc/build/zlib-1.2.5/makefile.mk	Fri Mar 14 10:16:56 2008
-@@ -1 +1,67 @@
+@@ -1 +1,63 @@
 -dummy
 +#*************************************************************************
 +#
@@ -31,9 +31,7 @@
 +			$(SLO)$/inflate.obj		\
 +			$(SLO)$/inftrees.obj	\
 +			$(SLO)$/trees.obj		\
-+			$(SLO)$/zutil.obj       \
-+			$(SLO)$/unzip.obj		\
-+			$(SLO)$/ioapi.obj
++			$(SLO)$/zutil.obj
 +
 +
 +LIB1TARGET=$(SLB)$/$(TARGET).lib
@@ -49,9 +47,7 @@
 +			$(SLO_X64)$/inflate.obj		\
 +			$(SLO_X64)$/inftrees.obj	\
 +			$(SLO_X64)$/trees.obj		\
-+			$(SLO_X64)$/zutil.obj       \
-+			$(SLO_X64)$/unzip.obj		\
-+			$(SLO_X64)$/ioapi.obj
++			$(SLO_X64)$/zutil.obj
 +
 +LIB1TARGET_X64=$(SLB_X64)$/$(TARGET).lib
 +LIB1OBJFILES_X64=$(SLOFILES_X64)
commit 04366df3bca16d4e0cbe254551e44427ae6338bb
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Mon Mar 19 15:09:34 2012 +0100

    Simple Zip file-format implementation to avoid the need of minizip

diff --git a/shell/inc/internal/basereader.hxx b/shell/inc/internal/basereader.hxx
index bb5c276..7a15410 100644
--- a/shell/inc/internal/basereader.hxx
+++ b/shell/inc/internal/basereader.hxx
@@ -46,7 +46,7 @@ public:
 protected: // protected because its only an implementation relevant class
     CBaseReader( const std::string& DocumentName );
 
-    CBaseReader( void* stream, zlib_filefunc_def* fa );
+    CBaseReader( StreamInterface *stream );
 
     virtual void start_document();
 
diff --git a/shell/inc/internal/contentreader.hxx b/shell/inc/internal/contentreader.hxx
index 6a7dc59..e55a760 100644
--- a/shell/inc/internal/contentreader.hxx
+++ b/shell/inc/internal/contentreader.hxx
@@ -32,6 +32,7 @@
 #include "internal/basereader.hxx"
 
 class ITag;
+class StreamInterface;
 
 class CContentReader : public CBaseReader
 {
@@ -40,7 +41,7 @@ public:
 
     CContentReader( const std::string& DocumentName, LocaleSet_t const & DocumentLocale );
 
-    CContentReader( void* stream, LocaleSet_t const & DocumentLocale, zlib_filefunc_def* fa );
+    CContentReader( StreamInterface* stream, LocaleSet_t const & DocumentLocale );
 
 
     /** Get the chunkbuffer.
diff --git a/shell/inc/internal/metainforeader.hxx b/shell/inc/internal/metainforeader.hxx
index 5162245..a0ed7d9 100644
--- a/shell/inc/internal/metainforeader.hxx
+++ b/shell/inc/internal/metainforeader.hxx
@@ -44,7 +44,7 @@ public:
 
     CMetaInfoReader( const std::string& DocumentName );
 
-    CMetaInfoReader( void* stream, zlib_filefunc_def* fa);
+    CMetaInfoReader( StreamInterface* stream );
 
     /** check if the Tag is in the target meta.xml file.
 
diff --git a/shell/inc/internal/stream_helper.hxx b/shell/inc/internal/stream_helper.hxx
index bd31ee1..72eaf73 100644
--- a/shell/inc/internal/stream_helper.hxx
+++ b/shell/inc/internal/stream_helper.hxx
@@ -31,7 +31,29 @@
 
 #include "internal/types.hxx"
 
-IStream* PrepareIStream( IStream* pStream, zlib_filefunc_def &zFileFunc );
+class BufferStream : public StreamInterface
+{
+public:
+    BufferStream(IStream *str);
+    ~BufferStream();
+    unsigned long sread (unsigned char *vuf, unsigned long size);
+    long stell ();
+    long sseek (unsigned long offset, int origin);
+private:
+    IStream *stream;
+};
+
+class FileStream : public StreamInterface
+{
+public:
+    FileStream(const char *filename);
+    ~FileStream();
+    unsigned long sread (unsigned char *buf, unsigned long size);
+    long stell ();
+    long sseek (unsigned long offset, int origin);
+private:
+    FILE *file;
+};
 
 #endif
 
diff --git a/shell/inc/internal/types.hxx b/shell/inc/internal/types.hxx
index 0c6810a..c6fbfac 100644
--- a/shell/inc/internal/types.hxx
+++ b/shell/inc/internal/types.hxx
@@ -35,14 +35,6 @@
 #include <vector>
 #include <stack>
 
-#if defined SYSTEM_ZLIB
-#include <zlib.h>
-#include <minizip/ioapi.h>
-#else
-#include <external/zlib/zlib.h>
-#include <external/zlib/ioapi.h>
-#endif
-
 typedef std::vector<std::wstring> StringList_t;
 
 //+-------------------------------------------------------------------------
@@ -89,6 +81,15 @@ typedef ::std::map<StyleName_t, LocaleSet_t>  StyleLocaleMap_t;
 
 const StyleLocalePair_t EMPTY_STYLELOCALE_PAIR = ::std::make_pair(::std::wstring(), EMPTY_LOCALE );
 
+class StreamInterface
+{
+public:
+    virtual ~StreamInterface() {}
+    virtual unsigned long sread (unsigned char* vuf, unsigned long size) = 0;
+    virtual long stell () = 0;
+    virtual long sseek (unsigned long offset, int origin) = 0;
+};
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/inc/internal/zipfile.hxx b/shell/inc/internal/zipfile.hxx
index 062ce38..24fba65 100644
--- a/shell/inc/internal/zipfile.hxx
+++ b/shell/inc/internal/zipfile.hxx
@@ -33,16 +33,19 @@
 #define _WINDOWS
 #endif
 
-#if defined SYSTEM_ZLIB
-#include <minizip/unzip.h>
+#ifdef SYSTEM_ZLIB
+#include <zlib.h>
 #else
-#include <external/zlib/unzip.h>
+#include <external/zlib/zlib.h>
 #endif
 
 #include <string>
 #include <vector>
 #include <memory>
 
+class StreamInterface;
+class ZipFilePrivate;
+
 /** A simple zip content provider based on the zlib
 */
 
@@ -69,9 +72,9 @@ public:
             IOException if the specified file doesn't exist
             AccessViolationException if read access to the file is denied
     */
-    static bool IsZipFile(const std::string& FileName);
+    static bool IsZipFile(const std::string &FileName);
 
-    static bool IsZipFile(void* stream);
+    static bool IsZipFile(void *stream);
 
 
     /** Returns wheter the version of the specified zip file may be uncompressed with the
@@ -89,9 +92,9 @@ public:
             IOException if the specified file doesn't exist or is no zip file
             AccessViolationException if read access to the file is denied
     */
-    static bool IsValidZipFileVersionNumber(const std::string& FileName);
+    static bool IsValidZipFileVersionNumber(const std::string &FileName);
 
-    static bool IsValidZipFileVersionNumber(void* stream);
+    static bool IsValidZipFileVersionNumber(void *stream);
 
 public:
 
@@ -107,9 +110,9 @@ public:
             WrongZipVersionException if the zip file cannot be uncompressed
             with the used zlib version
     */
-    ZipFile(const std::string& FileName);
+    ZipFile(const std::string &FileName);
 
-    ZipFile(void* stream, zlib_filefunc_def* fa);
+    ZipFile(StreamInterface *stream);
 
 
     /** Destroys a zip file
@@ -134,7 +137,7 @@ public:
                 ZipContentMissException if the specified zip content
                 does not exist in this zip file
     */
-    void GetUncompressedContent(const std::string& ContentName, /*inout*/ ZipContentBuffer_t& ContentBuffer);
+    void GetUncompressedContent(const std::string &ContentName, /*inout*/ ZipContentBuffer_t &ContentBuffer);
 
     /** Returns a list with the content names contained within this file
 
@@ -146,7 +149,7 @@ public:
         iterating over a ZipFileDirectory returned by
         GetDirectory
     */
-    bool HasContent(const std::string& ContentName) const;
+    bool HasContent(const std::string &ContentName) const;
 
 private:
 
@@ -158,7 +161,9 @@ private:
     long GetFileLongestFileNameLength() const;
 
 private:
-    unzFile m_uzFile;
+    StreamInterface *m_pStream;
+    bool m_bShouldFree;
+    long m_iStartOffset;
 };
 
 #endif
diff --git a/shell/source/win32/ooofilereader/basereader.cxx b/shell/source/win32/ooofilereader/basereader.cxx
index ed0c4a0..f4f694e 100644
--- a/shell/source/win32/ooofilereader/basereader.cxx
+++ b/shell/source/win32/ooofilereader/basereader.cxx
@@ -47,8 +47,8 @@ m_ZipFile( DocumentName )
 
 //------------------------------
 
-CBaseReader::CBaseReader(void * sw, zlib_filefunc_def* fa):
-m_ZipFile( sw , fa )
+CBaseReader::CBaseReader(StreamInterface * sw):
+m_ZipFile( sw )
 {
 }
 
diff --git a/shell/source/win32/ooofilereader/contentreader.cxx b/shell/source/win32/ooofilereader/contentreader.cxx
index f824dbc..76cfc6c 100644
--- a/shell/source/win32/ooofilereader/contentreader.cxx
+++ b/shell/source/win32/ooofilereader/contentreader.cxx
@@ -62,8 +62,8 @@ CBaseReader( DocumentName )
     }
 }
 
-CContentReader::CContentReader( void* stream, LocaleSet_t const & DocumentLocale, zlib_filefunc_def* fa ) :
-CBaseReader( stream, fa )
+CContentReader::CContentReader( StreamInterface* stream, LocaleSet_t const & DocumentLocale ) :
+CBaseReader( stream )
 {
 try
     {
diff --git a/shell/source/win32/ooofilereader/metainforeader.cxx b/shell/source/win32/ooofilereader/metainforeader.cxx
index 5abf72b..4027b65 100644
--- a/shell/source/win32/ooofilereader/metainforeader.cxx
+++ b/shell/source/win32/ooofilereader/metainforeader.cxx
@@ -81,8 +81,8 @@ CBaseReader( DocumentName )
     }
 }
 
-CMetaInfoReader::CMetaInfoReader( void* stream, zlib_filefunc_def* fa) :
-CBaseReader( stream, fa)
+CMetaInfoReader::CMetaInfoReader( StreamInterface* stream ) :
+CBaseReader( stream )
 {
 try
     {
diff --git a/shell/source/win32/shlxthandler/makefile.mk b/shell/source/win32/shlxthandler/makefile.mk
index fa2a480..81c3515 100644
--- a/shell/source/win32/shlxthandler/makefile.mk
+++ b/shell/source/win32/shlxthandler/makefile.mk
@@ -73,6 +73,7 @@ SLOFILES=$(SLO)$/classfactory.obj\
     $(SLO)$/listviewbuilder.obj\
     $(SLO)$/document_statistic.obj\
     $(SLO)$/thumbviewer.obj\
+    $(SLO)$/stream_helper.obj\
 
 SHL1TARGET=$(TARGET)
 
@@ -128,6 +129,7 @@ SLOFILES_X64= \
     $(SLO_X64)$/listviewbuilder.obj\
     $(SLO_X64)$/document_statistic.obj\
     $(SLO_X64)$/thumbviewer.obj\
+    $(SLO_X64)$/stream_helper.obj\
 
 SHL1TARGET_X64=$(TARGET)
 SHL1LIBS_X64=$(SOLARLIBDIR_X64)$/zlib.lib\
diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx b/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx
index 8528d0c..401ee6f 100644
--- a/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx
+++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx
@@ -120,6 +120,8 @@ COooFilter::~COooFilter()
         delete m_pContentReader;
     if (m_pMetaInfoReader)
         delete m_pMetaInfoReader;
+    if (m_pStream)
+        delete m_pStream;
 
     InterlockedDecrement( &g_lInstances );
 }
@@ -640,19 +642,16 @@ SCODE STDMETHODCALLTYPE COooFilter::SaveCompleted(LPCWSTR /*pszFileName*/)
 //--------------------------------------------------------------------------
 SCODE STDMETHODCALLTYPE COooFilter::Load(IStream *pStm)
 {
-    zlib_filefunc_def z_filefunc;
-
-    m_pStream = PrepareIStream( pStm, z_filefunc );
-
+    m_pStream = new BufferStream(pStm);
     try
     {
         if (m_pMetaInfoReader)
             delete m_pMetaInfoReader;
-        m_pMetaInfoReader = new CMetaInfoReader((void*)m_pStream, &z_filefunc);
+        m_pMetaInfoReader = new CMetaInfoReader(m_pStream);
 
         if (m_pContentReader)
             delete m_pContentReader;
-        m_pContentReader = new CContentReader((void*)m_pStream, m_pMetaInfoReader->getDefaultLocale(), &z_filefunc);
+        m_pContentReader = new CContentReader(m_pStream, m_pMetaInfoReader->getDefaultLocale());
     }
     catch (const std::exception&)
     {
diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx b/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx
index 030a3e5..5ecd917 100644
--- a/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx
+++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx
@@ -165,7 +165,7 @@ private:
     ULONG                     m_ChunkPosition;          // Chunk pointer to specify the current Chunk;
     ULONG                     m_cAttributes;            // Count of attributes
     CFullPropSpec *           m_pAttributes;            // Attributes to filter
-    IStream *                 m_pStream;
+    StreamInterface *         m_pStream;
 
 };
 
diff --git a/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx b/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx
index 54409eb..e4ace54 100644
--- a/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx
+++ b/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx
@@ -39,20 +39,8 @@
 #include <objidl.h>
 #include "internal/stream_helper.hxx"
 
-extern "C" {
-    voidpf ZCALLBACK cb_sopen OF((voidpf opaque, const char * filename, int mode));
-    uLong ZCALLBACK cb_sread OF((voidpf opaque, voidpf stream, void* vuf, uLong size));
-    uLong ZCALLBACK cb_swrite OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-    long ZCALLBACK cb_stell OF((voidpf opaque, voidpf stream));
-    long ZCALLBACK cb_sseek OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-    int ZCALLBACK cb_sclose OF((voidpf opaque, voidpf stream));
-    int ZCALLBACK cb_serror OF((voidpf opaque, voidpf stream));
-
-    void fill_stream_filefunc (zlib_filefunc_def* pzlib_filefunc_def);
-}
-
-//-----------------------------
-IStream* PrepareIStream( IStream* pStream, zlib_filefunc_def &zFileFunc )
+BufferStream::BufferStream(IStream *str) :
+    stream(str)
 {
     // These next few lines work around the "Seek pointer" bug found on Vista.
     char cBuf[20];
@@ -60,109 +48,101 @@ IStream* PrepareIStream( IStream* pStream, zlib_filefunc_def &zFileFunc )
     ULARGE_INTEGER nNewPosition;
     LARGE_INTEGER nMove;
     nMove.QuadPart = 0;
-    pStream->Seek( nMove, STREAM_SEEK_SET, &nNewPosition );
-    pStream->Read( cBuf, 20, &nCount );
-
-    fill_stream_filefunc( &zFileFunc );
-    zFileFunc.opaque = (void*)pStream;
+    stream->Seek( nMove, STREAM_SEEK_SET, &nNewPosition );
+    stream->Read( cBuf, 20, &nCount );
+}
 
-    return pStream;
+BufferStream::~BufferStream()
+{
 }
 
-extern "C" {
+unsigned long BufferStream::sread (unsigned char *buf, unsigned long size)
+{
+    unsigned long newsize;
+    HRESULT hr;
+
+    hr = stream->Read (buf, size, &newsize);
+    if (hr == S_OK)
+        return (unsigned long)newsize;
+    else
+        return (unsigned long)0;
+}
 
-    // IStream callback
-    voidpf ZCALLBACK cb_sopen (voidpf opaque, const char* /*filename*/, int /*mode*/) {
-        return opaque;
-    }
+long BufferStream::stell ()
+{
+    HRESULT hr;
+    LARGE_INTEGER Move;
+    ULARGE_INTEGER NewPosition;
+    Move.QuadPart = 0;
+    NewPosition.QuadPart = 0;
+
+    hr = ((IStream *)stream)->Seek (Move, STREAM_SEEK_CUR, &NewPosition);
+    if (hr == S_OK)
+        return (long) NewPosition.QuadPart;
+    else
+        return -1;
+}
 
-    uLong ZCALLBACK cb_sread (voidpf /*opaque*/, voidpf stream, void* buf, uLong size) {
-        unsigned long newsize;
-        HRESULT hr;
-
-        hr = ((IStream *)stream)->Read (buf, size, &newsize);
-        if (hr == S_OK){
-            return (unsigned long)newsize;
-        }
-        else {
-            return (uLong)0;
-        }
+long BufferStream::sseek (unsigned long offset, int origin)
+{
+    HRESULT hr;
+    LARGE_INTEGER Move;
+    DWORD dwOrigin;
+    Move.QuadPart = (__int64)offset;
+
+    switch (origin)
+    {
+    case SEEK_CUR:
+        dwOrigin = STREAM_SEEK_CUR;
+        break;
+    case SEEK_END:
+        dwOrigin = STREAM_SEEK_END;
+        break;
+    case SEEK_SET:
+        dwOrigin = STREAM_SEEK_SET;
+        break;
+    default:
+        return -1;
     }
 
-    long ZCALLBACK cb_sseek (voidpf /*opaque*/, voidpf stream, uLong offset, int origin) {
-        // IStream::Seek parameters
-        HRESULT hr;
-        LARGE_INTEGER Move;
-        DWORD dwOrigin;
-        Move.QuadPart = (__int64)offset;
-
-        switch (origin) {
-            case SEEK_CUR:
-                dwOrigin = STREAM_SEEK_CUR;
-                break;
-            case SEEK_END:
-                dwOrigin = STREAM_SEEK_END;
-                break;
-            case SEEK_SET:
-                dwOrigin = STREAM_SEEK_SET;
-                break;
-            default:
-                return -1;
-        }
-
-        hr = ((IStream*)stream)->Seek (Move, dwOrigin, NULL);
-        if (hr == S_OK){
-            return 0;
-        }
-        else {
-            return -1;
-        }
-    }
+    hr = stream->Seek (Move, dwOrigin, NULL);
+    if (hr == S_OK)
+        return 0;
+    else
+        return -1;
+}
 
-    long ZCALLBACK cb_stell (voidpf /*opaque*/, voidpf stream) {
-        // IStream::Seek parameters
-        HRESULT hr;
-        LARGE_INTEGER Move;
-        ULARGE_INTEGER NewPosition;
-        Move.QuadPart = 0;
-        NewPosition.QuadPart = 0;
-
-        hr = ((IStream*)stream)->Seek (Move, STREAM_SEEK_CUR, &NewPosition);
-        if (hr == S_OK){
-            return (long) NewPosition.QuadPart;
-        }
-        else {
-            return -1;
-        }
-    }
+FileStream::FileStream(const char *filename) :
+    file(0)
+{
+    file = fopen(filename, "rb");
+}
 
-    int ZCALLBACK cb_sclose (voidpf /*opaque*/, voidpf /*stream*/) {
-        return 0;
-    }
+FileStream::~FileStream()
+{
+    if (file)
+        fclose(file);
+}
 
-    int ZCALLBACK cb_serror (voidpf /*opaque*/, voidpf /*stream*/) {
-        return 0;  //RJK - for now
-    }
+unsigned long FileStream::sread (unsigned char *buf, unsigned long size)
+{
+    if (file)
+        return fread(buf, 1, size, file);
+    return 0;
+}
 
-    uLong ZCALLBACK cb_swrite (voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) {
-        HRESULT hr;
-        unsigned long writecount;
-        hr = ((IStream*)stream)->Write (buf, size, &writecount);
-        if (hr == S_OK)
-            return (unsigned int)writecount;
-        else
-            return (uLong)0;
-    }
+long FileStream::stell ()
+{
+    if (file)
+        return ftell(file);
+    return -1L;
+}
 
-    void fill_stream_filefunc (zlib_filefunc_def* pzlib_filefunc_def) {
-        pzlib_filefunc_def->zopen_file = cb_sopen;
-        pzlib_filefunc_def->zread_file = cb_sread;
-        pzlib_filefunc_def->zwrite_file = cb_swrite;
-        pzlib_filefunc_def->ztell_file = cb_stell;
-        pzlib_filefunc_def->zseek_file = cb_sseek;
-        pzlib_filefunc_def->zclose_file = cb_sclose;
-        pzlib_filefunc_def->zerror_file = cb_serror;
-    }
+long FileStream::sseek (unsigned long offset, int origin)
+{
+    if (file)
+        return fseek(file, offset, origin);
+    return -1L;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx b/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx
index d2d23ff..7d21f3a 100644
--- a/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx
+++ b/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx
@@ -228,14 +228,13 @@ HRESULT STDMETHODCALLTYPE CPropertyHdl::Initialize( IStream *pStream, DWORD grfM
 #endif
             OutputDebugStringFormat( "CPropertyHdl::Initialize: PSCreateMemoryPropertyStore failed" );
 
-        zlib_filefunc_def z_filefunc;
-        pStream = PrepareIStream( pStream, z_filefunc );
+        BufferStream tmpStream(pStream);
 
         CMetaInfoReader *pMetaInfoReader = NULL;
 
         try
         {
-            pMetaInfoReader = new CMetaInfoReader( (void*)pStream, &z_filefunc );
+            pMetaInfoReader = new CMetaInfoReader( &tmpStream );
             LoadProperties( pMetaInfoReader );
             delete pMetaInfoReader;
         }
diff --git a/shell/source/win32/zipfile/zipfile.cxx b/shell/source/win32/zipfile/zipfile.cxx
index 30c46b0..de99aa6 100644
--- a/shell/source/win32/zipfile/zipfile.cxx
+++ b/shell/source/win32/zipfile/zipfile.cxx
@@ -29,6 +29,8 @@
 #include "zipexcptn.hxx"
 #include "internal/zipfile.hxx"
 #include "internal/global.hxx"
+#include "internal/types.hxx"
+#include "internal/stream_helper.hxx"
 
 #include <malloc.h>
 #include <algorithm>
@@ -36,19 +38,289 @@
 
 #include <string.h>
 
-namespace internal
+namespace
+{
+
+struct LocalFileHeader
+{
+    unsigned short min_version;
+    unsigned short general_flag;
+    unsigned short compression;
+    unsigned short lastmod_time;
+    unsigned short lastmod_date;
+    unsigned crc32;
+    unsigned compressed_size;
+    unsigned uncompressed_size;
+    unsigned short filename_size;
+    unsigned short extra_field_size;
+    std::string filename;
+    std::string extra_field;
+    LocalFileHeader()
+        : min_version(0), general_flag(0), compression(0), lastmod_time(0), lastmod_date(0),
+          crc32(0), compressed_size(0), uncompressed_size(0), filename_size(0), extra_field_size(0),
+          filename(), extra_field() {}
+    ~LocalFileHeader() {}
+};
+
+struct CentralDirectoryEntry
+{
+    unsigned short creator_version;
+    unsigned short min_version;
+    unsigned short general_flag;
+    unsigned short compression;
+    unsigned short lastmod_time;
+    unsigned short lastmod_date;
+    unsigned crc32;
+    unsigned compressed_size;
+    unsigned uncompressed_size;
+    unsigned short filename_size;
+    unsigned short extra_field_size;
+    unsigned short file_comment_size;
+    unsigned short disk_num;
+    unsigned short internal_attr;
+    unsigned external_attr;
+    unsigned offset;
+    std::string filename;
+    std::string extra_field;
+    std::string file_comment;
+    CentralDirectoryEntry()
+        : creator_version(0), min_version(0), general_flag(0), compression(0), lastmod_time(0),
+          lastmod_date(0), crc32(0), compressed_size(0), uncompressed_size(0), filename_size(0),
+          extra_field_size(0), file_comment_size(0), disk_num(0), internal_attr(0),
+          external_attr(0), offset(0), filename(), extra_field(), file_comment() {}
+    ~CentralDirectoryEntry() {}
+};
+
+struct CentralDirectoryEnd
+{
+    unsigned short disk_num;
+    unsigned short cdir_disk;
+    unsigned short disk_entries;
+    unsigned short cdir_entries;
+    unsigned cdir_size;
+    unsigned cdir_offset;
+    unsigned short comment_size;
+    std::string comment;
+    CentralDirectoryEnd()
+        : disk_num(0), cdir_disk(0), disk_entries(0), cdir_entries(0),
+          cdir_size(0), cdir_offset(0), comment_size(0), comment() {}
+    ~CentralDirectoryEnd() {}
+};
+
+#define CDIR_ENTRY_SIG 0x02014b50
+#define LOC_FILE_HEADER_SIG 0x04034b50
+#define CDIR_END_SIG 0x06054b50
+
+static unsigned char readByte(StreamInterface *stream)
+{
+    if (!stream || stream->stell() == -1)
+        throw IOException(-1);
+    unsigned char tmpBuf;
+    unsigned long numBytesRead = stream->sread(&tmpBuf, 1);
+    if (numBytesRead != 1)
+        throw IOException(-1);
+    return tmpBuf;
+}
+
+static unsigned short readShort(StreamInterface *stream)
+{
+    unsigned short p0 = (unsigned short)readByte(stream);
+    unsigned short p1 = (unsigned short)readByte(stream);
+    return (unsigned short)(p0|(p1<<8));
+}
+
+static unsigned readInt(StreamInterface *stream)
+{
+    unsigned p0 = (unsigned)readByte(stream);
+    unsigned p1 = (unsigned)readByte(stream);
+    unsigned p2 = (unsigned)readByte(stream);
+    unsigned p3 = (unsigned)readByte(stream);
+    return (unsigned)(p0|(p1<<8)|(p2<<16)|(p3<<24));
+}
+
+static bool readCentralDirectoryEnd(StreamInterface *stream, CentralDirectoryEnd &end)
+{
+    try
+    {
+        unsigned signature = readInt(stream);
+        if (signature != CDIR_END_SIG)
+            return false;
+
+        end.disk_num = readShort(stream);
+        end.cdir_disk = readShort(stream);
+        end.disk_entries = readShort(stream);
+        end.cdir_entries = readShort(stream);
+        end.cdir_size = readInt(stream);
+        end.cdir_offset = readInt(stream);
+        end.comment_size = readShort(stream);
+        end.comment.clear();
+        for (unsigned short i = 0; i < end.comment_size; i++)
+            end.comment.append(1,(char)readByte(stream));
+    }
+    catch (...)
+    {
+        return false;
+    }
+    return true;
+}
+
+static bool readCentralDirectoryEntry(StreamInterface *stream, CentralDirectoryEntry &entry)
+{
+    try
+    {
+        unsigned signature = readInt(stream);
+        if (signature != CDIR_ENTRY_SIG)
+            return false;
+
+        entry.creator_version = readShort(stream);
+        entry.min_version = readShort(stream);
+        entry.general_flag = readShort(stream);
+        entry.compression = readShort(stream);
+        entry.lastmod_time = readShort(stream);
+        entry.lastmod_date = readShort(stream);
+        entry.crc32 = readInt(stream);
+        entry.compressed_size = readInt(stream);
+        entry.uncompressed_size = readInt(stream);
+        entry.filename_size = readShort(stream);
+        entry.extra_field_size = readShort(stream);
+        entry.file_comment_size = readShort(stream);
+        entry.disk_num = readShort(stream);
+        entry.internal_attr = readShort(stream);
+        entry.external_attr = readInt(stream);
+        entry.offset = readInt(stream);
+        unsigned short i = 0;
+        entry.filename.clear();
+        for (i=0; i < entry.filename_size; i++)
+            entry.filename.append(1,(char)readByte(stream));
+        entry.extra_field.clear();
+        for (i=0; i < entry.extra_field_size; i++)
+            entry.extra_field.append(1,(char)readByte(stream));
+        entry.file_comment.clear();
+        for (i=0; i < entry.file_comment_size; i++)
+            entry.file_comment.append(1,(char)readByte(stream));
+    }
+    catch (...)
+    {
+        return false;
+    }
+    return true;
+}
+
+static bool readLocalFileHeader(StreamInterface *stream, LocalFileHeader &header)
+{
+    try
+    {
+        unsigned signature = readInt(stream);
+        if (signature != LOC_FILE_HEADER_SIG)
+            return false;
+
+        header.min_version = readShort(stream);
+        header.general_flag = readShort(stream);
+        header.compression = readShort(stream);
+        header.lastmod_time = readShort(stream);
+        header.lastmod_date = readShort(stream);
+        header.crc32 = readInt(stream);
+        header.compressed_size = readInt(stream);
+        header.uncompressed_size = readInt(stream);
+        header.filename_size = readShort(stream);
+        header.extra_field_size = readShort(stream);
+        unsigned short i = 0;
+        header.filename.clear();
+        for (i=0; i < header.filename_size; i++)
+            header.filename.append(1,(char)readByte(stream));
+        header.extra_field.clear();
+        for (i=0; i < header.extra_field_size; i++)
+            header.extra_field.append(1,(char)readByte(stream));
+    }
+    catch (...)
+    {
+        return false;
+    }
+    return true;
+}
+
+static bool areHeadersConsistent(const LocalFileHeader &header, const CentralDirectoryEntry &entry)
+{
+    if (header.min_version != entry.min_version)
+        return false;
+    if (header.general_flag != entry.general_flag)
+        return false;
+    if (header.compression != entry.compression)
+        return false;
+    if (!(header.general_flag & 0x08))
+    {
+        if (header.crc32 != entry.crc32)
+            return false;
+        if (header.compressed_size != entry.compressed_size)
+            return false;
+        if (header.uncompressed_size != entry.uncompressed_size)
+            return false;
+    }
+    return true;
+}
+
+static bool findCentralDirectoryEnd(StreamInterface *stream, long &startOffset)
 {
-    /* for case in-sensitive string comparison */
-    struct stricmp : public std::unary_function<std::string, bool>
+    stream->sseek(startOffset, SEEK_SET);
+    try
     {
-        stricmp(const std::string& str) : str_(str)
-        {}
+        while (stream->stell() != -1)
+        {
+            unsigned signature = readInt(stream);
+            if (signature == CDIR_END_SIG)
+            {
+                stream->sseek(-4, SEEK_CUR);
+                startOffset = stream->stell();
+                return true;
+            }
+            else
+                stream->sseek(-3, SEEK_CUR);
+        }
+    }
+    catch (...)
+    {
+        return false;
+    }
+    return false;
+}
+
+static bool isZipStream(StreamInterface *stream, long &startOffset)
+{
+    if (!findCentralDirectoryEnd(stream, startOffset))
+        return false;
+    CentralDirectoryEnd end;
+    if (!readCentralDirectoryEnd(stream, end))
+        return false;
+    stream->sseek(end.cdir_offset, SEEK_SET);
+    CentralDirectoryEntry entry;
+    if (!readCentralDirectoryEntry(stream, entry))
+        return false;
+    stream->sseek(entry.offset, SEEK_SET);
+    LocalFileHeader header;
+    if (!readLocalFileHeader(stream, header))
+        return false;
+    if (!areHeadersConsistent(header, entry))
+        return false;
+    return true;
+}
+
+} // anonymous namespace
+
+namespace internal
+{
+/* for case in-sensitive string comparison */
+struct stricmp : public std::unary_function<std::string, bool>
+{
+    stricmp(const std::string &str) : str_(str)
+    {}
 
-        bool operator() (const std::string& other)
-        { return (0 == _stricmp(str_.c_str(), other.c_str())); }
+    bool operator() (const std::string &other)
+    {
+        return (0 == _stricmp(str_.c_str(), other.c_str()));
+    }
 
-        std::string str_;
-    };
+    std::string str_;
+};
 } // namespace internal
 
 /** Checks whether a file is a zip file or not
@@ -113,21 +385,26 @@ bool ZipFile::IsValidZipFileVersionNumber(void* /* stream*/)
             WrongZipVersionException if the zip file cannot be uncompressed
             with the used zlib version
 */
-ZipFile::ZipFile(const std::string& FileName)
+ZipFile::ZipFile(const std::string &FileName) :
+    m_pStream(0),
+    m_bShouldFree(true),
+    m_iStartOffset(0)
 {
-    m_uzFile = unzOpen(FileName.c_str());
-
-    if (0 == m_uzFile)
-        throw IOException(-1);
+    m_pStream = new FileStream(FileName.c_str());
+    if (m_pStream && !isZipStream(m_pStream, m_iStartOffset))
+    {
+        delete m_pStream;
+        m_pStream = 0;
+    }
 }
 
-ZipFile::ZipFile(void* stream, zlib_filefunc_def* fa)
+ZipFile::ZipFile(StreamInterface *stream) :
+    m_pStream(stream),
+    m_bShouldFree(false),
+    m_iStartOffset(0)
 {
-    fa->opaque = stream;
-    m_uzFile = unzOpen2((const char *)NULL, fa);
-
-    if (0 == m_uzFile)
-        throw IOException(-1);
+    if (!isZipStream(stream, m_iStartOffset))
+        m_pStream = 0;
 }
 
 
@@ -135,41 +412,84 @@ ZipFile::ZipFile(void* stream, zlib_filefunc_def* fa)
 */
 ZipFile::~ZipFile()
 {
-    unzClose(m_uzFile);
+    if (m_pStream && m_bShouldFree)
+        delete m_pStream;
 }
 
+#define CHUNK 16384
+
 /** Provides an interface to read the uncompressed data of a content of the zip file
 
     @precond    The specified content must exist in this file
             ppstm must not be NULL
 */
 void ZipFile::GetUncompressedContent(
-    const std::string& ContentName, /*inout*/ ZipContentBuffer_t& ContentBuffer)
+    const std::string &ContentName, /*inout*/ ZipContentBuffer_t &ContentBuffer)
 {
-    int rc = unzLocateFile(m_uzFile, ContentName.c_str(), 0);
-
-    if (UNZ_END_OF_LIST_OF_FILE == rc)
-        throw ZipContentMissException(rc);
-
-    unz_file_info finfo;
-    unzGetCurrentFileInfo(m_uzFile, &finfo, 0, 0, 0, 0, 0, 0);
-
-    ContentBuffer.resize(finfo.uncompressed_size);
-
-    rc = unzOpenCurrentFile(m_uzFile);
-
-    if (UNZ_OK != rc)
-        throw ZipException(rc);
-
-    rc = unzReadCurrentFile(m_uzFile, &ContentBuffer[0], finfo.uncompressed_size);
-
-    if (rc < 0)
-        throw ZipException(rc);
-
-    rc = unzCloseCurrentFile(m_uzFile);
-
-    if (rc < 0)
-        throw ZipException(rc);
+    long startOffset = m_iStartOffset;
+    if (!findCentralDirectoryEnd(m_pStream, startOffset))
+        return;
+    CentralDirectoryEnd end;
+    if (!readCentralDirectoryEnd(m_pStream, end))
+        return;
+    m_pStream->sseek(end.cdir_offset, SEEK_SET);
+    CentralDirectoryEntry entry;
+    while (m_pStream->stell() != -1 && m_pStream->stell() < startOffset && (unsigned long)m_pStream->stell() < end.cdir_offset + end.cdir_size)
+    {
+        if (!readCentralDirectoryEntry(m_pStream, entry))
+            return;
+        if (ContentName.length() == entry.filename_size && !_stricmp(entry.filename.c_str(), ContentName.c_str()))
+            break;
+    }
+    if (ContentName.length() != entry.filename_size)
+        return;
+    if (_stricmp(entry.filename.c_str(), ContentName.c_str()))
+        return;
+    m_pStream->sseek(entry.offset, SEEK_SET);
+    LocalFileHeader header;
+    if (!readLocalFileHeader(m_pStream, header))
+        return;
+    if (!areHeadersConsistent(header, entry))
+        return;
+    ContentBuffer.clear();
+    ContentBuffer = ZipContentBuffer_t(entry.uncompressed_size);
+    if (!entry.compression)
+        m_pStream->sread((unsigned char *)&ContentBuffer[0], entry.uncompressed_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 = inflateInit(&strm);
+        if (ret != Z_OK)
+            return;
+
+        std::vector<unsigned char> tmpBuffer(entry.compressed_size);
+        if (entry.compressed_size != m_pStream->sread(&tmpBuffer[0], entry.compressed_size))
+            return;
+
+        strm.avail_in = entry.compressed_size;
+        strm.next_in = reinterpret_cast<Bytef *>(&tmpBuffer[0]);
+
+        strm.avail_out = entry.uncompressed_size;
+        strm.next_out = reinterpret_cast<Bytef *>(&ContentBuffer[0]);
+        ret = inflate(&strm, Z_FINISH);
+        switch (ret)
+        {
+        case Z_NEED_DICT:
+        case Z_DATA_ERROR:
+        case Z_MEM_ERROR:
+            (void)inflateEnd(&strm);
+            ContentBuffer.clear();
+            return;
+        }
+    }
 }
 
 /** Returns a list with the content names contained within this file
@@ -178,36 +498,28 @@ void ZipFile::GetUncompressedContent(
 ZipFile::DirectoryPtr_t ZipFile::GetDirectory() const
 {
     DirectoryPtr_t dir(new Directory_t());
-
-    long lmax = GetFileLongestFileNameLength() + 1;
-    char* szFileName = reinterpret_cast<char*>(_alloca(lmax));
-
-    if (!szFileName)
-        throw ZipException(ERROR_NOT_ENOUGH_MEMORY);
-
-    int rc = unzGoToFirstFile(m_uzFile);
-
-    while (UNZ_OK == rc && UNZ_END_OF_LIST_OF_FILE != rc)
+    long startOffset = m_iStartOffset;
+    if (!findCentralDirectoryEnd(m_pStream, startOffset))
+        return dir;
+    CentralDirectoryEnd end;
+    if (!readCentralDirectoryEnd(m_pStream, end))
+        return dir;
+    m_pStream->sseek(end.cdir_offset, SEEK_SET);
+    CentralDirectoryEntry entry;
+    while (m_pStream->stell() != -1 && m_pStream->stell() < startOffset && (unsigned long)m_pStream->stell() < end.cdir_offset + end.cdir_size)
     {
-        unz_file_info finfo;
-        unzGetCurrentFileInfo(
-            m_uzFile, &finfo, szFileName, lmax, 0, 0, 0, 0);
-
-        dir->push_back(szFileName);
-
-        rc = unzGoToNextFile(m_uzFile);
+        if (!readCentralDirectoryEntry(m_pStream, entry))
+            return dir;
+        if (entry.filename_size)
+            dir->push_back(entry.filename);
     }
-
-    if (UNZ_OK != rc && UNZ_END_OF_LIST_OF_FILE != rc)
-        throw ZipException(rc);
-
     return dir;
 }
 
 /** Convinience query function may even realized with
     iterating over a ZipFileDirectory returned by
     GetDirectory */
-bool ZipFile::HasContent(const std::string& ContentName) const
+bool ZipFile::HasContent(const std::string &ContentName) const
 {
     //#i34314# we need to compare package content names
     //case in-sensitive as it is not defined that such
@@ -226,20 +538,21 @@ bool ZipFile::HasContent(const std::string& ContentName) const
 long ZipFile::GetFileLongestFileNameLength() const
 {
     long lmax = 0;
-    unz_file_info finfo;
-
-    int rc = unzGoToFirstFile(m_uzFile);
-
-    while (UNZ_OK == rc && UNZ_END_OF_LIST_OF_FILE != rc)
+    long startOffset = m_iStartOffset;
+    if (!findCentralDirectoryEnd(m_pStream, startOffset))
+        return lmax;
+    CentralDirectoryEnd end;
+    if (!readCentralDirectoryEnd(m_pStream, end))
+        return lmax;
+    m_pStream->sseek(end.cdir_offset, SEEK_SET);
+    CentralDirectoryEntry entry;
+    while (m_pStream->stell() != -1 && m_pStream->stell() < startOffset && (unsigned long)m_pStream->stell() < end.cdir_offset + end.cdir_size)
     {
-        unzGetCurrentFileInfo(m_uzFile, &finfo, 0, 0, 0, 0, 0, 0);
-        lmax = std::max<long>(lmax, finfo.size_filename);
-        rc = unzGoToNextFile(m_uzFile);
+        if (!readCentralDirectoryEntry(m_pStream, entry))
+            return lmax;
+        if (entry.filename_size > lmax)
+            lmax = entry.filename_size;
     }
-
-    if (UNZ_OK != rc && UNZ_END_OF_LIST_OF_FILE != rc)
-        throw ZipException(rc);
-
     return lmax;
 }
 


More information about the Libreoffice-commits mailing list