20#include <com/sun/star/packages/zip/ZipConstants.hpp>
21#include <com/sun/star/packages/zip/ZipIOException.hpp>
22#include <com/sun/star/xml/crypto/CipherID.hpp>
32#include <osl/diagnose.h>
33#include <osl/mutex.hxx>
38using namespace com::sun::star::packages::zip::ZipConstants;
41using com::sun::star::packages::zip::ZipIOException;
44 const uno::Reference< uno::XComponentContext >& xContext,
48 const ::rtl::Reference< EncryptionData >& rData,
51 const OUString& aMediaType,
53: maMutexHolder(
std::move( aMutexHolder ))
54, mxZipStream ( xNewZipStream )
55, mxZipSeek ( xNewZipStream, UNO_QUERY )
66, mbCheckCRC(!bRecoveryMode)
68 mnZipCurrent = maEntry.nOffset;
72 mnZipSize = maEntry.nMethod == DEFLATED ? maEntry.nCompressedSize : maEntry.nSize;
77 mnZipSize = maEntry.nSize;
78 nSize = maEntry.nMethod == DEFLATED ? maEntry.nCompressedSize : maEntry.nSize;
82 throw ZipIOException(
"The stream seems to be broken!");
85 throw ZipIOException(
"Integer-overflow");
87 bool bHaveEncryptData = rData.is() && rData->m_aInitVector.hasElements() &&
88 ((rData->m_aSalt.hasElements() && rData->m_nIterationCount != 0)
90 rData->m_aKey.hasElements());
91 bool bMustDecrypt = nStreamMode ==
UNBUFF_STREAM_DATA && bHaveEncryptData && bIsEncrypted;
95 m_xCipherContext = ZipFile::StaticGetCipher( xContext, rData,
false );
96 mnBlockSize = ( rData->m_nEncAlg == xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 1 );
99 if ( !(bHaveEncryptData && mbWrappedRaw && bIsEncrypted) )
108 rData->m_aInitVector.getLength() +
109 rData->m_aSalt.getLength() +
110 rData->m_aDigest.getLength() +
112 sal_Int8 * pHeader = maHeader.getArray();
113 ZipFile::StaticFillHeader( rData, rEntry.
nSize, aMediaType, pHeader );
114 mnHeaderToRead =
static_cast < sal_Int16
> ( maHeader.getLength() );
115 mnZipSize += mnHeaderToRead;
122 const ::rtl::Reference< EncryptionData >& rData )
123: maMutexHolder(
std::move( aMutexHolder ))
124, mxZipStream ( xRawStream )
125, mxZipSeek ( xRawStream, UNO_QUERY )
128, mbRawStream ( false )
129, mbWrappedRaw ( false )
130, mnHeaderToRead ( 0 )
138 OSL_ENSURE( mxZipSeek.is(),
"The stream must be seekable!" );
142 rData->m_aSalt.getLength() + rData->m_aDigest.getLength();
145 if ( mxZipSeek.is() )
146 mnZipSize = mxZipSeek->getLength();
147 }
catch(
const Exception& )
153 mnZipEnd = mnZipCurrent + mnZipSize;
167 sal_Int32 nRequestedBytes = nBytesToRead;
172 sal_Int32 nTotal = 0;
173 aData.realloc ( nRequestedBytes );
174 if ( nRequestedBytes )
177 sal_Int32 nLastRead = 0;
184 sal_Int16 nHeadRead =
static_cast< sal_Int16
>(( nRequestedBytes >
mnHeaderToRead ?
189 if ( nHeadRead < nRequestedBytes )
191 sal_Int32 nToRead = nRequestedBytes - nHeadRead;
192 nToRead = ( nDiff < nToRead ) ? sal::static_int_cast< sal_Int32 >( nDiff ) : nToRead;
196 nRead =
mxZipStream->readBytes ( aPureData, nToRead );
199 aPureData.realloc( nRead );
203 aData.realloc( nHeadRead + nRead );
205 const sal_Int8* pPureBuffer = aPureData.getConstArray();
207 for ( sal_Int32 nInd = 0; nInd < nRead; nInd++ )
208 pBuffer[ nHeadRead + nInd ] = pPureBuffer[ nInd ];
219 std::min<sal_Int64>(nDiff, nRequestedBytes) );
223 aData.realloc( nRead );
236 if ( nRead > nRequestedBytes )
238 "Should not be possible to read more than requested!" );
241 throw ZipIOException(
"The stream seems to be broken!" );
244 throw ZipIOException(
"Dictionaries are not supported!" );
249 throw ZipIOException(
"The stream seems to be broken!" );
254 sal_Int32 nToRead = std::max( nRequestedBytes,
static_cast< sal_Int32
>( 8192 ) );
257 nToRead = std::min( nDiff, nToRead );
260 if ( nZipRead < nToRead )
261 throw ZipIOException(
"No expected data!" );
274 uno::Sequence< sal_Int8 > aSuffix =
m_xCipherContext->finalizeCipherContextAndDispose();
275 if ( aSuffix.hasElements() )
279 memcpy(
maCompBuffer.getArray() + nOldLen, aSuffix.getConstArray(), aSuffix.getLength() );
289 nTotal = nRead + nLastRead;
290 if ( nTotal < nRequestedBytes)
291 aData.realloc ( nTotal );
299 throw ZipIOException(
"The stream seems to be broken!" );
#define UNBUFF_STREAM_RAW
#define UNBUFF_STREAM_DATA
#define UNBUFF_STREAM_WRAPPEDRAW
sal_Int32 getValue() const
void update(const css::uno::Sequence< sal_Int8 > &b)
Update CRC32 with specified sequence of bytes.
css::uno::Reference< css::io::XInputStream > mxZipStream
virtual void SAL_CALL closeInput() override
virtual ~XUnbufferedStream() override
virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override
rtl::Reference< comphelper::RefCountedMutex > maMutexHolder
virtual sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nMaxBytesToRead) override
virtual sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nBytesToRead) override
css::uno::Sequence< sal_Int8 > maHeader
css::uno::Sequence< sal_Int8 > maCompBuffer
ZipUtils::Inflater maInflater
css::uno::Reference< css::xml::crypto::XCipherContext > m_xCipherContext
css::uno::Reference< css::io::XSeekable > mxZipSeek
XUnbufferedStream(const css::uno::Reference< css::uno::XComponentContext > &xContext, rtl::Reference< comphelper::RefCountedMutex > aMutexHolder, ZipEntry const &rEntry, css::uno::Reference< css::io::XInputStream > const &xNewZipStream, const ::rtl::Reference< EncryptionData > &rData, sal_Int8 nStreamMode, bool bIsEncrypted, const OUString &aMediaType, bool bRecoveryMode)
virtual sal_Int32 SAL_CALL available() override
sal_Int32 doInflateSegment(css::uno::Sequence< sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
sal_Int32 getLastInflateError() const
bool needsDictionary() const
void setInput(const css::uno::Sequence< sal_Int8 > &rBuffer)
#define TOOLS_WARN_EXCEPTION(area, stream)
constexpr OUStringLiteral aData
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)