diff options
Diffstat (limited to 'package/source')
-rw-r--r-- | package/source/xstor/ocompinstream.cxx | 17 | ||||
-rw-r--r-- | package/source/xstor/ocompinstream.hxx | 7 | ||||
-rw-r--r-- | package/source/xstor/selfterminatefilestream.cxx | 5 | ||||
-rw-r--r-- | package/source/xstor/selfterminatefilestream.hxx | 6 | ||||
-rw-r--r-- | package/source/xstor/switchpersistencestream.cxx | 16 | ||||
-rw-r--r-- | package/source/xstor/switchpersistencestream.hxx | 6 | ||||
-rw-r--r-- | package/source/zipapi/ByteGrabber.cxx | 49 | ||||
-rw-r--r-- | package/source/zipapi/CRC32.cxx | 4 | ||||
-rw-r--r-- | package/source/zipapi/Inflater.cxx | 108 | ||||
-rw-r--r-- | package/source/zipapi/MemoryByteGrabber.hxx | 6 | ||||
-rw-r--r-- | package/source/zipapi/XBufferedThreadedStream.cxx | 26 | ||||
-rw-r--r-- | package/source/zipapi/XBufferedThreadedStream.hxx | 7 | ||||
-rw-r--r-- | package/source/zipapi/ZipFile.cxx | 145 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackage.cxx | 1 | ||||
-rw-r--r-- | package/source/zippackage/wrapstreamforshare.cxx | 16 | ||||
-rw-r--r-- | package/source/zippackage/wrapstreamforshare.hxx | 7 |
16 files changed, 342 insertions, 84 deletions
diff --git a/package/source/xstor/ocompinstream.cxx b/package/source/xstor/ocompinstream.cxx index 8a23169f6814..b71b8ef99697 100644 --- a/package/source/xstor/ocompinstream.cxx +++ b/package/source/xstor/ocompinstream.cxx @@ -38,6 +38,7 @@ OInputCompStream::OInputCompStream( OWriteStream_Impl& aImpl, : m_pImpl( &aImpl ) , m_xMutex( m_pImpl->m_xMutex ) , m_xStream(std::move( xStream )) +, m_pByteReader( dynamic_cast<comphelper::ByteReader*>(m_xStream.get()) ) , m_aProperties( aProps ) , m_bDisposed( false ) , m_nStorageType( nStorageType ) @@ -47,6 +48,7 @@ OInputCompStream::OInputCompStream( OWriteStream_Impl& aImpl, throw uno::RuntimeException(); // just a disaster assert(m_xStream.is()); + assert(m_pByteReader); } OInputCompStream::OInputCompStream( uno::Reference < io::XInputStream > xStream, @@ -55,11 +57,13 @@ OInputCompStream::OInputCompStream( uno::Reference < io::XInputStream > xStream, : m_pImpl( nullptr ) , m_xMutex( new comphelper::RefCountedMutex ) , m_xStream(std::move( xStream )) +, m_pByteReader( dynamic_cast<comphelper::ByteReader*>(m_xStream.get()) ) , m_aProperties( aProps ) , m_bDisposed( false ) , m_nStorageType( nStorageType ) { assert(m_xStream.is()); + assert(m_pByteReader); } OInputCompStream::~OInputCompStream() @@ -125,6 +129,19 @@ sal_Int32 SAL_CALL OInputCompStream::readSomeBytes( uno::Sequence< sal_Int8 >& a } +sal_Int32 OInputCompStream::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead ) +{ + ::osl::MutexGuard aGuard( m_xMutex->GetMutex() ); + if ( m_bDisposed ) + { + SAL_INFO("package.xstor", "Disposed!"); + throw lang::DisposedException(); + } + + return m_pByteReader->readSomeBytes( aData, nMaxBytesToRead ); + +} + void SAL_CALL OInputCompStream::skipBytes( sal_Int32 nBytesToSkip ) { ::osl::MutexGuard aGuard( m_xMutex->GetMutex() ); diff --git a/package/source/xstor/ocompinstream.hxx b/package/source/xstor/ocompinstream.hxx index effbc4be2fb8..54fc7dc19308 100644 --- a/package/source/xstor/ocompinstream.hxx +++ b/package/source/xstor/ocompinstream.hxx @@ -28,6 +28,7 @@ #include <cppuhelper/implbase.hxx> #include <comphelper/interfacecontainer3.hxx> #include <comphelper/refcountedmutex.hxx> +#include <comphelper/bytereader.hxx> #include <rtl/ref.hxx> #include <memory> @@ -37,12 +38,14 @@ struct OWriteStream_Impl; class OInputCompStream : public cppu::WeakImplHelper < css::io::XInputStream ,css::embed::XExtendedStorageStream ,css::embed::XRelationshipAccess - ,css::beans::XPropertySet > + ,css::beans::XPropertySet >, + public comphelper::ByteReader { protected: OWriteStream_Impl* m_pImpl; rtl::Reference<comphelper::RefCountedMutex> m_xMutex; css::uno::Reference < css::io::XInputStream > m_xStream; + comphelper::ByteReader* m_pByteReader; std::unique_ptr<::comphelper::OInterfaceContainerHelper3<css::lang::XEventListener>> m_pInterfaceContainer; css::uno::Sequence < css::beans::PropertyValue > m_aProperties; bool m_bDisposed; @@ -102,6 +105,8 @@ public: virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + // comphelper::ByteReader + virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override; }; #endif diff --git a/package/source/xstor/selfterminatefilestream.cxx b/package/source/xstor/selfterminatefilestream.cxx index f3fe79439781..80d21dd3bee5 100644 --- a/package/source/xstor/selfterminatefilestream.cxx +++ b/package/source/xstor/selfterminatefilestream.cxx @@ -62,6 +62,11 @@ sal_Int32 SAL_CALL OSelfTerminateFileStream::readSomeBytes( uno::Sequence< sal_I return m_xStreamWrapper->readSomeBytes( aData, nMaxBytesToRead ); } +sal_Int32 OSelfTerminateFileStream::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead ) +{ + return m_xStreamWrapper->readSomeBytes( aData, nMaxBytesToRead ); +} + void SAL_CALL OSelfTerminateFileStream::skipBytes( sal_Int32 nBytesToSkip ) { return m_xStreamWrapper->skipBytes( nBytesToSkip ); diff --git a/package/source/xstor/selfterminatefilestream.hxx b/package/source/xstor/selfterminatefilestream.hxx index f8cedcb64c46..4520552956c5 100644 --- a/package/source/xstor/selfterminatefilestream.hxx +++ b/package/source/xstor/selfterminatefilestream.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/io/XSeekable.hpp> #include <com/sun/star/ucb/XSimpleFileAccess3.hpp> #include <com/sun/star/uno/XComponentContext.hpp> +#include <comphelper/bytereader.hxx> #include <cppuhelper/implbase.hxx> #include <unotools/streamwrap.hxx> #include <unotools/tempfile.hxx> @@ -33,7 +34,8 @@ struct OWriteStream_Impl; class OSelfTerminateFileStream final : public cppu::WeakImplHelper< css::io::XInputStream, - css::io::XSeekable > + css::io::XSeekable >, + public comphelper::ByteReader { std::optional<utl::TempFileFast> m_oTempFile; rtl::Reference< utl::OSeekableInputStreamWrapper > m_xStreamWrapper; @@ -57,6 +59,8 @@ public: virtual sal_Int64 SAL_CALL getPosition() override; virtual sal_Int64 SAL_CALL getLength() override; + // comphelper::ByteReader + virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override; }; #endif diff --git a/package/source/xstor/switchpersistencestream.cxx b/package/source/xstor/switchpersistencestream.cxx index ef07966f09d0..6613b8b046b1 100644 --- a/package/source/xstor/switchpersistencestream.cxx +++ b/package/source/xstor/switchpersistencestream.cxx @@ -39,6 +39,7 @@ struct SPStreamData_Impl uno::Reference< io::XSeekable > m_xOrigSeekable; uno::Reference< io::XInputStream > m_xOrigInStream; uno::Reference< io::XOutputStream > m_xOrigOutStream; + comphelper::ByteReader* m_pByteReader; bool m_bInOpen; bool m_bOutOpen; @@ -56,6 +57,7 @@ struct SPStreamData_Impl , m_xOrigSeekable(std::move( xOrigSeekable )) , m_xOrigInStream(std::move( xOrigInStream )) , m_xOrigOutStream(std::move( xOrigOutStream )) + , m_pByteReader(dynamic_cast<comphelper::ByteReader*>(m_xOrigInStream.get())) , m_bInOpen( bInOpen ) , m_bOutOpen( bOutOpen ) { @@ -243,6 +245,20 @@ uno::Reference< io::XOutputStream > SAL_CALL SwitchablePersistenceStream::getOut return m_pStreamData->m_xOrigInStream->readBytes( aData, nMaxBytesToRead ); } +::sal_Int32 SwitchablePersistenceStream::readSomeBytes( sal_Int8* aData, sal_Int32 nBytesToRead) +{ + std::scoped_lock aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_pByteReader->readSomeBytes( aData, nBytesToRead ); +} + void SAL_CALL SwitchablePersistenceStream::skipBytes( ::sal_Int32 nBytesToSkip ) { std::scoped_lock aGuard( m_aMutex ); diff --git a/package/source/xstor/switchpersistencestream.hxx b/package/source/xstor/switchpersistencestream.hxx index 64d4e37fd025..657ed3e98949 100644 --- a/package/source/xstor/switchpersistencestream.hxx +++ b/package/source/xstor/switchpersistencestream.hxx @@ -29,6 +29,7 @@ #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XAsyncOutputMonitor.hpp> #include <mutex> +#include <comphelper/bytereader.hxx> #include <cppuhelper/implbase.hxx> // SwitchablePersistenceStream @@ -45,7 +46,8 @@ class SwitchablePersistenceStream css::io::XOutputStream, css::io::XTruncate, css::io::XSeekable, - css::io::XAsyncOutputMonitor > + css::io::XAsyncOutputMonitor >, + public comphelper::ByteReader { std::mutex m_aMutex; @@ -96,6 +98,8 @@ public: // css::io::XAsyncOutputMonitor virtual void SAL_CALL waitForCompletion( ) override; + // comphelper::ByteReader + virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override; }; #endif // INCLUDED_PACKAGE_SOURCE_XSTOR_SWITCHPERSISTENCESTREAM_HXX diff --git a/package/source/zipapi/ByteGrabber.cxx b/package/source/zipapi/ByteGrabber.cxx index 50083b4dafc2..cd9e201dba0b 100644 --- a/package/source/zipapi/ByteGrabber.cxx +++ b/package/source/zipapi/ByteGrabber.cxx @@ -39,9 +39,9 @@ using namespace ::com::sun::star; ByteGrabber::ByteGrabber(uno::Reference < io::XInputStream > const & xIstream) : xStream(xIstream) , xSeek (xIstream, uno::UNO_QUERY ) -, aSequence ( 4 ) { - pSequence = aSequence.getArray(); + mpByteReader = dynamic_cast<comphelper::ByteReader*>(xStream.get()); + assert(mpByteReader); } ByteGrabber::~ByteGrabber() @@ -52,6 +52,8 @@ void ByteGrabber::setInputStream (const uno::Reference < io::XInputStream >& xNe { xStream = xNewStream; xSeek.set(xNewStream, uno::UNO_QUERY); + mpByteReader = dynamic_cast<comphelper::ByteReader*>(xStream.get()); + assert(mpByteReader); } // XInputStream chained @@ -61,6 +63,12 @@ sal_Int32 ByteGrabber::readBytes( uno::Sequence< sal_Int8 >& aData, return xStream->readBytes(aData, nBytesToRead ); } +sal_Int32 ByteGrabber::readBytes( sal_Int8* aData, + sal_Int32 nBytesToRead ) +{ + return mpByteReader->readSomeBytes(aData, nBytesToRead ); +} + // XSeekable chained... void ByteGrabber::seek( sal_Int64 location ) { @@ -88,42 +96,39 @@ sal_Int64 ByteGrabber::getLength( ) sal_uInt16 ByteGrabber::ReadUInt16() { - if (xStream->readBytes(aSequence, 2) != 2) + if (mpByteReader->readSomeBytes(maBuffer.data(), 2) != 2) return 0; - pSequence = aSequence.getConstArray(); return static_cast <sal_uInt16> - ( (pSequence[0] & 0xFF) - | (pSequence[1] & 0xFF) << 8); + ( (maBuffer[0] & 0xFF) + | (maBuffer[1] & 0xFF) << 8); } sal_uInt32 ByteGrabber::ReadUInt32() { - if (xStream->readBytes(aSequence, 4) != 4) + if (mpByteReader->readSomeBytes(maBuffer.data(), 4) != 4) return 0; - pSequence = aSequence.getConstArray(); return static_cast < sal_uInt32 > - ( (pSequence[0] & 0xFF) - | ( pSequence[1] & 0xFF ) << 8 - | ( pSequence[2] & 0xFF ) << 16 - | ( pSequence[3] & 0xFF ) << 24 ); + ( (maBuffer[0] & 0xFF) + | ( maBuffer[1] & 0xFF ) << 8 + | ( maBuffer[2] & 0xFF ) << 16 + | ( maBuffer[3] & 0xFF ) << 24 ); } sal_uInt64 ByteGrabber::ReadUInt64() { - if (xStream->readBytes(aSequence, 8) != 8) + if (mpByteReader->readSomeBytes(maBuffer.data(), 8) != 8) return 0; - pSequence = aSequence.getConstArray(); - return static_cast<sal_uInt64>(pSequence[0] & 0xFF) - | static_cast<sal_uInt64>(pSequence[1] & 0xFF) << 8 - | static_cast<sal_uInt64>(pSequence[2] & 0xFF) << 16 - | static_cast<sal_uInt64>(pSequence[3] & 0xFF) << 24 - | static_cast<sal_uInt64>(pSequence[4] & 0xFF) << 32 - | static_cast<sal_uInt64>(pSequence[5] & 0xFF) << 40 - | static_cast<sal_uInt64>(pSequence[6] & 0xFF) << 48 - | static_cast<sal_uInt64>(pSequence[7] & 0xFF) << 56; + return static_cast<sal_uInt64>(maBuffer[0] & 0xFF) + | static_cast<sal_uInt64>(maBuffer[1] & 0xFF) << 8 + | static_cast<sal_uInt64>(maBuffer[2] & 0xFF) << 16 + | static_cast<sal_uInt64>(maBuffer[3] & 0xFF) << 24 + | static_cast<sal_uInt64>(maBuffer[4] & 0xFF) << 32 + | static_cast<sal_uInt64>(maBuffer[5] & 0xFF) << 40 + | static_cast<sal_uInt64>(maBuffer[6] & 0xFF) << 48 + | static_cast<sal_uInt64>(maBuffer[7] & 0xFF) << 56; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/package/source/zipapi/CRC32.cxx b/package/source/zipapi/CRC32.cxx index bd06822486b3..b6415efbf2f8 100644 --- a/package/source/zipapi/CRC32.cxx +++ b/package/source/zipapi/CRC32.cxx @@ -46,6 +46,10 @@ void CRC32::updateSegment(const Sequence< sal_Int8 > &b, sal_Int32 len) { nCRC = rtl_crc32(nCRC, b.getConstArray(), len ); } +void CRC32::updateSegment(const sal_Int8* b, sal_Int32 len) +{ + nCRC = rtl_crc32(nCRC, b, len ); +} /** Update CRC32 with specified sequence of bytes */ void CRC32::update(const Sequence< sal_Int8 > &b) diff --git a/package/source/zipapi/Inflater.cxx b/package/source/zipapi/Inflater.cxx index d03fed8c0968..7867259aa764 100644 --- a/package/source/zipapi/Inflater.cxx +++ b/package/source/zipapi/Inflater.cxx @@ -134,4 +134,112 @@ sal_Int32 Inflater::doInflateBytes (Sequence < sal_Int8 > &rBuffer, sal_Int32 n return 0; } +InflaterBytes::InflaterBytes(bool bNoWrap) +: bFinished(false), + bNeedDict(false), + nOffset(0), + nLength(0), + nLastInflateError(0) +{ + pStream.reset(new z_stream); + /* memset to 0 to set zalloc/opaque etc */ + memset (pStream.get(), 0, sizeof(*pStream)); + sal_Int32 nRes; + nRes = inflateInit2(pStream.get(), bNoWrap ? -MAX_WBITS : MAX_WBITS); + switch (nRes) + { + case Z_OK: + break; + case Z_MEM_ERROR: + pStream.reset(); + break; + case Z_STREAM_ERROR: + pStream.reset(); + break; + default: + break; + } +} + +InflaterBytes::~InflaterBytes() +{ + end(); +} + +void InflaterBytes::setInput( const sal_Int8* rBuffer, sal_Int32 nBufLen ) +{ + sInBuffer = rBuffer; + nOffset = 0; + nLength = nBufLen; +} + + +sal_Int32 InflaterBytes::doInflateSegment( sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength ) +{ + if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > nBufLen) + { + // do error handling + } + return doInflateBytes(pOutBuffer, nNewOffset, nNewLength); +} + +void InflaterBytes::end( ) +{ + if (pStream) + { +#if !defined Z_PREFIX + inflateEnd(pStream.get()); +#else + z_inflateEnd(pStream.get()); +#endif + pStream.reset(); + } +} + +sal_Int32 InflaterBytes::doInflateBytes (sal_Int8* pOutBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength) +{ + if ( !pStream ) + { + nLastInflateError = Z_STREAM_ERROR; + return 0; + } + + nLastInflateError = 0; + + pStream->next_in = reinterpret_cast<const unsigned char*>( sInBuffer + nOffset ); + pStream->avail_in = nLength; + pStream->next_out = reinterpret_cast < unsigned char* > ( pOutBuffer + nNewOffset ); + pStream->avail_out = nNewLength; + +#if !defined Z_PREFIX + sal_Int32 nResult = ::inflate(pStream.get(), Z_PARTIAL_FLUSH); +#else + sal_Int32 nResult = ::z_inflate(pStream.get(), Z_PARTIAL_FLUSH); +#endif + + switch (nResult) + { + case Z_STREAM_END: + bFinished = true; + [[fallthrough]]; + case Z_OK: + nOffset += nLength - pStream->avail_in; + nLength = pStream->avail_in; + return nNewLength - pStream->avail_out; + + case Z_NEED_DICT: + bNeedDict = true; + nOffset += nLength - pStream->avail_in; + nLength = pStream->avail_in; + return 0; + + default: + // it is no error, if there is no input or no output + if ( nLength && nNewLength ) + nLastInflateError = nResult; + } + + return 0; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/package/source/zipapi/MemoryByteGrabber.hxx b/package/source/zipapi/MemoryByteGrabber.hxx index dd876d66ebfa..f9076067cd91 100644 --- a/package/source/zipapi/MemoryByteGrabber.hxx +++ b/package/source/zipapi/MemoryByteGrabber.hxx @@ -32,6 +32,12 @@ public: , mnEnd ( rBuffer.getLength() ) { } + MemoryByteGrabber ( const sal_Int8* pBuffer, sal_Int32 nBufLen ) + : mpBuffer ( pBuffer ) + , mnCurrent ( 0 ) + , mnEnd ( nBufLen ) + { + } MemoryByteGrabber(css::uno::Sequence<sal_Int8> &&) = delete; const sal_Int8 * getCurrentPos () const { return mpBuffer + mnCurrent; } diff --git a/package/source/zipapi/XBufferedThreadedStream.cxx b/package/source/zipapi/XBufferedThreadedStream.cxx index d3bf995d9073..ea7c270ebea6 100644 --- a/package/source/zipapi/XBufferedThreadedStream.cxx +++ b/package/source/zipapi/XBufferedThreadedStream.cxx @@ -158,6 +158,32 @@ sal_Int32 SAL_CALL XBufferedThreadedStream::readBytes( Sequence< sal_Int8 >& rDa return nAvailableSize; } +sal_Int32 XBufferedThreadedStream::readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) +{ + if( !hasBytes() ) + return 0; + + const sal_Int32 nAvailableSize = static_cast< sal_Int32 > ( std::min< sal_Int64 >( nBytesToRead, remainingSize() ) ); + sal_Int32 i = 0, nPendingBytes = nAvailableSize; + + while( nPendingBytes ) + { + const Buffer &pBuffer = getNextBlock(); + if( !pBuffer.hasElements() ) + return nAvailableSize - nPendingBytes; + const sal_Int32 limit = std::min<sal_Int32>( nPendingBytes, pBuffer.getLength() - mnOffset ); + + memcpy( &pData[i], &pBuffer[mnOffset], limit ); + + nPendingBytes -= limit; + mnOffset += limit; + mnPos += limit; + i += limit; + } + + return nAvailableSize; +} + sal_Int32 SAL_CALL XBufferedThreadedStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) { return readBytes( aData, nMaxBytesToRead ); diff --git a/package/source/zipapi/XBufferedThreadedStream.hxx b/package/source/zipapi/XBufferedThreadedStream.hxx index beb1cd33c700..c3243f4f1326 100644 --- a/package/source/zipapi/XBufferedThreadedStream.hxx +++ b/package/source/zipapi/XBufferedThreadedStream.hxx @@ -12,6 +12,7 @@ #include <com/sun/star/io/XInputStream.hpp> +#include <comphelper/bytereader.hxx> #include <cppuhelper/implbase.hxx> #include <rtl/ref.hxx> #include <salhelper/thread.hxx> @@ -23,7 +24,8 @@ typedef css::uno::Sequence< sal_Int8 > Buffer; -class XBufferedThreadedStream : public cppu::WeakImplHelper< css::io::XInputStream > +class XBufferedThreadedStream : public cppu::WeakImplHelper< css::io::XInputStream >, + public comphelper::ByteReader { private: const css::uno::Reference<XInputStream> mxSrcStream; @@ -78,6 +80,9 @@ public: virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override; virtual sal_Int32 SAL_CALL available( ) override; virtual void SAL_CALL closeInput( ) override; + + // comphelper::ByteReader + virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override; }; #endif diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx index 2d8d69c853c7..37907647711b 100644 --- a/package/source/zipapi/ZipFile.cxx +++ b/package/source/zipapi/ZipFile.cxx @@ -590,7 +590,8 @@ uno::Reference<io::XInputStream> ZipFile::checkValidPassword( namespace { -class XBufferedStream : public cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable> +class XBufferedStream : public cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable>, + public comphelper::ByteReader { std::vector<sal_Int8> maBytes; size_t mnPos; @@ -655,6 +656,22 @@ public: return nReadSize; } + virtual sal_Int32 readSomeBytes(sal_Int8* pData, sal_Int32 nBytesToRead) override + { + if (!hasBytes()) + return 0; + + sal_Int32 nReadSize = std::min<sal_Int32>(nBytesToRead, remainingSize()); + std::vector<sal_Int8>::const_iterator it = maBytes.cbegin(); + std::advance(it, mnPos); + for (sal_Int32 i = 0; i < nReadSize; ++i, ++it) + pData[i] = *it; + + mnPos += nReadSize; + + return nReadSize; + } + virtual sal_Int32 SAL_CALL readSomeBytes( ::css::uno::Sequence<sal_Int8>& rData, sal_Int32 nMaxBytesToRead ) override { return readBytes(rData, nMaxBytesToRead); @@ -918,7 +935,12 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry) sal_Int64 nPos = -rEntry.nOffset; aGrabber.seek(nPos); - sal_Int32 nTestSig = aGrabber.ReadInt32(); + std::array<sal_Int8, 30> aHeader; + if (aGrabber.readBytes(aHeader.data(), 30) != 30) + throw new uno::RuntimeException(); + MemoryByteGrabber headerMemGrabber(aHeader.data(), 30); + + sal_Int32 nTestSig = headerMemGrabber.ReadInt32(); if (nTestSig != LOCSIG) throw ZipIOException(u"Invalid LOC header (bad signature)"_ustr ); @@ -927,18 +949,18 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry) // Just verify the path and calculate the data offset and otherwise // rely on the central directory info. - aGrabber.ReadInt16(); // version - ignore any mismatch (Maven created JARs) - sal_uInt16 const nLocFlag = aGrabber.ReadUInt16(); // general purpose bit flag - sal_uInt16 const nLocMethod = aGrabber.ReadUInt16(); // compression method + headerMemGrabber.ReadInt16(); // version - ignore any mismatch (Maven created JARs) + sal_uInt16 const nLocFlag = headerMemGrabber.ReadUInt16(); // general purpose bit flag + sal_uInt16 const nLocMethod = headerMemGrabber.ReadUInt16(); // compression method // Do *not* compare timestamps, since MSO 2010 can produce documents // with timestamp difference in the central directory entry and local // file header. - aGrabber.ReadInt32(); //time - sal_uInt32 nLocCrc = aGrabber.ReadUInt32(); //crc - sal_uInt64 nLocCompressedSize = aGrabber.ReadUInt32(); //compressed size - sal_uInt64 nLocSize = aGrabber.ReadUInt32(); //size - sal_Int16 nPathLen = aGrabber.ReadInt16(); - sal_Int16 nExtraLen = aGrabber.ReadInt16(); + headerMemGrabber.ReadInt32(); //time + sal_uInt32 nLocCrc = headerMemGrabber.ReadUInt32(); //crc + sal_uInt64 nLocCompressedSize = headerMemGrabber.ReadUInt32(); //compressed size + sal_uInt64 nLocSize = headerMemGrabber.ReadUInt32(); //size + sal_Int16 nPathLen = headerMemGrabber.ReadInt16(); + sal_Int16 nExtraLen = headerMemGrabber.ReadInt16(); if (nPathLen < 0) { @@ -955,13 +977,13 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry) { // read always in UTF8, some tools seem not to set UTF8 bit // coverity[tainted_data] - we've checked negative lens, and up to max short is ok here - uno::Sequence<sal_Int8> aNameBuffer(nPathLen); - sal_Int32 nRead = aGrabber.readBytes(aNameBuffer, nPathLen); - if (nRead < aNameBuffer.getLength()) - aNameBuffer.realloc(nRead); + std::vector<sal_Int8> aNameBuffer(nPathLen); + sal_Int32 nRead = aGrabber.readBytes(aNameBuffer.data(), nPathLen); + if (nRead < nPathLen) + aNameBuffer.resize(nRead); - OUString sLOCPath( reinterpret_cast<const char *>(aNameBuffer.getConstArray()), - aNameBuffer.getLength(), + OUString sLOCPath( reinterpret_cast<const char *>(aNameBuffer.data()), + nRead, RTL_TEXTENCODING_UTF8 ); if ( rEntry.nPathLen == -1 ) // the file was created @@ -980,9 +1002,9 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry) ::std::optional<sal_uInt64> oOffset64; if (nExtraLen != 0) { - Sequence<sal_Int8> aExtraBuffer; - aGrabber.readBytes(aExtraBuffer, nExtraLen); - MemoryByteGrabber extraMemGrabber(aExtraBuffer); + std::vector<sal_Int8> aExtraBuffer(nExtraLen); + aGrabber.readBytes(aExtraBuffer.data(), nExtraLen); + MemoryByteGrabber extraMemGrabber(aExtraBuffer.data(), nExtraLen); isZip64 = readExtraFields(extraMemGrabber, nExtraLen, nLocSize, nLocCompressedSize, oOffset64, &sLOCPath); @@ -1116,7 +1138,7 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry) std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory() { // this method is called in constructor only, no need for mutex - Sequence < sal_Int8 > aBuffer; + std::vector < sal_Int8 > aBuffer; try { sal_Int64 const nLength = aGrabber.getLength(); @@ -1130,10 +1152,11 @@ std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory() aGrabber.seek( nEnd ); auto nSize = nLength - nEnd; - if (nSize != aGrabber.readBytes(aBuffer, nSize)) + aBuffer.reserve(nSize); + if (nSize != aGrabber.readBytes(aBuffer.data(), nSize)) throw ZipException(u"Zip END signature not found!"_ustr ); - const sal_Int8 *pBuffer = aBuffer.getConstArray(); + const sal_Int8 *pBuffer = aBuffer.data(); sal_Int64 nEndPos = {}; nPos = nSize - ENDHDR; @@ -1176,9 +1199,10 @@ std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory() if (20 <= nEndPos) { aGrabber.seek(nEndPos - 20); - Sequence<sal_Int8> aZip64EndLocator; - aGrabber.readBytes(aZip64EndLocator, 20); - MemoryByteGrabber loc64Grabber(aZip64EndLocator); + std::array<sal_Int8, 20> aZip64EndLocator; + if (20 != aGrabber.readBytes(aZip64EndLocator.data(), 20)) + throw uno::RuntimeException(); + MemoryByteGrabber loc64Grabber(aZip64EndLocator.data(), 20); if (loc64Grabber.ReadUInt8() == 'P' && loc64Grabber.ReadUInt8() == 'K' && loc64Grabber.ReadUInt8() == 6 @@ -1201,9 +1225,9 @@ std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory() throw ZipException(u"invalid Zip64 end locator (number of disks)"_ustr); } aGrabber.seek(nLoc64End64Offset); - Sequence<sal_Int8> aZip64EndDirectory; - aGrabber.readBytes(aZip64EndDirectory, nEndPos - 20 - nLoc64End64Offset); - MemoryByteGrabber end64Grabber(aZip64EndDirectory); + std::vector<sal_Int8> aZip64EndDirectory(nEndPos - 20 - nLoc64End64Offset); + aGrabber.readBytes(aZip64EndDirectory.data(), nEndPos - 20 - nLoc64End64Offset); + MemoryByteGrabber end64Grabber(aZip64EndDirectory.data(), nEndPos - 20 - nLoc64End64Offset); if (end64Grabber.ReadUInt8() != 'P' || end64Grabber.ReadUInt8() != 'K' || end64Grabber.ReadUInt8() != 6 @@ -1309,12 +1333,12 @@ sal_Int32 ZipFile::readCEN() throw ZipException(u"central directory too big"_ustr); aGrabber.seek(nCenPos); - Sequence<sal_Int8> aCENBuffer(nCenLen); - sal_Int64 nRead = aGrabber.readBytes ( aCENBuffer, nCenLen ); + std::vector<sal_Int8> aCENBuffer(nCenLen); + sal_Int64 nRead = aGrabber.readBytes ( aCENBuffer.data(), nCenLen ); if (nCenLen != nRead) throw ZipException (u"Error reading CEN into memory buffer!"_ustr ); - MemoryByteGrabber aMemGrabber(aCENBuffer); + MemoryByteGrabber aMemGrabber(aCENBuffer.data(), nCenLen); ZipEntry aEntry; sal_Int16 nCommentLen; @@ -1590,29 +1614,30 @@ void ZipFile::HandlePK34(std::span<const sal_Int8> data, sal_Int64 dataOffset, s RTL_TEXTENCODING_UTF8); else { - Sequence<sal_Int8> aFileName; + std::vector<sal_Int8> aFileName(aEntry.nPathLen); aGrabber.seek(dataOffset + 30); - aGrabber.readBytes(aFileName, aEntry.nPathLen); - aEntry.sPath = OUString(reinterpret_cast<const char*>(aFileName.getConstArray()), - aFileName.getLength(), RTL_TEXTENCODING_UTF8); - aEntry.nPathLen = static_cast<sal_Int16>(aFileName.getLength()); + aGrabber.readBytes(aFileName.data(), aEntry.nPathLen); + aEntry.sPath = OUString(reinterpret_cast<const char*>(aFileName.data()), + aEntry.nPathLen, RTL_TEXTENCODING_UTF8); + aEntry.nPathLen = aEntry.nPathLen; } aEntry.sPath = aEntry.sPath.replace('\\', '/'); // read 64bit header if (aEntry.nExtraLen > 0) { - Sequence<sal_Int8> aExtraBuffer; + std::vector<sal_Int8> aExtraBuffer(aEntry.nExtraLen); if (o3tl::make_unsigned(30 + aEntry.nPathLen) + aEntry.nExtraLen <= data.size()) { - aExtraBuffer = Sequence<sal_Int8>(data.data() + 30 + aEntry.nPathLen, aEntry.nExtraLen); + auto it = data.begin() + 30 + aEntry.nPathLen; + std::copy(it, it + aEntry.nExtraLen, aExtraBuffer.begin()); } else { aGrabber.seek(dataOffset + 30 + aEntry.nExtraLen); - aGrabber.readBytes(aExtraBuffer, aEntry.nExtraLen); + aGrabber.readBytes(aExtraBuffer.data(), aEntry.nExtraLen); } - MemoryByteGrabber aMemGrabberExtra(aExtraBuffer); + MemoryByteGrabber aMemGrabberExtra(aExtraBuffer.data(), aEntry.nExtraLen); if (aEntry.nExtraLen > 0) { ::std::optional<sal_uInt64> oOffset64; @@ -1743,7 +1768,9 @@ void ZipFile::recover() { ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() ); - Sequence < sal_Int8 > aBuffer; + std::vector < sal_Int8 > aBuffer; + const sal_Int64 nToRead = 32000; + aBuffer.reserve(nToRead); try { @@ -1753,11 +1780,11 @@ void ZipFile::recover() aGrabber.seek( 0 ); - const sal_Int64 nToRead = 32000; - for( sal_Int64 nGenPos = 0; aGrabber.readBytes( aBuffer, nToRead ) && aBuffer.getLength() > 16; ) + sal_Int32 nRead; + for( sal_Int64 nGenPos = 0; (nRead = aGrabber.readBytes( aBuffer.data(), nToRead )) && nRead > 16; ) { - const sal_Int8 *pBuffer = aBuffer.getConstArray(); - const sal_Int32 nBufSize = aBuffer.getLength(); + const sal_Int8 *pBuffer = aBuffer.data(); + const sal_Int32 nBufSize = nRead; sal_Int64 nPos = 0; // the buffer should contain at least one header, @@ -1822,17 +1849,18 @@ sal_Int32 ZipFile::getCRC( sal_Int64 nOffset, sal_Int64 nSize ) { ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() ); - Sequence < sal_Int8 > aBuffer; CRC32 aCRC; sal_Int64 nBlockSize = ::std::min(nSize, static_cast< sal_Int64 >(32000)); + std::vector < sal_Int8 > aBuffer; + aBuffer.reserve(nBlockSize); aGrabber.seek( nOffset ); + sal_Int32 nRead; for (sal_Int64 ind = 0; - aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nSize; + (nRead = aGrabber.readBytes( aBuffer.data(), nBlockSize )) && ind * nBlockSize < nSize; ++ind) { - sal_Int64 nLen = ::std::min(nBlockSize, nSize - ind * nBlockSize); - aCRC.updateSegment(aBuffer, static_cast<sal_Int32>(nLen)); + aCRC.updateSegment(aBuffer.data(), nRead); } return aCRC.getValue(); @@ -1842,26 +1870,29 @@ void ZipFile::getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_I { ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() ); - Sequence < sal_Int8 > aBuffer; CRC32 aCRC; sal_Int64 nRealSize = 0; - Inflater aInflaterLocal( true ); + ZipUtils::InflaterBytes aInflaterLocal( true ); sal_Int32 nBlockSize = static_cast< sal_Int32 > (::std::min( nCompressedSize, static_cast< sal_Int64 >( 32000 ) ) ); + std::vector < sal_Int8 > aBuffer(nBlockSize); + std::vector< sal_Int8 > aData( nBlockSize ); aGrabber.seek( nOffset ); + sal_Int32 nRead; for ( sal_Int64 ind = 0; - !aInflaterLocal.finished() && aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nCompressedSize; + !aInflaterLocal.finished() + && (nRead = aGrabber.readBytes( aBuffer.data(), nBlockSize )) + && ind * nBlockSize < nCompressedSize; ind++ ) { - Sequence < sal_Int8 > aData( nBlockSize ); sal_Int32 nLastInflated = 0; sal_Int64 nInBlock = 0; - aInflaterLocal.setInput( aBuffer ); + aInflaterLocal.setInput( aBuffer.data(), nRead ); do { - nLastInflated = aInflaterLocal.doInflateSegment( aData, 0, nBlockSize ); - aCRC.updateSegment( aData, nLastInflated ); + nLastInflated = aInflaterLocal.doInflateSegment( aData.data(), nBlockSize, 0, nBlockSize ); + aCRC.updateSegment( aData.data(), nLastInflated ); nInBlock += nLastInflated; } while( !aInflater.finished() && nLastInflated ); diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 1b129362b4a4..0b6b1ee0503f 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -1241,6 +1241,7 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const std::vector< void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream ) { + assert(dynamic_cast<comphelper::ByteReader*>(xInStream.get())); m_xContentSeek.set( xInStream, uno::UNO_QUERY_THROW ); m_xContentStream = xInStream; diff --git a/package/source/zippackage/wrapstreamforshare.cxx b/package/source/zippackage/wrapstreamforshare.cxx index 250ccb4ba5ce..026aee989b01 100644 --- a/package/source/zippackage/wrapstreamforshare.cxx +++ b/package/source/zippackage/wrapstreamforshare.cxx @@ -46,6 +46,8 @@ WrapStreamForShare::WrapStreamForShare( uno::Reference< io::XInputStream > xInSt throw uno::RuntimeException(THROW_WHERE ); } m_xSeekable.set( m_xInStream, uno::UNO_QUERY_THROW ); + mpByteReader = dynamic_cast<comphelper::ByteReader*>(m_xInStream.get()); + assert(mpByteReader); } WrapStreamForShare::~WrapStreamForShare() @@ -79,6 +81,19 @@ sal_Int32 SAL_CALL WrapStreamForShare::readSomeBytes( uno::Sequence< sal_Int8 >& return nRead; } +sal_Int32 WrapStreamForShare::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead ) +{ + if ( !m_xInStream.is() ) + throw io::IOException(THROW_WHERE ); + + m_xSeekable->seek( m_nCurPos ); + + sal_Int32 nRead = mpByteReader->readSomeBytes( aData, nMaxBytesToRead ); + m_nCurPos += nRead; + + return nRead; +} + void SAL_CALL WrapStreamForShare::skipBytes( sal_Int32 nBytesToSkip ) { ::osl::MutexGuard aGuard( m_xMutex->GetMutex() ); @@ -113,6 +128,7 @@ void SAL_CALL WrapStreamForShare::closeInput() // m_xInStream->closeInput(); m_xInStream.clear(); m_xSeekable.clear(); + mpByteReader = nullptr; } // XSeekable diff --git a/package/source/zippackage/wrapstreamforshare.hxx b/package/source/zippackage/wrapstreamforshare.hxx index ac8de258842f..adc57862d4ea 100644 --- a/package/source/zippackage/wrapstreamforshare.hxx +++ b/package/source/zippackage/wrapstreamforshare.hxx @@ -22,15 +22,18 @@ #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <comphelper/bytereader.hxx> #include <comphelper/refcountedmutex.hxx> #include <cppuhelper/implbase.hxx> #include <rtl/ref.hxx> class WrapStreamForShare final : public cppu::WeakImplHelper < css::io::XInputStream - , css::io::XSeekable > + , css::io::XSeekable >, + public comphelper::ByteReader { rtl::Reference< comphelper::RefCountedMutex > m_xMutex; css::uno::Reference < css::io::XInputStream > m_xInStream; + comphelper::ByteReader* mpByteReader; css::uno::Reference < css::io::XSeekable > m_xSeekable; sal_Int64 m_nCurPos; @@ -52,6 +55,8 @@ public: virtual sal_Int64 SAL_CALL getPosition() override; virtual sal_Int64 SAL_CALL getLength() override; + // comphelper::ByteReader + virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override; }; #endif |