summaryrefslogtreecommitdiff
path: root/package/source/zipapi/ZipFile.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'package/source/zipapi/ZipFile.cxx')
-rw-r--r--package/source/zipapi/ZipFile.cxx122
1 files changed, 75 insertions, 47 deletions
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