diff options
author | Michael Meeks <michael.meeks@suse.com> | 2012-09-21 13:09:29 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-09-21 15:37:17 +0100 |
commit | 9b0198b2442bc749491d0f1e5e2c811346e5d568 (patch) | |
tree | 6af3f097947c8d5a4ebf5fd5599d1fe1fcc9e96c /package | |
parent | b3603e0e0e5dbfbeaa2426c499e8f64be2d15765 (diff) |
package: convert internal ZIP handling data-types to 64bit
Prepare for a ZIP64 implementation.
Audit all "Size" property fetches through Anys.
Audit all uses of nSize, nCompressedSize, nOffset through the code.
Add FIXME64: comments to all points requiring future work.
Diffstat (limited to 'package')
-rw-r--r-- | package/inc/CRC32.hxx | 2 | ||||
-rw-r--r-- | package/inc/ZipEntry.hxx | 6 | ||||
-rw-r--r-- | package/inc/ZipFile.hxx | 6 | ||||
-rw-r--r-- | package/inc/ZipPackageStream.hxx | 4 | ||||
-rw-r--r-- | package/inc/package/Deflater.hxx | 6 | ||||
-rw-r--r-- | package/qa/ofopxmlstorages/TestHelper.java | 4 | ||||
-rw-r--r-- | package/qa/storages/TestHelper.java | 6 | ||||
-rw-r--r-- | package/source/manifest/ManifestImport.cxx | 2 | ||||
-rw-r--r-- | package/source/xstor/owriteablestream.cxx | 19 | ||||
-rw-r--r-- | package/source/zipapi/CRC32.cxx | 8 | ||||
-rw-r--r-- | package/source/zipapi/Deflater.cxx | 8 | ||||
-rw-r--r-- | package/source/zipapi/ZipFile.cxx | 122 | ||||
-rw-r--r-- | package/source/zipapi/ZipOutputStream.cxx | 63 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackage.cxx | 12 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackageFolder.cxx | 9 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackageStream.cxx | 2 |
16 files changed, 179 insertions, 100 deletions
diff --git a/package/inc/CRC32.hxx b/package/inc/CRC32.hxx index 444c385cbb76..183c1befb906 100644 --- a/package/inc/CRC32.hxx +++ b/package/inc/CRC32.hxx @@ -33,7 +33,7 @@ public: CRC32(); ~CRC32(); - sal_Int32 SAL_CALL updateStream (::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > & xStream) + sal_Int64 SAL_CALL updateStream (::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > & xStream) throw(::com::sun::star::uno::RuntimeException); void SAL_CALL updateSegment(const ::com::sun::star::uno::Sequence< sal_Int8 > &b, sal_Int32 off, sal_Int32 len) throw(::com::sun::star::uno::RuntimeException); diff --git a/package/inc/ZipEntry.hxx b/package/inc/ZipEntry.hxx index 31469b07a7a8..98de664cce17 100644 --- a/package/inc/ZipEntry.hxx +++ b/package/inc/ZipEntry.hxx @@ -28,9 +28,9 @@ struct ZipEntry sal_Int16 nMethod; sal_Int32 nTime; sal_Int32 nCrc; - sal_Int32 nCompressedSize; - sal_Int32 nSize; - sal_Int32 nOffset; + sal_Int64 nCompressedSize; + sal_Int64 nSize; + sal_Int64 nOffset; sal_Int16 nPathLen; sal_Int16 nExtraLen; ::rtl::OUString sPath; diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx index 31ab8b432229..e438156cee0c 100644 --- a/package/inc/ZipFile.hxx +++ b/package/inc/ZipFile.hxx @@ -93,9 +93,9 @@ protected: sal_Bool checkSizeAndCRC( const ZipEntry& aEntry ); - sal_Int32 getCRC( sal_Int32 nOffset, sal_Int32 nSize ); + sal_Int32 getCRC( sal_Int64 nOffset, sal_Int64 nSize ); - void getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC ); + void getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_Int64 *nSize, sal_Int32 *nCRC ); public: @@ -136,7 +136,7 @@ public: bool bEncrypt ); static void StaticFillHeader ( const ::rtl::Reference < EncryptionData > & rData, - sal_Int32 nSize, + sal_Int64 nSize, const ::rtl::OUString& aMediaType, sal_Int8 * & pHeader ); diff --git a/package/inc/ZipPackageStream.hxx b/package/inc/ZipPackageStream.hxx index b7e528661eb8..a9943c19a7e0 100644 --- a/package/inc/ZipPackageStream.hxx +++ b/package/inc/ZipPackageStream.hxx @@ -98,7 +98,7 @@ public: { return m_xBaseEncryptionData->m_aSalt;} sal_Int32 getIterationCount () const { return m_xBaseEncryptionData->m_nIterationCount;} - sal_Int32 getSize () const + sal_Int64 getSize () const { return aEntry.nSize;} sal_uInt8 GetStreamMode() const { return m_nStreamMode; } @@ -133,7 +133,7 @@ public: { m_xBaseEncryptionData->m_aDigest = rNewDigest;} void setIterationCount (const sal_Int32 nNewCount) { m_xBaseEncryptionData->m_nIterationCount = nNewCount;} - void setSize (const sal_Int32 nNewSize); + void setSize (const sal_Int64 nNewSize); ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnStreamNoWrap() { return xStream; } diff --git a/package/inc/package/Deflater.hxx b/package/inc/package/Deflater.hxx index 3bfca03cb32c..7531e3a1ac66 100644 --- a/package/inc/package/Deflater.hxx +++ b/package/inc/package/Deflater.hxx @@ -37,7 +37,7 @@ protected: sal_Bool bFinished; sal_Bool bSetParams; sal_Int32 nLevel, nStrategy; - sal_Int32 nOffset, nLength; + sal_Int64 nOffset, nLength; z_stream* pStream; void init (sal_Int32 nLevel, sal_Int32 nStrategy, sal_Bool bNowrap); @@ -52,8 +52,8 @@ public: void SAL_CALL finish( ); sal_Bool SAL_CALL finished( ); sal_Int32 SAL_CALL doDeflateSegment( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength ); - sal_Int32 SAL_CALL getTotalIn( ); - sal_Int32 SAL_CALL getTotalOut( ); + sal_Int64 SAL_CALL getTotalIn( ); + sal_Int64 SAL_CALL getTotalOut( ); void SAL_CALL reset( ); void SAL_CALL end( ); }; diff --git a/package/qa/ofopxmlstorages/TestHelper.java b/package/qa/ofopxmlstorages/TestHelper.java index fa2baf48b261..d3cdb109eac9 100644 --- a/package/qa/ofopxmlstorages/TestHelper.java +++ b/package/qa/ofopxmlstorages/TestHelper.java @@ -99,7 +99,7 @@ public class TestHelper { // check size property of the stream try { - int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) ); + long nSize = AnyConverter.toLong( xPropSet.getPropertyValue( "Size" ) ); if ( nSize != pBytes.length ) { Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" ); @@ -466,7 +466,7 @@ public class TestHelper { { // get "MediaType" and "Size" properties and control there values String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) ); - int nPropSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) ); + long nPropSize = AnyConverter.toLong( xPropSet.getPropertyValue( "Size" ) ); bOk = true; if ( !sPropMediaType.equals( sMediaType ) ) diff --git a/package/qa/storages/TestHelper.java b/package/qa/storages/TestHelper.java index a58425c03b47..82494c89bf87 100644 --- a/package/qa/storages/TestHelper.java +++ b/package/qa/storages/TestHelper.java @@ -98,7 +98,7 @@ public class TestHelper { // check size property of the stream try { - int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) ); + long nSize = AnyConverter.toLong( xPropSet.getPropertyValue( "Size" ) ); if ( nSize != pBytes.length ) { Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" ); @@ -188,7 +188,7 @@ public class TestHelper { // check size property of the stream try { - int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) ); + long nSize = AnyConverter.toLong( xPropSet.getPropertyValue( "Size" ) ); if ( nSize != pBytes.length ) { Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" ); @@ -825,7 +825,7 @@ public class TestHelper { { // get "MediaType" and "Size" properties and control there values String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) ); - int nPropSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) ); + long nPropSize = AnyConverter.toLong( xPropSet.getPropertyValue( "Size" ) ); boolean bPropCompress = AnyConverter.toBoolean( xPropSet.getPropertyValue( "Compressed" ) ); bOk = true; diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx index 7e68f6cc4a9e..10270683cf59 100644 --- a/package/source/manifest/ManifestImport.cxx +++ b/package/source/manifest/ManifestImport.cxx @@ -133,7 +133,7 @@ void ManifestImport::doFileEntry(StringHashMap &rConvertedAttribs) OUString sSize = rConvertedAttribs[sSizeAttribute]; if ( sSize.getLength() ) { - sal_Int32 nSize = sSize.toInt32(); + sal_Int64 nSize = sSize.toInt64(); aSequence[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty; aSequence[PKG_MNFST_UCOMPSIZE].Value <<= nSize; } diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx index 88371544f4b4..a8d1b925c5f5 100644 --- a/package/source/xstor/owriteablestream.cxx +++ b/package/source/xstor/owriteablestream.cxx @@ -914,7 +914,7 @@ void OWriteStream_Impl::Commit() { if ( m_pAntiImpl && !m_bHasInsertedStreamOptimization && m_pAntiImpl->m_xSeekable.is() ) { - m_aProps[nInd].Value <<= ((sal_Int32)m_pAntiImpl->m_xSeekable->getLength()); + m_aProps[nInd].Value <<= m_pAntiImpl->m_xSeekable->getLength(); xPropertySet->setPropertyValue( m_aProps[nInd].Name, m_aProps[nInd].Value ); } } @@ -1136,18 +1136,17 @@ uno::Sequence< beans::PropertyValue > OWriteStream_Impl::ReadPackageStreamProper if ( m_nStorageType == embed::StorageFormats::OFOPXML || m_nStorageType == embed::StorageFormats::PACKAGE ) { - aResult[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType") ); - aResult[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed") ); - aResult[2].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size") ); + aResult[0].Name = "MediaType"; + aResult[1].Name = "Compressed"; + aResult[2].Name = "Size"; if ( m_nStorageType == embed::StorageFormats::PACKAGE ) - aResult[3].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Encrypted") ); + aResult[3].Name = "Encrypted"; } else { - aResult[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed") ); - aResult[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size") ); - + aResult[0].Name = "Compressed"; + aResult[1].Name = "Size"; } // TODO: may be also raw stream should be marked @@ -2414,7 +2413,7 @@ void OWriteStream::CloseOutput_Impl() for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ ) { if ( m_pImpl->m_aProps[nInd].Name == "Size" ) - m_pImpl->m_aProps[nInd].Value <<= ((sal_Int32)m_xSeekable->getLength()); + m_pImpl->m_aProps[nInd].Value <<= m_xSeekable->getLength(); } } } @@ -3283,7 +3282,7 @@ uno::Any SAL_CALL OWriteStream::getPropertyValue( const ::rtl::OUString& aProp ) if ( !m_xSeekable.is() ) throw uno::RuntimeException(); - return uno::makeAny( (sal_Int32)m_xSeekable->getLength() ); + return uno::makeAny( m_xSeekable->getLength() ); } throw beans::UnknownPropertyException(); // TODO diff --git a/package/source/zipapi/CRC32.cxx b/package/source/zipapi/CRC32.cxx index e6ad6fb35f2e..6aee4d514136 100644 --- a/package/source/zipapi/CRC32.cxx +++ b/package/source/zipapi/CRC32.cxx @@ -48,8 +48,7 @@ sal_Int32 SAL_CALL CRC32::getValue() /** Update CRC32 with specified sequence of bytes */ void SAL_CALL CRC32::updateSegment(const Sequence< sal_Int8 > &b, - sal_Int32 off, - sal_Int32 len) + sal_Int32 off, sal_Int32 len) throw(RuntimeException) { nCRC = rtl_crc32(nCRC, b.getConstArray()+off, len ); @@ -62,10 +61,11 @@ void SAL_CALL CRC32::update(const Sequence< sal_Int8 > &b) nCRC = rtl_crc32(nCRC, b.getConstArray(),b.getLength()); } -sal_Int32 SAL_CALL CRC32::updateStream( Reference < XInputStream > & xStream ) +sal_Int64 SAL_CALL CRC32::updateStream( Reference < XInputStream > & xStream ) throw ( RuntimeException ) { - sal_Int32 nLength, nTotal = 0; + sal_Int32 nLength; + sal_Int64 nTotal = 0; Sequence < sal_Int8 > aSeq ( n_ConstBufferSize ); do { diff --git a/package/source/zipapi/Deflater.cxx b/package/source/zipapi/Deflater.cxx index 53323f036898..dc3d3442b446 100644 --- a/package/source/zipapi/Deflater.cxx +++ b/package/source/zipapi/Deflater.cxx @@ -167,13 +167,13 @@ sal_Int32 SAL_CALL Deflater::doDeflateSegment( uno::Sequence< sal_Int8 >& rBuffe OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength())); return doDeflateBytes(rBuffer, nNewOffset, nNewLength); } -sal_Int32 SAL_CALL Deflater::getTotalIn( ) +sal_Int64 SAL_CALL Deflater::getTotalIn( ) { - return pStream->total_in; + return pStream->total_in; // FIXME64: zlib doesn't look 64bit clean here } -sal_Int32 SAL_CALL Deflater::getTotalOut( ) +sal_Int64 SAL_CALL Deflater::getTotalOut( ) { - return pStream->total_out; + return pStream->total_out; // FIXME64: zlib doesn't look 64bit clean here } void SAL_CALL Deflater::reset( ) { diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx index 7b946c7df3fd..b655d3739cde 100644 --- a/package/source/zipapi/ZipFile.cxx +++ b/package/source/zipapi/ZipFile.cxx @@ -198,7 +198,7 @@ uno::Reference< xml::crypto::XCipherContext > ZipFile::StaticGetCipher( const un } void ZipFile::StaticFillHeader( const ::rtl::Reference< EncryptionData >& rData, - sal_Int32 nSize, + sal_Int64 nSize, const ::rtl::OUString& aMediaType, sal_Int8 * & pHeader ) { @@ -225,7 +225,8 @@ void ZipFile::StaticFillHeader( const ::rtl::Reference< EncryptionData >& rData, *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 16 ) & 0xFF); *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 24 ) & 0xFF); - // Then the size + // FIXME64: need to handle larger sizes + // Then the size: *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 0 ) & 0xFF); *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 8 ) & 0xFF); *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 16 ) & 0xFF); @@ -499,7 +500,7 @@ sal_Bool ZipFile::hasValidPassword ( ZipEntry & rEntry, const ::rtl::Reference< if ( rData.is() && rData->m_aKey.getLength() ) { xSeek->seek( rEntry.nOffset ); - sal_Int32 nSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize; + sal_Int64 nSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize; // Only want to read enough to verify the digest if ( nSize > n_ConstDigestDecrypt ) @@ -645,7 +646,7 @@ sal_Bool ZipFile::readLOC( ZipEntry &rEntry ) sal_Int32 nTestSig, nTime, nCRC, nSize, nCompressedSize; sal_Int16 nVersion, nFlag, nHow, nPathLen, nExtraLen; - sal_Int32 nPos = -rEntry.nOffset; + sal_Int64 nPos = -rEntry.nOffset; aGrabber.seek(nPos); aGrabber >> nTestSig; @@ -661,7 +662,9 @@ sal_Bool ZipFile::readLOC( ZipEntry &rEntry ) aGrabber >> nSize; aGrabber >> nPathLen; aGrabber >> nExtraLen; - rEntry.nOffset = static_cast < sal_Int32 > (aGrabber.getPosition()) + nPathLen + nExtraLen; + rEntry.nOffset = aGrabber.getPosition() + nPathLen + nExtraLen; + + // FIXME64: need to read 64bit LOC sal_Bool bBroken = sal_False; @@ -674,8 +677,8 @@ sal_Bool ZipFile::readLOC( ZipEntry &rEntry ) aNameBuffer.realloc( nRead ); ::rtl::OUString sLOCPath = rtl::OUString::intern( (sal_Char *) aNameBuffer.getArray(), - aNameBuffer.getLength(), - RTL_TEXTENCODING_UTF8 ); + aNameBuffer.getLength(), + RTL_TEXTENCODING_UTF8 ); if ( rEntry.nPathLen == -1 ) // the file was created { @@ -814,13 +817,27 @@ sal_Int32 ZipFile::readCEN() aMemGrabber >> aEntry.nTime; aMemGrabber >> aEntry.nCrc; - aMemGrabber >> aEntry.nCompressedSize; - aMemGrabber >> aEntry.nSize; + + sal_uInt32 nCompressedSize, nSize, nOffset; + + aMemGrabber >> nCompressedSize; + aMemGrabber >> nSize; aMemGrabber >> aEntry.nPathLen; aMemGrabber >> aEntry.nExtraLen; aMemGrabber >> nCommentLen; aMemGrabber.skipBytes ( 8 ); - aMemGrabber >> aEntry.nOffset; + aMemGrabber >> nOffset; + + // FIXME64: need to read the 64bit header instead + if ( nSize == 0xffffffff || + nOffset == 0xffffffff || + nCompressedSize == 0xffffffff ) { + throw ZipException("PK64 zip file entry", uno::Reference < XInterface > () ); + } else { + aEntry.nCompressedSize = nCompressedSize; + aEntry.nSize = nSize; + aEntry.nOffset = nOffset; + } aEntry.nOffset += nLocPos; aEntry.nOffset *= -1; @@ -862,25 +879,25 @@ sal_Int32 ZipFile::recover() { ::osl::MutexGuard aGuard( m_aMutex ); - sal_Int32 nLength; + sal_Int64 nLength; Sequence < sal_Int8 > aBuffer; Sequence < sal_Int32 > aHeaderOffsets; try { - nLength = static_cast <sal_Int32 > (aGrabber.getLength()); + nLength = aGrabber.getLength(); if (nLength == 0 || nLength < ENDHDR) return -1; aGrabber.seek( 0 ); - const sal_Int32 nToRead = 32000; - for( sal_Int32 nGenPos = 0; aGrabber.readBytes( aBuffer, nToRead ) && aBuffer.getLength() > 16; ) + const sal_Int64 nToRead = 32000; + for( sal_Int64 nGenPos = 0; aGrabber.readBytes( aBuffer, nToRead ) && aBuffer.getLength() > 16; ) { const sal_Int8 *pBuffer = aBuffer.getConstArray(); sal_Int32 nBufSize = aBuffer.getLength(); - sal_Int32 nPos = 0; + sal_Int64 nPos = 0; // the buffer should contain at least one header, // or if it is end of the file, at least the postheader with sizes and hash while( nPos < nBufSize - 30 @@ -900,44 +917,45 @@ sal_Int32 ZipFile::recover() if ( aEntry.nMethod == STORED || aEntry.nMethod == DEFLATED ) { + sal_uInt32 nCompressedSize, nSize; + aMemGrabber >> aEntry.nTime; aMemGrabber >> aEntry.nCrc; - aMemGrabber >> aEntry.nCompressedSize; - aMemGrabber >> aEntry.nSize; + aMemGrabber >> nCompressedSize; + aMemGrabber >> nSize; aMemGrabber >> aEntry.nPathLen; aMemGrabber >> aEntry.nExtraLen; - sal_Int32 nDescrLength = - ( aEntry.nMethod == DEFLATED && ( aEntry.nFlag & 8 ) ) ? - 16 : 0; - + // FIXME64: need to read the 64bit header instead + if ( nSize == 0xffffffff || + nCompressedSize == 0xffffffff ) { + throw ZipException("PK64 zip file entry", uno::Reference < XInterface > () ); + } else { + aEntry.nCompressedSize = nCompressedSize; + aEntry.nSize = nSize; + } - // This is a quick fix for OOo1.1RC - // For OOo2.0 the whole package must be switched to unsigned values - if ( aEntry.nCompressedSize < 0 ) aEntry.nCompressedSize = 0x7FFFFFFF; - if ( aEntry.nSize < 0 ) aEntry.nSize = 0x7FFFFFFF; - if ( aEntry.nPathLen < 0 ) aEntry.nPathLen = 0x7FFF; - if ( aEntry.nExtraLen < 0 ) aEntry.nExtraLen = 0x7FFF; - // End of quick fix + sal_Int32 nDescrLength = + ( aEntry.nMethod == DEFLATED && ( aEntry.nFlag & 8 ) ) ? 16 : 0; - sal_Int32 nDataSize = ( aEntry.nMethod == DEFLATED ) ? aEntry.nCompressedSize : aEntry.nSize; - sal_Int32 nBlockLength = nDataSize + aEntry.nPathLen + aEntry.nExtraLen + 30 + nDescrLength; + sal_Int64 nDataSize = ( aEntry.nMethod == DEFLATED ) ? aEntry.nCompressedSize : aEntry.nSize; + sal_Int64 nBlockLength = nDataSize + aEntry.nPathLen + aEntry.nExtraLen + 30 + nDescrLength; if ( aEntry.nPathLen >= 0 && aEntry.nExtraLen >= 0 && ( nGenPos + nPos + nBlockLength ) <= nLength ) { // read always in UTF8, some tools seem not to set UTF8 bit if( nPos + 30 + aEntry.nPathLen <= nBufSize ) aEntry.sPath = OUString ( (sal_Char *) &pBuffer[nPos + 30], - aEntry.nPathLen, - RTL_TEXTENCODING_UTF8 ); + aEntry.nPathLen, + RTL_TEXTENCODING_UTF8 ); else { Sequence < sal_Int8 > aFileName; aGrabber.seek( nGenPos + nPos + 30 ); aGrabber.readBytes( aFileName, aEntry.nPathLen ); aEntry.sPath = OUString ( (sal_Char *) aFileName.getArray(), - aFileName.getLength(), - RTL_TEXTENCODING_UTF8 ); + aFileName.getLength(), + RTL_TEXTENCODING_UTF8 ); aEntry.nPathLen = static_cast< sal_Int16 >(aFileName.getLength()); } @@ -960,11 +978,17 @@ sal_Int32 ZipFile::recover() } else if (pBuffer[nPos] == 'P' && pBuffer[nPos+1] == 'K' && pBuffer[nPos+2] == 7 && pBuffer[nPos+3] == 8 ) { - sal_Int32 nCompressedSize, nSize, nCRC32; + sal_Int32 nCRC32; + sal_uInt32 nCompressedSize32, nSize32; + sal_Int64 nCompressedSize, nSize; MemoryByteGrabber aMemGrabber ( Sequence< sal_Int8 >( ((sal_Int8*)(&(pBuffer[nPos+4]))), 12 ) ); aMemGrabber >> nCRC32; - aMemGrabber >> nCompressedSize; - aMemGrabber >> nSize; + aMemGrabber >> nCompressedSize32; + aMemGrabber >> nSize32; + + // FIXME64: work to be done here ... + nCompressedSize = nCompressedSize32; + nSize = nSize32; for( EntryHash::iterator aIter = aEntries.begin(); aIter != aEntries.end(); ++aIter ) { @@ -973,7 +997,7 @@ sal_Int32 ZipFile::recover() // this is a broken package, accept this block not only for DEFLATED streams if( (*aIter).second.nFlag & 8 ) { - sal_Int32 nStreamOffset = nGenPos + nPos - nCompressedSize; + sal_Int64 nStreamOffset = nGenPos + nPos - nCompressedSize; if ( nStreamOffset == (*aIter).second.nOffset && nCompressedSize > (*aIter).second.nCompressedSize ) { // only DEFLATED blocks need to be checked @@ -981,7 +1005,8 @@ sal_Int32 ZipFile::recover() if ( !bAcceptBlock ) { - sal_Int32 nRealSize = 0, nRealCRC = 0; + sal_Int64 nRealSize = 0; + sal_Int32 nRealCRC = 0; getSizeAndCRC( nStreamOffset, nCompressedSize, &nRealSize, &nRealCRC ); bAcceptBlock = ( nRealSize == nSize && nRealCRC == nCRC32 ); } @@ -1036,7 +1061,8 @@ sal_Bool ZipFile::checkSizeAndCRC( const ZipEntry& aEntry ) { ::osl::MutexGuard aGuard( m_aMutex ); - sal_Int32 nSize = 0, nCRC = 0; + sal_Int32 nCRC = 0; + sal_Int64 nSize = 0; if( aEntry.nMethod == STORED ) return ( getCRC( aEntry.nOffset, aEntry.nSize ) == aEntry.nCrc ); @@ -1045,34 +1071,36 @@ sal_Bool ZipFile::checkSizeAndCRC( const ZipEntry& aEntry ) return ( aEntry.nSize == nSize && aEntry.nCrc == nCRC ); } -sal_Int32 ZipFile::getCRC( sal_Int32 nOffset, sal_Int32 nSize ) +sal_Int32 ZipFile::getCRC( sal_Int64 nOffset, sal_Int64 nSize ) { ::osl::MutexGuard aGuard( m_aMutex ); Sequence < sal_Int8 > aBuffer; CRC32 aCRC; - sal_Int32 nBlockSize = ::std::min( nSize, static_cast< sal_Int32 >( 32000 ) ); + sal_Int32 nBlockSize = static_cast< sal_Int32 > (::std::min( nSize, static_cast< sal_Int64 >( 32000 ) ) ); 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 ) ); + sal_Int64 nLen = ::std::min( static_cast< sal_Int64 >( nBlockSize ), + nSize - ind * nBlockSize ); + aCRC.updateSegment( aBuffer, 0, static_cast< sal_Int32 >( nLen ) ); } return aCRC.getValue(); } -void ZipFile::getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC ) +void ZipFile::getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_Int64 *nSize, sal_Int32 *nCRC ) { ::osl::MutexGuard aGuard( m_aMutex ); Sequence < sal_Int8 > aBuffer; CRC32 aCRC; - sal_Int32 nRealSize = 0; + sal_Int64 nRealSize = 0; Inflater aInflaterLocal( sal_True ); - sal_Int32 nBlockSize = ::std::min( nCompressedSize, static_cast< sal_Int32 >( 32000 ) ); + sal_Int32 nBlockSize = static_cast< sal_Int32 > (::std::min( nCompressedSize, static_cast< sal_Int64 >( 32000 ) ) ); aGrabber.seek( nOffset ); for ( int ind = 0; @@ -1081,7 +1109,7 @@ void ZipFile::getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_I { Sequence < sal_Int8 > aData( nBlockSize ); sal_Int32 nLastInflated = 0; - sal_Int32 nInBlock = 0; + sal_Int64 nInBlock = 0; aInflaterLocal.setInput( aBuffer ); do diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx index 31278a491387..df5c70ffbf67 100644 --- a/package/source/zipapi/ZipOutputStream.cxx +++ b/package/source/zipapi/ZipOutputStream.cxx @@ -103,7 +103,7 @@ void SAL_CALL ZipOutputStream::putNextEntry( ZipEntry& rEntry, m_pCurrentStream = pStream; } sal_Int32 nLOCLength = writeLOC(rEntry); - rEntry.nOffset = static_cast < sal_Int32 > (aChucker.GetPosition()) - nLOCLength; + rEntry.nOffset = aChucker.GetPosition() - nLOCLength; aZipList.push_back( &rEntry ); pCurrentEntry = &rEntry; } @@ -258,6 +258,7 @@ void ZipOutputStream::doDeflate() mnDigested = mnDigested + static_cast< sal_Int16 >( nEat ); } + // FIXME64: uno::Sequence not 64bit safe. uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer ); aChucker.WriteBytes( aEncryptionBuffer ); @@ -275,6 +276,7 @@ void ZipOutputStream::doDeflate() if ( aDeflater.finished() && bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is() ) { + // FIXME64: sequence not 64bit safe. uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose(); if ( aEncryptionBuffer.getLength() ) { @@ -300,6 +302,18 @@ void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength) aChucker << nOffset; aChucker << static_cast < sal_Int16 > ( 0 ); } + +static sal_uInt32 getTruncated( sal_Int64 nNum, bool *pIsTruncated ) +{ + if( nNum >= 0xffffffff ) + { + *pIsTruncated = true; + return 0xffffffff; + } + else + return static_cast< sal_uInt32 >( nNum ); +} + void ZipOutputStream::writeCEN( const ZipEntry &rEntry ) throw(IOException, RuntimeException) { @@ -325,17 +339,28 @@ void ZipOutputStream::writeCEN( const ZipEntry &rEntry ) aChucker << rEntry.nFlag; aChucker << rEntry.nMethod; } + bool bWrite64Header = false; + aChucker << static_cast < sal_uInt32> ( rEntry.nTime ); aChucker << static_cast < sal_uInt32> ( rEntry.nCrc ); - aChucker << rEntry.nCompressedSize; - aChucker << rEntry.nSize; + aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); + aChucker << getTruncated( rEntry.nSize, &bWrite64Header ); aChucker << nNameLength; aChucker << static_cast < sal_Int16> (0); aChucker << static_cast < sal_Int16> (0); aChucker << static_cast < sal_Int16> (0); aChucker << static_cast < sal_Int16> (0); aChucker << static_cast < sal_Int32> (0); - aChucker << rEntry.nOffset; + aChucker << getTruncated( rEntry.nOffset, &bWrite64Header ); + + if( bWrite64Header ) + { + // FIXME64: need to append a ZIP64 header instead of throwing + // We're about to silently loose people's data - which they are + // unlikely to appreciate so fail instead: + throw IOException( "File contains streams that are too large.", + uno::Reference< XInterface >() ); + } Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() ); aChucker.WriteBytes( aSequence ); @@ -343,10 +368,21 @@ void ZipOutputStream::writeCEN( const ZipEntry &rEntry ) void ZipOutputStream::writeEXT( const ZipEntry &rEntry ) throw(IOException, RuntimeException) { + bool bWrite64Header = false; + aChucker << EXTSIG; aChucker << static_cast < sal_uInt32> ( rEntry.nCrc ); - aChucker << rEntry.nCompressedSize; - aChucker << rEntry.nSize; + aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); + aChucker << getTruncated( rEntry.nSize, &bWrite64Header ); + + if( bWrite64Header ) + { + // FIXME64: need to append a ZIP64 header instead of throwing + // We're about to silently loose people's data - which they are + // unlikely to appreciate so fail instead: + throw IOException( "File contains streams that are too large.", + uno::Reference< XInterface >() ); + } } sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry ) @@ -375,6 +411,8 @@ sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry ) aChucker << rEntry.nMethod; } + bool bWrite64Header = false; + aChucker << static_cast < sal_uInt32 > (rEntry.nTime); if ((rEntry.nFlag & 8) == 8 ) { @@ -385,12 +423,21 @@ sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry ) else { aChucker << static_cast < sal_uInt32 > (rEntry.nCrc); - aChucker << rEntry.nCompressedSize; - aChucker << rEntry.nSize; + aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header ); + aChucker << getTruncated( rEntry.nSize, &bWrite64Header ); } aChucker << nNameLength; aChucker << static_cast < sal_Int16 > (0); + if( bWrite64Header ) + { + // FIXME64: need to append a ZIP64 header instead of throwing + // We're about to silently loose people's data - which they are + // unlikely to appreciate so fail instead: + throw IOException( "File contains streams that are too large.", + uno::Reference< XInterface >() ); + } + Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() ); aChucker.WriteBytes( aSequence ); diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 5e2b2cf2bc47..b3e1730e4462 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -289,7 +289,9 @@ void ZipPackage::parseManifest() if ( pSalt && pVector && pCount && pSize && pDigest && pDigestAlg && pEncryptionAlg ) { uno::Sequence < sal_Int8 > aSequence; - sal_Int32 nCount = 0, nSize = 0, nDigestAlg = 0, nEncryptionAlg = 0, nDerivedKeySize = 16, nStartKeyAlg = xml::crypto::DigestID::SHA1; + sal_Int64 nSize = 0; + sal_Int32 nCount = 0, nDigestAlg = 0, nEncryptionAlg = 0; + sal_Int32 nDerivedKeySize = 16, nStartKeyAlg = xml::crypto::DigestID::SHA1; pStream->SetToBeEncrypted ( sal_True ); @@ -984,7 +986,7 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut ) sal_Int32 nBufferLength = m_pRootFolder->GetMediaType().getLength(); OString sMediaType = OUStringToOString( m_pRootFolder->GetMediaType(), RTL_TEXTENCODING_ASCII_US ); uno::Sequence< sal_Int8 > aType( ( sal_Int8* )sMediaType.getStr(), - nBufferLength ); + nBufferLength ); pEntry->sPath = sMime; @@ -1025,7 +1027,8 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq pEntry->sPath = "META-INF/manifest.xml"; pEntry->nMethod = DEFLATED; - pEntry->nCrc = pEntry->nSize = pEntry->nCompressedSize = -1; + pEntry->nCrc = -1; + pEntry->nSize = pEntry->nCompressedSize = -1; pEntry->nTime = ZipOutputStream::getCurrentDosTime(); // Convert vector into a uno::Sequence @@ -1070,7 +1073,8 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno: pEntry->sPath = "[Content_Types].xml"; pEntry->nMethod = DEFLATED; - pEntry->nCrc = pEntry->nSize = pEntry->nCompressedSize = -1; + pEntry->nCrc = -1; + pEntry->nSize = pEntry->nCompressedSize = -1; pEntry->nTime = ZipOutputStream::getCurrentDosTime(); // Convert vector into a uno::Sequence diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx index c3dd800d40a2..31421585add4 100644 --- a/package/source/zippackage/ZipPackageFolder.cxx +++ b/package/source/zippackage/ZipPackageFolder.cxx @@ -68,7 +68,7 @@ ZipPackageFolder::ZipPackageFolder ( const uno::Reference< XMultiServiceFactory aEntry.nMethod = STORED; aEntry.nTime = -1; aEntry.nCrc = 0; - aEntry.nCompressedSize = 0; + aEntry.nCompressedSize = 0; aEntry.nSize = 0; aEntry.nOffset = -1; uno::Sequence < sal_Int8 > &rCachedImplId = lcl_CachedImplId::get(); @@ -368,7 +368,7 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo sal_Bool bTransportOwnEncrStreamAsRaw = sal_False; // During the storing the original size of the stream can be changed // TODO/LATER: get rid of this hack - sal_Int32 nOwnStreamOrigSize = bRawStream ? rInfo.pStream->GetMagicalHackSize() : rInfo.pStream->getSize(); + sal_Int64 nOwnStreamOrigSize = bRawStream ? rInfo.pStream->GetMagicalHackSize() : rInfo.pStream->getSize(); sal_Bool bUseNonSeekableAccess = sal_False; uno::Reference < XInputStream > xStream; @@ -414,7 +414,7 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo else if ( bToBeEncrypted ) { // this is the correct original size - pTempEntry->nSize = static_cast < sal_Int32 > ( xSeek->getLength() ); + pTempEntry->nSize = xSeek->getLength(); nOwnStreamOrigSize = pTempEntry->nSize; } @@ -584,7 +584,8 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo if ( bToBeCompressed ) { pTempEntry->nMethod = DEFLATED; - pTempEntry->nCrc = pTempEntry->nCompressedSize = pTempEntry->nSize = -1; + pTempEntry->nCrc = -1; + pTempEntry->nCompressedSize = pTempEntry->nSize = -1; } try diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx index fa8b17dbdb73..550486f9ad90 100644 --- a/package/source/zippackage/ZipPackageStream.cxx +++ b/package/source/zippackage/ZipPackageStream.cxx @@ -897,7 +897,7 @@ Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName ) } //-------------------------------------------------------------------------- -void ZipPackageStream::setSize ( const sal_Int32 nNewSize ) +void ZipPackageStream::setSize ( const sal_Int64 nNewSize ) { if ( aEntry.nCompressedSize != nNewSize ) aEntry.nMethod = DEFLATED; |