summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2003-03-26 13:16:07 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2003-03-26 13:16:07 +0000
commitfa66eeb587f11bea88ab5950ffd94aee221d6b31 (patch)
treefcf83a2077cad967959ca83f04613be41b1f9ff3 /package
parentcaa2a9eb27f7e266bc844a3ad215ec35bd804b1a (diff)
MWS_SRX644: migrate branch mws_srx644 -> HEAD
Diffstat (limited to 'package')
-rw-r--r--package/inc/ZipEntry.hxx6
-rw-r--r--package/inc/ZipFile.hxx28
-rw-r--r--package/inc/ZipPackage.hxx5
-rw-r--r--package/source/zipapi/EntryInputStream.cxx240
-rw-r--r--package/source/zipapi/EntryInputStream.hxx130
-rw-r--r--package/source/zipapi/MemoryByteGrabber.hxx6
-rw-r--r--package/source/zipapi/XUnbufferedStream.cxx58
-rw-r--r--package/source/zipapi/XUnbufferedStream.hxx8
-rw-r--r--package/source/zipapi/ZipFile.cxx289
-rw-r--r--package/source/zippackage/ZipPackage.cxx272
-rw-r--r--package/source/zippackage/ZipPackageFolder.cxx6
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx9
12 files changed, 898 insertions, 159 deletions
diff --git a/package/inc/ZipEntry.hxx b/package/inc/ZipEntry.hxx
index d181105f9108..5aa7b9bb626d 100644
--- a/package/inc/ZipEntry.hxx
+++ b/package/inc/ZipEntry.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipEntry.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: mtg $ $Date: 2001-10-30 13:53:22 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:41 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -75,6 +75,8 @@ struct ZipEntry
sal_Int32 nCompressedSize;
sal_Int32 nSize;
sal_Int32 nOffset;
+ sal_Int16 nNameLen;
+ sal_Int16 nExtraLen;
::rtl::OUString sName;
};
#endif
diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx
index de09b30aae03..edc6ad166a0d 100644
--- a/package/inc/ZipFile.hxx
+++ b/package/inc/ZipFile.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipFile.hxx,v $
*
- * $Revision: 1.17 $
+ * $Revision: 1.18 $
*
- * last change: $Author: mtg $ $Date: 2001-12-04 17:44:39 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:41 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -76,6 +76,7 @@
namespace com { namespace sun { namespace star {
namespace lang { class XMultiServiceFactory; }
+ namespace ucb { class XProgressHandler; }
} } }
namespace vos
{
@@ -104,6 +105,7 @@ protected:
com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > xFactory;
+ ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
com::sun::star::uno::Reference < com::sun::star::io::XInputStream > createMemoryStream(
ZipEntry & rEntry,
@@ -124,10 +126,27 @@ protected:
sal_Bool bDecrypt );
sal_Bool hasValidPassword ( ZipEntry & rEntry, const vos::ORef < EncryptionData > &rData );
+
+ sal_Bool checkSizeAndCRC( const ZipEntry& aEntry );
+
+ sal_Int32 getCRC( sal_Int32 nOffset, sal_Int32 nSize );
+
+ void getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC );
+
public:
+
ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
- sal_Bool bInitialise)
+ sal_Bool bInitialise
+ )
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+
+ ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
+ const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
+ sal_Bool bInitialise,
+ sal_Bool bForceRecover,
+ ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgress
+ )
throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
~ZipFile();
@@ -161,6 +180,9 @@ protected:
throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
sal_Int32 findEND()
throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+ sal_Int32 recover()
+ throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
+
};
#endif
diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx
index 25161b3df069..eb60e7c60e7b 100644
--- a/package/inc/ZipPackage.hxx
+++ b/package/inc/ZipPackage.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipPackage.hxx,v $
*
- * $Revision: 1.33 $
+ * $Revision: 1.34 $
*
- * last change: $Author: cl $ $Date: 2002-09-25 09:49:05 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:42 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -137,6 +137,7 @@ protected:
::rtl::OUString sURL;
sal_Bool bHasEncryptedEntries;
sal_Bool bUseManifest;
+ sal_Bool bForceRecovery;
InitialisationMode eMode;
::com::sun::star::uno::Reference < com::sun::star::container::XNameContainer > xRootFolder;
diff --git a/package/source/zipapi/EntryInputStream.cxx b/package/source/zipapi/EntryInputStream.cxx
new file mode 100644
index 000000000000..0f6f775e0675
--- /dev/null
+++ b/package/source/zipapi/EntryInputStream.cxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * $RCSfile: EntryInputStream.cxx,v $
+ *
+ * $Revision: 1.19 $
+ *
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ *
+ ************************************************************************/
+#ifndef _ENTRY_INPUT_STREAM_HXX
+#include <EntryInputStream.hxx>
+#endif
+#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPCONSTANTS_HPP_
+#include <com/sun/star/packages/zip/ZipConstants.hpp>
+#endif
+#ifndef _RTL_CIPHER_H_
+#include <rtl/cipher.h>
+#endif
+#ifndef _RTL_DIGEST_H_
+#include <rtl/digest.h>
+#endif
+#include <memory.h> // for memcpy
+
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::packages::zip;
+using namespace com::sun::star::packages::zip::ZipConstants;
+
+/** Provides access to the compressed data in a zipfile.
+ *
+ * 04/12/00 - uncompresses the stream into memory and seeks on it 'in memory'
+ * This and the ZipPackageBuffer used in the ZipOutputStream are memory hogs
+ * and will hopefully be replaced eventually
+ *
+ * Acts on the same underlying XInputStream as both the full Zip File and other
+ * EntryInputStreams, and thus must maintain its current position in the stream and
+ * seek to it before performing any reads.
+ */
+
+EntryInputStream::EntryInputStream( Reference < io::XInputStream > xNewInput,
+ const ZipEntry & rNewEntry,
+ const vos::ORef < EncryptionData > &xEncryptData,
+ sal_Bool bGetRawStream)
+: xStream( xNewInput )
+, xSeek( xNewInput, UNO_QUERY )
+, aEntry (rNewEntry )
+, nCurrent( 0 )
+, bHaveInMemory ( sal_False )
+, aInflater( sal_True )
+, aBuffer( 0 )
+, xEncryptionData (xEncryptData)
+, bRawStream (bGetRawStream)
+{
+ if (bGetRawStream)
+ {
+ nUncompressedSize = aEntry.nMethod == DEFLATED ? aEntry.nCompressedSize : aEntry.nSize;
+ nEnd = aEntry.nOffset + nUncompressedSize;
+ }
+ else
+ {
+ nEnd = aEntry.nMethod == DEFLATED ? aEntry.nOffset + aEntry.nCompressedSize : aEntry.nOffset + aEntry.nSize;
+ nUncompressedSize = aEntry.nSize;
+ }
+}
+void EntryInputStream::readIntoMemory()
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ if (!bHaveInMemory)
+ {
+ Sequence < sal_Int8 > aReadBuffer;
+ xSeek->seek(aEntry.nOffset);
+ sal_Int32 nSize = aEntry.nMethod == DEFLATED ? aEntry.nCompressedSize : aEntry.nSize;
+
+ if (nSize <0)
+ throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+
+ xStream->readBytes( aReadBuffer, nSize ); // Now it holds the raw stuff from disk
+
+ if (xEncryptionData->aSalt.getLength())
+ {
+ // Have salt, will travel
+ Sequence < sal_uInt8 > aDerivedKey (16);
+ rtlCipherError aResult;
+ Sequence < sal_Int8 > aDecryptBuffer;
+
+ // Get the key
+ rtl_digest_PBKDF2 ( aDerivedKey.getArray(), 16,
+ reinterpret_cast < const sal_uInt8 * > (xEncryptionData->aKey.getConstArray()),
+ xEncryptionData->aKey.getLength(),
+ xEncryptionData->aSalt.getConstArray(),
+ xEncryptionData->aSalt.getLength(),
+ xEncryptionData->nIterationCount );
+
+ rtlCipher aCipher = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream);
+ aResult = rtl_cipher_init( aCipher, rtl_Cipher_DirectionDecode,
+ aDerivedKey.getConstArray(),
+ aDerivedKey.getLength(),
+ xEncryptionData->aInitVector.getConstArray(),
+ xEncryptionData->aInitVector.getLength());
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ aDecryptBuffer.realloc ( nSize );
+ aResult = rtl_cipher_decode ( aCipher,
+ aReadBuffer.getConstArray(),
+ nSize,
+ reinterpret_cast < sal_uInt8 * > (aDecryptBuffer.getArray()),
+ nSize);
+ OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ aReadBuffer = aDecryptBuffer; // Now it holds the decrypted data
+ }
+ if (bRawStream || aEntry.nMethod == STORED)
+ aBuffer = aReadBuffer; // bRawStream means the caller doesn't want it decompressed
+ else
+ {
+ aInflater.setInputSegment(aReadBuffer, 0, nSize );
+ aBuffer.realloc( aEntry.nSize );
+ aInflater.doInflate(aBuffer);
+ aInflater.end();
+ }
+ bHaveInMemory = sal_True;
+ }
+}
+EntryInputStream::~EntryInputStream( void )
+{
+}
+
+sal_Int32 SAL_CALL EntryInputStream::readBytes( Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ if (nBytesToRead <0)
+ throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+ if (!bHaveInMemory)
+ readIntoMemory();
+ if (nBytesToRead + nCurrent > nUncompressedSize)
+ nBytesToRead = static_cast < sal_Int32> ( nUncompressedSize - nCurrent );
+
+ aData.realloc( nBytesToRead );
+ memcpy(aData.getArray(), aBuffer.getConstArray() + nCurrent, nBytesToRead);
+ nCurrent+=nBytesToRead;
+
+ return nBytesToRead;
+}
+sal_Int32 SAL_CALL EntryInputStream::readSomeBytes( Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ return readBytes( aData, nMaxBytesToRead );
+}
+void SAL_CALL EntryInputStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+{
+ if (nBytesToSkip < 0)
+ throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+
+ if (nBytesToSkip + nCurrent > nUncompressedSize)
+ nBytesToSkip = static_cast < sal_Int32 > (nUncompressedSize- nCurrent);
+
+ nCurrent+=nBytesToSkip;
+}
+sal_Int32 SAL_CALL EntryInputStream::available( )
+ throw(io::NotConnectedException, io::IOException, RuntimeException)
+{
+ return static_cast < sal_Int32 > (nUncompressedSize - nCurrent);
+}
+void SAL_CALL EntryInputStream::closeInput( )
+ throw(io::NotConnectedException, io::IOException, RuntimeException)
+{
+}
+
+void SAL_CALL EntryInputStream::seek( sal_Int64 location )
+ throw(lang::IllegalArgumentException, io::IOException, RuntimeException)
+{
+ if (location > nUncompressedSize)
+ location = nUncompressedSize;
+ if (location <0)
+ location = 0;
+ nCurrent = location;
+}
+sal_Int64 SAL_CALL EntryInputStream::getPosition( )
+ throw(io::IOException, RuntimeException)
+{
+ return nCurrent;
+}
+sal_Int64 SAL_CALL EntryInputStream::getLength( )
+ throw(io::IOException, RuntimeException)
+{
+ return nUncompressedSize;
+}
diff --git a/package/source/zipapi/EntryInputStream.hxx b/package/source/zipapi/EntryInputStream.hxx
new file mode 100644
index 000000000000..a425f295b9ab
--- /dev/null
+++ b/package/source/zipapi/EntryInputStream.hxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * $RCSfile: EntryInputStream.hxx,v $
+ *
+ * $Revision: 1.8 $
+ *
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ *
+ ************************************************************************/
+#ifndef _ENTRY_INPUT_STREAM_HXX
+#define _ENTRY_INPUT_STREAM_HXX
+
+#ifndef _CPPUHELPER_IMPLBASE2_HXX_
+#include <cppuhelper/implbase2.hxx> // helper for implementations
+#endif
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
+#include <com/sun/star/io/XSeekable.hpp>
+#endif
+#ifndef _INFLATER_HXX_
+#include <Inflater.hxx>
+#endif
+#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPENTRY_HPP_
+#include <com/sun/star/packages/zip/ZipEntry.hpp>
+#endif
+#ifndef _VOS_REF_H_
+#include <vos/ref.hxx>
+#endif
+#ifndef _ENCRYPTION_DATA_HXX
+#include <EncryptionData.hxx>
+#endif
+class EntryInputStream : public cppu::WeakImplHelper2< com::sun::star::io::XInputStream,
+ com::sun::star::io::XSeekable >
+{
+protected:
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xStream;
+ com::sun::star::uno::Reference< com::sun::star::io::XSeekable > xSeek;
+ sal_Int64 nEnd, nCurrent, nUncompressedSize;
+ sal_Bool bRawStream, bHaveInMemory, bEncrypted;
+ com::sun::star::uno::Sequence < sal_Int8 > aBuffer;
+ const vos::ORef < EncryptionData > xEncryptionData;
+ const com::sun::star::packages::zip::ZipEntry aEntry;
+ Inflater aInflater;
+ void readIntoMemory()
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+public:
+ EntryInputStream( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xInput,
+ const com::sun::star::packages::zip::ZipEntry &rNewEntry,
+ const vos::ORef < EncryptionData > &xEncryptData,
+ sal_Bool bGetRawStream = sal_False);
+ virtual ~EntryInputStream();
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( )
+ throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ /*
+private:
+ void fill( void );
+ */
+};
+
+#endif
diff --git a/package/source/zipapi/MemoryByteGrabber.hxx b/package/source/zipapi/MemoryByteGrabber.hxx
index 16d3c9808423..d9004060a57f 100644
--- a/package/source/zipapi/MemoryByteGrabber.hxx
+++ b/package/source/zipapi/MemoryByteGrabber.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: MemoryByteGrabber.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: hr $ $Date: 2002-02-21 14:32:09 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:45 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -61,8 +61,6 @@
#ifndef _MEMORY_BYTE_GRABBER_HXX_
#define _MEMORY_BYTE_GRABBER_HXX_
-#include <string.h>
-
#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
diff --git a/package/source/zipapi/XUnbufferedStream.cxx b/package/source/zipapi/XUnbufferedStream.cxx
index b307cde1dde8..fa7923758c74 100644
--- a/package/source/zipapi/XUnbufferedStream.cxx
+++ b/package/source/zipapi/XUnbufferedStream.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: XUnbufferedStream.cxx,v $
*
- * $Revision: 1.4 $
+ * $Revision: 1.5 $
*
- * last change: $Author: hr $ $Date: 2002-02-21 14:32:09 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:45 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -58,7 +58,6 @@
*
*
************************************************************************/
-#include <string.h>
#ifndef _XUNBUFFERED_STREAM_HXX
#include <XUnbufferedStream.hxx>
#endif
@@ -68,6 +67,9 @@
#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPCONSTANTS_HPP_
#include <com/sun/star/packages/zip/ZipConstants.hpp>
#endif
+#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPIOEXCEPTION_HPP_
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#endif
#ifndef _PACKAGE_CONSTANTS_HXX_
#include <PackageConstants.hxx>
#endif
@@ -82,11 +84,11 @@
#endif
#include <algorithm>
-
using namespace com::sun::star::packages::zip::ZipConstants;
using namespace com::sun::star::io;
using namespace com::sun::star::uno;
using com::sun::star::lang::IllegalArgumentException;
+using com::sun::star::packages::zip::ZipIOException;
using ::rtl::OUString;
XUnbufferedStream::XUnbufferedStream( ZipEntry & rEntry,
@@ -170,15 +172,23 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
if ( !mbRawStream )
{
- while ( 0 == ( nRead = maInflater.doInflateSegment( aData, nRead, aData.getLength() - nRead ) ) ||
- ( nRead + nLastRead < nRequestedBytes && mnZipCurrent < mnZipEnd ) )
+ while ( 0 == ( nLastRead = maInflater.doInflateSegment( aData, nRead, aData.getLength() - nRead ) ) ||
+ ( nRead + nLastRead != nRequestedBytes && mnZipCurrent < mnZipEnd ) )
{
- nLastRead = nRead;
- if ( maInflater.finished() || maInflater.needsDictionary() )
- {
- // some error handling ?
- return nRead + nLastRead;
- }
+ nRead += nLastRead;
+
+ if ( nRead > nRequestedBytes )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Should not be possible to read more then requested!" ) ),
+ Reference< XInterface >() );
+
+ if ( maInflater.finished() )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+
+ if ( maInflater.needsDictionary() )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Dictionaries are not supported!" ) ),
+ Reference< XInterface >() );
sal_Int32 nDiff = static_cast < sal_Int32 > ( mnZipEnd - mnZipCurrent );
if ( nDiff > 0 )
@@ -191,6 +201,7 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
// before passing to the Inflater
if ( maCipher )
{
+ maCRC.update( maCompBuffer );
Sequence < sal_Int8 > aCryptBuffer ( nZipRead );
rtlCipherError aResult = rtl_cipher_decode ( maCipher,
maCompBuffer.getConstArray(),
@@ -205,8 +216,8 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
}
else
{
- // some error handling ?
- return nRead + nLastRead;
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
}
}
}
@@ -214,14 +225,29 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
{
sal_Int64 nDiff = mnZipEnd - mnZipCurrent;
mxZipSeek->seek ( mnZipCurrent );
- nRead = mxZipStream->readBytes ( aData, static_cast < sal_Int32 > ( nDiff < nRequestedBytes ? nDiff : nRequestedBytes ) );
+ nRead = mxZipStream->readBytes (
+ aData,
+ static_cast < sal_Int32 > ( nDiff < nRequestedBytes ? nDiff : nRequestedBytes ) );
+
mnZipCurrent += nRead;
}
- mnMyCurrent += nRead;
+
+ mnMyCurrent += nRead + nLastRead;
nTotal = nRead + nLastRead;
if ( nTotal < nRequestedBytes)
aData.realloc ( nTotal );
+
+ if ( !mbRawStream )
+ {
+ if ( !maCipher )
+ maCRC.update( aData );
+
+ if ( mnZipSize == mnMyCurrent && maCRC.getValue() != maEntry.nCrc )
+ throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+ }
}
+
return nTotal;
}
diff --git a/package/source/zipapi/XUnbufferedStream.hxx b/package/source/zipapi/XUnbufferedStream.hxx
index b2494545a745..affe7de932f1 100644
--- a/package/source/zipapi/XUnbufferedStream.hxx
+++ b/package/source/zipapi/XUnbufferedStream.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: XUnbufferedStream.hxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: mtg $ $Date: 2001-12-04 17:41:17 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:45 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -88,6 +88,9 @@
#ifndef _ZIP_ENTRY_HXX_
#include <ZipEntry.hxx>
#endif
+#ifndef _CRC32_HXX_
+#include <CRC32.hxx>
+#endif
class EncryptionData;
typedef void* rtlCipher;
@@ -107,6 +110,7 @@ protected:
sal_Bool mbRawStream, mbFinished;
sal_Int16 mnHeaderToRead;
sal_Int64 mnZipCurrent, mnZipEnd, mnZipSize, mnMyCurrent;
+ CRC32 maCRC;
public:
XUnbufferedStream( ZipEntry & rEntry,
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index f7b2109bb1e9..61eac82808a1 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipFile.cxx,v $
*
- * $Revision: 1.36 $
+ * $Revision: 1.37 $
*
- * last change: $Author: mav $ $Date: 2002-09-25 10:28:31 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:45 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -99,6 +99,14 @@
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
+#ifndef _COM_SUN_STAR_UCB_XPROGRESSHANDLER_HPP_
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#endif
+
+#ifndef _CRC32_HXX_
+#include <CRC32.hxx>
+#endif
+
#include <string.h> // for memcpy
#include <vector>
@@ -107,6 +115,7 @@ using namespace rtl;
using namespace com::sun::star;
using namespace com::sun::star::io;
using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
using namespace com::sun::star::lang;
using namespace com::sun::star::packages;
using namespace com::sun::star::packages::zip;
@@ -115,7 +124,7 @@ using namespace com::sun::star::packages::zip::ZipConstants;
/** This class is used to read entries from a zip file
*/
-ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiServiceFactory > &xNewFactory, sal_Bool bInitialise)
+ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiServiceFactory > &xNewFactory, sal_Bool bInitialise )
throw(IOException, ZipException, RuntimeException)
: xStream(xInput)
, xSeek(xInput, UNO_QUERY)
@@ -133,6 +142,31 @@ ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiSe
}
}
+
+
+ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiServiceFactory > &xNewFactory, sal_Bool bInitialise, sal_Bool bForceRecovery, Reference < XProgressHandler > xProgress )
+ throw(IOException, ZipException, RuntimeException)
+: xStream(xInput)
+, xSeek(xInput, UNO_QUERY)
+, aGrabber(xInput)
+, aInflater (sal_True)
+, xFactory ( xNewFactory )
+, xProgressHandler( xProgress )
+{
+ if (bInitialise)
+ {
+ if ( bForceRecovery )
+ {
+ recover();
+ }
+ else if ( readCEN() == -1 )
+ {
+ aEntries.clear();
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "stream data looks to be broken" ) ), Reference < XInterface > () );
+ }
+ }
+}
+
ZipFile::~ZipFile()
{
aEntries.clear();
@@ -496,8 +530,8 @@ Reference< XInputStream > SAL_CALL ZipFile::getRawStream( ZipEntry& rEntry,
sal_Bool ZipFile::readLOC( ZipEntry &rEntry )
throw(IOException, ZipException, RuntimeException)
{
- sal_uInt32 nTestSig, nTime, nCRC, nSize, nCompressedSize;
- sal_uInt16 nVersion, nFlag, nHow, nNameLen, nExtraLen;
+ sal_Int32 nTestSig, nTime, nCRC, nSize, nCompressedSize;
+ sal_Int16 nVersion, nFlag, nHow, nNameLen, nExtraLen;
sal_Int32 nPos = -rEntry.nOffset;
aGrabber.seek(nPos);
@@ -515,6 +549,20 @@ sal_Bool ZipFile::readLOC( ZipEntry &rEntry )
aGrabber >> nNameLen;
aGrabber >> nExtraLen;
rEntry.nOffset = static_cast < sal_Int32 > (aGrabber.getPosition()) + nNameLen + nExtraLen;
+
+ if ( rEntry.nNameLen == -1 ) // the file was created
+ rEntry.nNameLen = nNameLen;
+
+ // the method can be reset for internal use so it is not checked
+ sal_Bool bBroken = rEntry.nVersion != nVersion
+ || rEntry.nFlag != nFlag
+ || rEntry.nTime != nTime
+ || rEntry.nNameLen != nNameLen;
+
+ if ( bBroken )
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM( "The stream seems to be broken!" ) ),
+ Reference< XInterface >() );
+
return sal_True;
}
@@ -600,7 +648,7 @@ sal_Int32 ZipFile::readCEN()
ZipEntry aEntry;
sal_Int32 nTestSig;
- sal_Int16 nNameLen, nExtraLen, nCommentLen;
+ sal_Int16 nCommentLen;
for (nCount = 0 ; nCount < nTotal; nCount++)
{
@@ -624,8 +672,8 @@ sal_Int32 ZipFile::readCEN()
aMemGrabber >> aEntry.nCrc;
aMemGrabber >> aEntry.nCompressedSize;
aMemGrabber >> aEntry.nSize;
- aMemGrabber >> nNameLen;
- aMemGrabber >> nExtraLen;
+ aMemGrabber >> aEntry.nNameLen;
+ aMemGrabber >> aEntry.nExtraLen;
aMemGrabber >> nCommentLen;
aMemGrabber.skipBytes ( 8 );
aMemGrabber >> aEntry.nOffset;
@@ -633,20 +681,20 @@ sal_Int32 ZipFile::readCEN()
aEntry.nOffset += nLocPos;
aEntry.nOffset *= -1;
- if ( nNameLen > ZIP_MAXNAMELEN )
+ if ( aEntry.nNameLen > ZIP_MAXNAMELEN )
throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "name length exceeds ZIP_MAXNAMELEN bytes" ) ), Reference < XInterface > () );
if ( nCommentLen > ZIP_MAXNAMELEN )
throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "comment length exceeds ZIP_MAXNAMELEN bytes" ) ), Reference < XInterface > () );
- if ( nExtraLen > ZIP_MAXEXTRA )
+ if ( aEntry.nExtraLen > ZIP_MAXEXTRA )
throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "extra header info exceeds ZIP_MAXEXTRA bytes") ), Reference < XInterface > () );
aEntry.sName = OUString ( (sal_Char *) aMemGrabber.getCurrentPos(),
- nNameLen,
+ aEntry.nNameLen,
RTL_TEXTENCODING_ASCII_US);
- aMemGrabber.skipBytes( nNameLen + nExtraLen + nCommentLen );
+ aMemGrabber.skipBytes( aEntry.nNameLen + aEntry.nExtraLen + nCommentLen );
aEntries[aEntry.sName] = aEntry;
}
@@ -660,3 +708,220 @@ sal_Int32 ZipFile::readCEN()
}
return nCenPos;
}
+
+sal_Int32 ZipFile::recover()
+ throw(IOException, ZipException, RuntimeException)
+{
+ sal_Int32 nLength;
+ Sequence < sal_Int8 > aBuffer;
+ Sequence < sal_Int32 > aHeaderOffsets;
+ sal_Int32 nNumOfHeaders = 0;
+
+ try
+ {
+ nLength = static_cast <sal_Int32 > (aGrabber.getLength());
+ if (nLength == 0 || nLength < ENDHDR)
+ return -1;
+
+ aGrabber.seek( 0 );
+
+ for( sal_Int32 nGenPos = 0; aGrabber.readBytes( aBuffer, 32000 ) && aBuffer.getLength() > 30; )
+ {
+ const sal_Int8 *pBuffer = aBuffer.getConstArray();
+ sal_Int32 nBufSize = aBuffer.getLength();
+
+ sal_Int32 nPos = 0;
+ while( nPos < nBufSize - 16 )
+ {
+ if ( nPos < nBufSize - 30 && pBuffer[nPos] == 'P' && pBuffer[nPos+1] == 'K' && pBuffer[nPos+2] == 3 && pBuffer[nPos+3] == 4 )
+ {
+ ZipEntry aEntry;
+ MemoryByteGrabber aMemGrabber ( Sequence< sal_Int8 >( ((sal_Int8*)(&(pBuffer[nPos+4]))), 26 ) );
+
+ aMemGrabber >> aEntry.nVersion;
+ if ( ( aEntry.nVersion & 1 ) != 1 )
+ {
+ aMemGrabber >> aEntry.nFlag;
+ aMemGrabber >> aEntry.nMethod;
+
+ if ( aEntry.nMethod == STORED || aEntry.nMethod == DEFLATED )
+ {
+ aMemGrabber >> aEntry.nTime;
+ aMemGrabber >> aEntry.nCrc;
+ aMemGrabber >> aEntry.nCompressedSize;
+ aMemGrabber >> aEntry.nSize;
+ aMemGrabber >> aEntry.nNameLen;
+ aMemGrabber >> aEntry.nExtraLen;
+
+ sal_Int32 nDescrLength =
+ ( aEntry.nMethod == DEFLATED && ( aEntry.nFlag & 8 ) ) ?
+ 16 : 0;
+
+ sal_Int32 nBlockLength = aEntry.nSize + aEntry.nNameLen + aEntry.nExtraLen + 30 + nDescrLength;
+ if ( aEntry.nNameLen <= ZIP_MAXNAMELEN && aEntry.nExtraLen < ZIP_MAXEXTRA
+ && ( nGenPos + nPos + nBlockLength ) <= nLength )
+ {
+ if( nPos + 30 + aEntry.nNameLen <= 32000 )
+ aEntry.sName = OUString ( (sal_Char *) &pBuffer[nPos + 30],
+ aEntry.nNameLen,
+ RTL_TEXTENCODING_ASCII_US);
+ else
+ {
+ Sequence < sal_Int8 > aFileName;
+ aGrabber.seek( nGenPos + nPos + 30 );
+ aGrabber.readBytes( aFileName, aEntry.nNameLen );
+ aEntry.sName = OUString ( (sal_Char *) aFileName.getArray(),
+ aFileName.getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ aEntry.nNameLen = aFileName.getLength();
+ }
+
+ aEntry.nOffset = nGenPos + nPos + 30 + aEntry.nNameLen + aEntry.nExtraLen;
+
+ if ( ( aEntry.nSize || aEntry.nCompressedSize ) && !checkSizeAndCRC( aEntry ) )
+ {
+ aEntry.nCrc = 0;
+ aEntry.nCompressedSize = 0;
+ aEntry.nSize = 0;
+ }
+
+ if ( aEntries.find( aEntry.sName ) == aEntries.end() )
+ aEntries[aEntry.sName] = aEntry;
+ }
+ }
+ }
+
+ nPos += 4;
+ }
+ else if (pBuffer[nPos] == 'P' && pBuffer[nPos+1] == 'K' && pBuffer[nPos+2] == 7 && pBuffer[nPos+3] == 8 )
+ {
+ sal_Int32 nCompressedSize, nSize, nCRC32;
+ MemoryByteGrabber aMemGrabber ( Sequence< sal_Int8 >( ((sal_Int8*)(&(pBuffer[nPos+4]))), 12 ) );
+ aMemGrabber >> nCRC32;
+ aMemGrabber >> nCompressedSize;
+ aMemGrabber >> nSize;
+
+ for( EntryHash::iterator aIter = aEntries.begin(); aIter != aEntries.end(); aIter++ )
+ {
+ ZipEntry aTmp = (*aIter).second;
+ if( (*aIter).second.nMethod == DEFLATED && (*aIter).second.nFlag & 8 )
+ {
+ sal_Int32 nStreamOffset = nGenPos + nPos - nCompressedSize;
+ sal_Int32 nTmp1 = (*aIter).second.nOffset;
+ if ( nStreamOffset == (*aIter).second.nOffset && nCompressedSize > (*aIter).second.nCompressedSize )
+ {
+ sal_Int32 nRealSize = 0, nRealCRC = 0;
+ getSizeAndCRC( nStreamOffset, nCompressedSize, &nRealSize, &nRealCRC );
+ if ( nRealSize == nSize && nRealCRC == nCRC32 )
+ {
+ (*aIter).second.nCrc = nCRC32;
+ (*aIter).second.nCompressedSize = nCompressedSize;
+ (*aIter).second.nSize = nSize;
+ }
+ }
+#if 0
+// for now ignore clearly broken streams
+ else if( !(*aIter).second.nCompressedSize )
+ {
+ (*aIter).second.nCrc = nCRC32;
+ sal_Int32 nRealStreamSize = nGenPos + nPos - (*aIter).second.nOffset;
+ (*aIter).second.nCompressedSize = nGenPos + nPos - (*aIter).second.nOffset;
+ (*aIter).second.nSize = nSize;
+ }
+#endif
+ }
+ }
+
+ nPos += 4;
+ }
+ else
+ nPos++;
+ }
+
+ nGenPos += nPos;
+ aGrabber.seek( nGenPos );
+ }
+
+ return 0;
+ }
+ catch ( IllegalArgumentException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ catch ( NotConnectedException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ catch ( BufferSizeExceededException& )
+ {
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+ }
+ throw ZipException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Zip END signature not found!") ), Reference < XInterface > () );
+
+}
+
+sal_Bool ZipFile::checkSizeAndCRC( const ZipEntry& aEntry )
+{
+ sal_Int32 nSize = 0, nCRC = 0;
+
+ if( aEntry.nMethod == STORED )
+ return ( getCRC( aEntry.nOffset, aEntry.nSize ) == aEntry.nCrc );
+
+ getSizeAndCRC( aEntry.nOffset, aEntry.nCompressedSize, &nSize, &nCRC );
+ return ( aEntry.nSize == nSize && aEntry.nCrc == nCRC );
+}
+
+sal_Int32 ZipFile::getCRC( sal_Int32 nOffset, sal_Int32 nSize )
+{
+ Sequence < sal_Int8 > aBuffer;
+ CRC32 aCRC;
+ sal_Int32 nBlockSize = ::std::min( nSize, 32000L );
+
+ aGrabber.seek( nOffset );
+ for ( int ind = 0;
+ aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nSize;
+ ind++ )
+ {
+ aCRC.updateSegment( aBuffer, 0, ::std::min( nBlockSize, nSize - ind * nBlockSize ) );
+ }
+
+ return aCRC.getValue();
+}
+
+void ZipFile::getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC )
+{
+ Sequence < sal_Int8 > aBuffer;
+ CRC32 aCRC;
+ sal_Int32 nRealSize = 0;
+ Inflater aInflater( sal_True );
+ sal_Int32 nBlockSize = ::std::min( nCompressedSize, 32000L );
+
+ aGrabber.seek( nOffset );
+ for ( int ind = 0;
+ !aInflater.finished() && aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nCompressedSize;
+ ind++ )
+ {
+ Sequence < sal_Int8 > aData( nBlockSize );
+ sal_Int32 nLastInflated = 0;
+ sal_Int32 nInBlock = 0;
+
+ aInflater.setInput( aBuffer );
+ do
+ {
+ nLastInflated = aInflater.doInflateSegment( aData, 0, nBlockSize );
+ aCRC.updateSegment( aData, 0, nLastInflated );
+ nInBlock += nLastInflated;
+ } while( !aInflater.finished() && nLastInflated );
+
+ nRealSize += nInBlock;
+ }
+
+ if( aInflater.finished() )
+ {
+ *nSize = nRealSize;
+ *nCRC = aCRC.getValue();
+ }
+ else
+ *nSize = *nCRC = 0;
+
+}
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index d829032fd38d..aa74a46f5c8e 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipPackage.cxx,v $
*
- * $Revision: 1.85 $
+ * $Revision: 1.86 $
*
- * last change: $Author: mav $ $Date: 2002-09-25 10:34:04 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:49 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -139,6 +139,9 @@
#ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
#include <com/sun/star/ucb/OpenMode.hpp>
#endif
+#ifndef _COM_SUN_STAR_UCB_XPROGRESSHANDLER_HPP_
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASTREAMER_HPP_
#include <com/sun/star/io/XActiveDataStreamer.hpp>
#endif
@@ -255,6 +258,7 @@ ZipPackage::ZipPackage (const Reference < XMultiServiceFactory > &xNewFactory)
, xFactory( xNewFactory )
, bHasEncryptedEntries ( sal_False )
, bUseManifest ( sal_True )
+, bForceRecovery ( sal_False )
, eMode ( e_IMode_None )
{
xRootFolder = pRootFolder = new ZipPackageFolder();
@@ -333,103 +337,110 @@ void ZipPackage::getZipFileContents()
const OUString sManifest (RTL_CONSTASCII_USTRINGPARAM( "META-INF/manifest.xml") );
if (hasByHierarchicalName( sManifest ) )
{
- Reference < XUnoTunnel > xTunnel;
- Any aAny = getByHierarchicalName( sManifest );
- aAny >>= xTunnel;
- Reference < XActiveDataSink > xSink (xTunnel, UNO_QUERY);
- if (xSink.is())
- {
- OUString sManifestReader ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.ManifestReader" ) );
- Reference < XManifestReader > xReader (xFactory->createInstance( sManifestReader ), UNO_QUERY );
- if ( xReader.is() )
+ try {
+ Reference < XUnoTunnel > xTunnel;
+ Any aAny = getByHierarchicalName( sManifest );
+ aAny >>= xTunnel;
+ Reference < XActiveDataSink > xSink (xTunnel, UNO_QUERY);
+ if (xSink.is())
{
- const OUString sPropFullPath ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
- const OUString sPropMediaType ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
- const OUString sPropInitialisationVector ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) );
- const OUString sPropSalt ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) );
- const OUString sPropIterationCount ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
- const OUString sPropSize ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
- const OUString sPropDigest ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
-
- Sequence < Sequence < PropertyValue > > aManifestSequence = xReader->readManifestSequence ( xSink->getInputStream() );
- sal_Int32 nLength = aManifestSequence.getLength();
- const Sequence < PropertyValue > *pSequence = aManifestSequence.getConstArray();
- ZipPackageStream *pStream = NULL;
- ZipPackageFolder *pFolder = NULL;
-
- for (sal_Int32 i = 0; i < nLength ; i++, pSequence++)
+ OUString sManifestReader ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.manifest.ManifestReader" ) );
+ Reference < XManifestReader > xReader (xFactory->createInstance( sManifestReader ), UNO_QUERY );
+ if ( xReader.is() )
{
- OUString sPath, sMediaType;
- const PropertyValue *pValue = pSequence->getConstArray();
- const Any *pSalt = NULL, *pVector = NULL, *pCount = NULL, *pSize = NULL, *pDigest = NULL;
- for (sal_Int32 j = 0, nNum = pSequence->getLength(); j < nNum; j++ )
- {
- if (pValue[j].Name.equals( sPropFullPath ) )
- pValue[j].Value >>= sPath;
- else if (pValue[j].Name.equals( sPropMediaType ) )
- pValue[j].Value >>= sMediaType;
- else if (pValue[j].Name.equals( sPropSalt ) )
- pSalt = &(pValue[j].Value);
- else if (pValue[j].Name.equals( sPropInitialisationVector ) )
- pVector = &(pValue[j].Value);
- else if (pValue[j].Name.equals( sPropIterationCount ) )
- pCount = &(pValue[j].Value);
- else if (pValue[j].Name.equals( sPropSize ) )
- pSize = &(pValue[j].Value);
- else if (pValue[j].Name.equals( sPropDigest ) )
- pDigest = &(pValue[j].Value);
- }
- if (sPath.getLength() && hasByHierarchicalName ( sPath ) )
+ const OUString sPropFullPath ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) );
+ const OUString sPropMediaType ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) );
+ const OUString sPropInitialisationVector ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) );
+ const OUString sPropSalt ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) );
+ const OUString sPropIterationCount ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
+ const OUString sPropSize ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
+ const OUString sPropDigest ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
+
+ Sequence < Sequence < PropertyValue > > aManifestSequence = xReader->readManifestSequence ( xSink->getInputStream() );
+ sal_Int32 nLength = aManifestSequence.getLength();
+ const Sequence < PropertyValue > *pSequence = aManifestSequence.getConstArray();
+ ZipPackageStream *pStream = NULL;
+ ZipPackageFolder *pFolder = NULL;
+
+ for (sal_Int32 i = 0; i < nLength ; i++, pSequence++)
{
- Any aAny = getByHierarchicalName( sPath );
- Reference < XUnoTunnel > xTunnel;
- aAny >>= xTunnel;
- sal_Int64 nTest=0;
- if ((nTest = xTunnel->getSomething(ZipPackageFolder::static_getImplementationId())) != 0)
+ OUString sPath, sMediaType;
+ const PropertyValue *pValue = pSequence->getConstArray();
+ const Any *pSalt = NULL, *pVector = NULL, *pCount = NULL, *pSize = NULL, *pDigest = NULL;
+ for (sal_Int32 j = 0, nNum = pSequence->getLength(); j < nNum; j++ )
{
- pFolder = reinterpret_cast < ZipPackageFolder* > ( nTest );
- pFolder->SetMediaType ( sMediaType );
+ if (pValue[j].Name.equals( sPropFullPath ) )
+ pValue[j].Value >>= sPath;
+ else if (pValue[j].Name.equals( sPropMediaType ) )
+ pValue[j].Value >>= sMediaType;
+ else if (pValue[j].Name.equals( sPropSalt ) )
+ pSalt = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropInitialisationVector ) )
+ pVector = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropIterationCount ) )
+ pCount = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropSize ) )
+ pSize = &(pValue[j].Value);
+ else if (pValue[j].Name.equals( sPropDigest ) )
+ pDigest = &(pValue[j].Value);
}
- else
+ if (sPath.getLength() && hasByHierarchicalName ( sPath ) )
{
- pStream = reinterpret_cast < ZipPackageStream* > ( xTunnel->getSomething(ZipPackageStream::static_getImplementationId()));
- pStream->SetMediaType ( sMediaType );
-
- if (pSalt && pVector && pCount && pSize)
+ Any aAny = getByHierarchicalName( sPath );
+ Reference < XUnoTunnel > xTunnel;
+ aAny >>= xTunnel;
+ sal_Int64 nTest=0;
+ if ((nTest = xTunnel->getSomething(ZipPackageFolder::static_getImplementationId())) != 0)
+ {
+ pFolder = reinterpret_cast < ZipPackageFolder* > ( nTest );
+ pFolder->SetMediaType ( sMediaType );
+ }
+ else
{
- Sequence < sal_uInt8 > aSequence;
- sal_Int32 nCount, nSize;
- pStream->SetToBeEncrypted ( sal_True );
+ pStream = reinterpret_cast < ZipPackageStream* > ( xTunnel->getSomething(ZipPackageStream::static_getImplementationId()));
+ pStream->SetMediaType ( sMediaType );
- *pSalt >>= aSequence;
- pStream->setSalt ( aSequence );
+ if (pSalt && pVector && pCount && pSize)
+ {
+ Sequence < sal_uInt8 > aSequence;
+ sal_Int32 nCount, nSize;
+ pStream->SetToBeEncrypted ( sal_True );
- *pVector >>= aSequence;
- pStream->setInitialisationVector ( aSequence );
+ *pSalt >>= aSequence;
+ pStream->setSalt ( aSequence );
- *pCount >>= nCount;
- pStream->setIterationCount ( nCount );
+ *pVector >>= aSequence;
+ pStream->setInitialisationVector ( aSequence );
- *pSize >>= nSize;
- pStream->setSize ( nSize );
+ *pCount >>= nCount;
+ pStream->setIterationCount ( nCount );
- if ( pDigest )
- {
- *pDigest >>= aSequence;
- pStream->setDigest ( aSequence );
- }
+ *pSize >>= nSize;
+ pStream->setSize ( nSize );
- pStream->SetToBeEncrypted ( sal_True );
- pStream->SetIsEncrypted ( sal_True );
- if ( !bHasEncryptedEntries && pStream->getName().compareToAscii ( "content.xml" ) == 0 )
- bHasEncryptedEntries = sal_True;
+ if ( pDigest )
+ {
+ *pDigest >>= aSequence;
+ pStream->setDigest ( aSequence );
+ }
+
+ pStream->SetToBeEncrypted ( sal_True );
+ pStream->SetIsEncrypted ( sal_True );
+ if ( !bHasEncryptedEntries && pStream->getName().compareToAscii ( "content.xml" ) == 0 )
+ bHasEncryptedEntries = sal_True;
+ }
}
}
}
}
+ else
+ VOS_ENSURE ( 0, "Couldn't get a ManifestReader!" ); // throw RuntimeException?
}
- else
- VOS_ENSURE ( 0, "Couldn't get a ManifestReader!" ); // throw RuntimeException?
+ }
+ catch( Exception& )
+ {
+ if ( !bForceRecovery )
+ throw;
}
}
@@ -447,49 +458,80 @@ void SAL_CALL ZipPackage::initialize( const Sequence< Any >& aArguments )
{
RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::initialize" );
sal_Bool bBadZipFile = sal_False, bHaveZipFile = sal_True;
+ Reference< XProgressHandler > xProgressHandler;
if ( aArguments.getLength() )
{
- if ( (aArguments[0] >>= sURL))
+ for( int ind = 0; ind < aArguments.getLength(); ind++ )
{
- eMode = e_IMode_URL;
- try
+ OUString aParamUrl;
+ if ( (aArguments[ind] >>= aParamUrl))
{
- Content aContent (sURL, Reference < XCommandEnvironment >() );
- Any aAny = aContent.getPropertyValue( OUString::createFromAscii( "Size" ) );
- sal_uInt64 aSize;
- // kind of optimisation: treat empty files as nonexistent files
- // and write to such files directly
- if( ( aAny >>= aSize ) && aSize )
+ eMode = e_IMode_URL;
+ try
{
- Reference < XActiveDataSink > xSink = new ZipPackageSink;
- if (aContent.openStream ( xSink ) )
- xContentStream = xSink->getInputStream();
+ sal_Int32 nParam = aParamUrl.indexOf( '?' );
+ if ( nParam >= 0 )
+ {
+ sURL = aParamUrl.copy( 0, nParam );
+ OUString aParam = aParamUrl.copy( nParam + 1 );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ if ( aParam.getToken( 0, '&', nIndex ).equals( OUString::createFromAscii( "repairpackage" ) ) )
+ {
+ bForceRecovery = sal_True;
+ break;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+ else
+ sURL = aParamUrl;
+
+ Content aContent ( sURL, Reference < XCommandEnvironment >() );
+ Any aAny = aContent.getPropertyValue( OUString::createFromAscii( "Size" ) );
+ sal_uInt64 aSize;
+ // kind of optimisation: treat empty files as nonexistent files
+ // and write to such files directly
+ if( ( aAny >>= aSize ) && aSize )
+ {
+ Reference < XActiveDataSink > xSink = new ZipPackageSink;
+ if (aContent.openStream ( xSink ) )
+ xContentStream = xSink->getInputStream();
+ }
+ else
+ bHaveZipFile = sal_False;
}
- else
+ catch (com::sun::star::uno::Exception&)
+ {
+ // Exception derived from uno::Exception thrown. This probably
+ // means the file doesn't exist...we'll create it at
+ // commitChanges time
bHaveZipFile = sal_False;
+ }
}
- catch (com::sun::star::uno::Exception&)
+ else if ( (aArguments[ind] >>= xContentStream) )
{
- // Exception derived from uno::Exception thrown. This probably
- // means the file doesn't exist...we'll create it at
- // commitChanges time
- bHaveZipFile = sal_False;
+ eMode = e_IMode_XInputStream;
+ }
+ else if ( (aArguments[ind] >>= xStream ) )
+ {
+ eMode = e_IMode_XStream;
+ xContentStream = xStream->getInputStream();
+ }
+ else if ( ( aArguments[ind] >>= xProgressHandler ) )
+ {
+ // progress handler is used only for repair feature
+ }
+ else
+ {
+ // The URL is not acceptable
+ throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Bad arguments." ) ),
+ static_cast < ::cppu::OWeakObject * > ( this ) );
}
}
- else if ( (aArguments[0] >>= xContentStream) )
- {
- eMode = e_IMode_XInputStream;
- }
- else if ( (aArguments[0] >>= xStream ) )
- {
- eMode = e_IMode_XStream;
- xContentStream = xStream->getInputStream();
- }
- else
- // The URL is not acceptable
- throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Bad URL." ) ),
- static_cast < ::cppu::OWeakObject * > ( this ) );
try
{
@@ -514,7 +556,7 @@ void SAL_CALL ZipPackage::initialize( const Sequence< Any >& aArguments )
{
try
{
- pZipFile = new ZipFile ( xContentStream, xFactory, sal_True );
+ pZipFile = new ZipFile ( xContentStream, xFactory, sal_True, bForceRecovery, xProgressHandler );
getZipFileContents();
}
catch ( IOException & )
@@ -540,6 +582,7 @@ void SAL_CALL ZipPackage::initialize( const Sequence< Any >& aArguments )
}
}
}
+
RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::initialize" );
}
@@ -1234,7 +1277,8 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const
if (!( aValue >>= bUseManifest ) )
throw IllegalArgumentException();
}
- throw UnknownPropertyException();
+ else
+ throw UnknownPropertyException();
}
Any SAL_CALL ZipPackage::getPropertyValue( const OUString& PropertyName )
throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index 0831a1866093..1e8d3c141098 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipPackageFolder.cxx,v $
*
- * $Revision: 1.59 $
+ * $Revision: 1.60 $
*
- * last change: $Author: hr $ $Date: 2002-08-20 12:58:51 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:49 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -170,6 +170,8 @@ void ZipPackageFolder::copyZipEntry( ZipEntry &rDest, const ZipEntry &rSource)
rDest.nSize = rSource.nSize;
rDest.nOffset = rSource.nOffset;
rDest.sName = rSource.sName;
+ rDest.nNameLen = rSource.nNameLen;
+ rDest.nExtraLen = rSource.nExtraLen;
}
#ifdef MACOSX
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 307944d97919..915432be39d7 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipPackageStream.cxx,v $
*
- * $Revision: 1.30 $
+ * $Revision: 1.31 $
*
- * last change: $Author: hr $ $Date: 2002-08-20 13:02:47 $
+ * last change: $Author: hr $ $Date: 2003-03-26 14:13:49 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -108,6 +108,9 @@ ZipPackageStream::ZipPackageStream (ZipPackage & rNewPackage )
aEntry.nCompressedSize = -1;
aEntry.nSize = -1;
aEntry.nOffset = -1;
+ aEntry.nNameLen = -1;
+ aEntry.nExtraLen = -1;
+
if ( !aImplementationId.getLength() )
{
#ifdef MACOSX
@@ -142,6 +145,8 @@ void ZipPackageStream::setZipEntry( const ZipEntry &rInEntry)
aEntry.nSize = rInEntry.nSize;
aEntry.nOffset = rInEntry.nOffset;
aEntry.sName = rInEntry.sName;
+ aEntry.nNameLen = rInEntry.nNameLen;
+ aEntry.nExtraLen = rInEntry.nExtraLen;
}
#ifdef MACOSX