tdf#137308 - Part 1: Refactor Inflater classes for extensibility
Refactor ZIP decompression classes (Inflater, InflaterBytes) to support multiple decompression algorithms, enabling future Zstandard support. Make Inflater and InflaterBytes abstract base classes defining a common interface. Move the original zlib/Deflate logic into new derived classes InflateZlib and InflaterBytesZlib. Update usage sites to instantiate the *Zlib variants via unique_ptr to the base class, preserving existing functionality. Move header files to standard locations (include/package, package/inc) and update includes and build files. This pure refactoring prepares the codebase for adding Zstandard (zstd) decompression. Correct a minor logical bug in the ZipFile::getSizeAndCRC loop condition. Change-Id: I9be3c02946e29eb2dae09f500eb47d8a4261af22 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183504 Reviewed-by: Devansh Varshney <varshney.devansh614@gmail.com> Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com> Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com> Tested-by: Jenkins
This commit is contained in:
committed by
Caolán McNamara
parent
ac6c7b4f82
commit
3e1aa5805c
@@ -41,6 +41,7 @@ $(eval $(call gb_Library_use_externals,xsltfilter,\
|
||||
libxml2 \
|
||||
libxslt \
|
||||
libexslt \
|
||||
zlib \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Library_add_exception_objects,xsltfilter,\
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "OleHandler.hxx"
|
||||
#include <optional>
|
||||
#include <package/InflateZlib.hxx>
|
||||
|
||||
using namespace ::com::sun::star::uno;
|
||||
using namespace ::com::sun::star::lang;
|
||||
@@ -116,7 +117,7 @@ namespace XSLT
|
||||
}
|
||||
|
||||
// Decompress the bytes
|
||||
std::optional< ::ZipUtils::Inflater> decompresser(std::in_place, false);
|
||||
std::unique_ptr< ::ZipUtils::Inflater> decompresser = std::make_unique< ::ZipUtils::InflateZlib>(false);
|
||||
decompresser->setInput(content);
|
||||
Sequence<sal_Int8> result(oleLength);
|
||||
decompresser->doInflateSegment(result, 0, oleLength);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <package/Inflater.hxx>
|
||||
#include <zlib.h>
|
||||
|
||||
namespace ZipUtils
|
||||
{
|
||||
class DLLPUBLIC_PACKAGE InflateZlib : public Inflater
|
||||
{
|
||||
private:
|
||||
bool bFinished;
|
||||
bool bNeedDict;
|
||||
sal_Int32 nOffset;
|
||||
sal_Int32 nLength;
|
||||
sal_Int32 nLastInflateError;
|
||||
css::uno::Sequence<sal_Int8> sInBuffer;
|
||||
std::unique_ptr<z_stream> pStream;
|
||||
|
||||
sal_Int32 doInflateBytes(css::uno::Sequence<sal_Int8>& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
|
||||
|
||||
public:
|
||||
explicit InflateZlib(bool bNoWrap);
|
||||
virtual ~InflateZlib() override;
|
||||
|
||||
virtual void setInput(const css::uno::Sequence<sal_Int8>& rBuffer) override;
|
||||
virtual bool needsDictionary() const override { return bNeedDict; }
|
||||
virtual bool finished() const override { return bFinished; }
|
||||
virtual sal_Int32 doInflateSegment(css::uno::Sequence<sal_Int8>& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength) override;
|
||||
virtual void end() override final;
|
||||
virtual sal_Int32 getLastInflateError() const override { return nLastInflateError; }
|
||||
};
|
||||
|
||||
} // namespace ZipUtils
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
@@ -25,52 +25,35 @@
|
||||
#include <package/packagedllapi.hxx>
|
||||
#include <memory>
|
||||
|
||||
struct z_stream_s;
|
||||
|
||||
namespace ZipUtils {
|
||||
|
||||
class UNLESS_MERGELIBS(DLLPUBLIC_PACKAGE) Inflater final
|
||||
class UNLESS_MERGELIBS(DLLPUBLIC_PACKAGE) Inflater
|
||||
{
|
||||
typedef struct z_stream_s z_stream;
|
||||
|
||||
bool bFinished, bNeedDict;
|
||||
sal_Int32 nOffset, nLength, nLastInflateError;
|
||||
std::unique_ptr<z_stream> pStream;
|
||||
css::uno::Sequence < sal_Int8 > sInBuffer;
|
||||
sal_Int32 doInflateBytes (css::uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
|
||||
|
||||
public:
|
||||
Inflater(bool bNoWrap);
|
||||
~Inflater();
|
||||
void setInput( const css::uno::Sequence< sal_Int8 >& rBuffer );
|
||||
bool needsDictionary() const { return bNeedDict; }
|
||||
bool finished() const { return bFinished; }
|
||||
sal_Int32 doInflateSegment( css::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength );
|
||||
void end( );
|
||||
Inflater() = default;
|
||||
virtual ~Inflater() = default;
|
||||
|
||||
sal_Int32 getLastInflateError() const { return nLastInflateError; }
|
||||
virtual void setInput(const css::uno::Sequence<sal_Int8>& rBuffer) = 0;
|
||||
virtual bool needsDictionary() const = 0;
|
||||
virtual bool finished() const = 0;
|
||||
virtual sal_Int32 doInflateSegment(css::uno::Sequence<sal_Int8>& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength) = 0;
|
||||
virtual void end() = 0;
|
||||
virtual sal_Int32 getLastInflateError() const = 0;
|
||||
};
|
||||
|
||||
class UNLESS_MERGELIBS(DLLPUBLIC_PACKAGE) InflaterBytes final
|
||||
class UNLESS_MERGELIBS(DLLPUBLIC_PACKAGE) InflaterBytes
|
||||
{
|
||||
typedef struct z_stream_s z_stream;
|
||||
|
||||
bool bFinished;
|
||||
sal_Int32 nOffset, nLength;
|
||||
std::unique_ptr<z_stream> pStream;
|
||||
const sal_Int8* sInBuffer;
|
||||
sal_Int32 doInflateBytes (sal_Int8* pOutBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
|
||||
|
||||
public:
|
||||
InflaterBytes();
|
||||
~InflaterBytes();
|
||||
void setInput( const sal_Int8* pBuffer, sal_Int32 nLen );
|
||||
bool finished() const { return bFinished; }
|
||||
sal_Int32 doInflateSegment( sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength );
|
||||
void end( );
|
||||
InflaterBytes() = default;
|
||||
virtual ~InflaterBytes() = default;
|
||||
|
||||
virtual void setInput(const sal_Int8* pBuffer, sal_Int32 nLen) = 0;
|
||||
virtual bool finished() const = 0;
|
||||
virtual sal_Int32 doInflateSegment(sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength) = 0;
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ZipUtils
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ $(eval $(call gb_Library_add_exception_objects,package2,\
|
||||
package/source/zipapi/ByteGrabber \
|
||||
package/source/zipapi/CRC32 \
|
||||
package/source/zipapi/Deflater \
|
||||
package/source/zipapi/Inflater \
|
||||
package/source/zipapi/InflaterBytesZlib \
|
||||
package/source/zipapi/InflateZlib \
|
||||
package/source/zipapi/sha1context \
|
||||
package/source/zipapi/ThreadedDeflater \
|
||||
package/source/zipapi/XBufferedThreadedStream \
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <package/Inflater.hxx>
|
||||
#include <zlib.h>
|
||||
|
||||
namespace ZipUtils
|
||||
{
|
||||
class DLLPUBLIC_PACKAGE InflaterBytesZlib : public InflaterBytes
|
||||
{
|
||||
private:
|
||||
bool bFinished;
|
||||
sal_Int32 nOffset;
|
||||
sal_Int32 nLength;
|
||||
const sal_Int8* sInBuffer;
|
||||
std::unique_ptr<z_stream> pStream;
|
||||
|
||||
sal_Int32 doInflateBytes(sal_Int8* pOutBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
|
||||
|
||||
public:
|
||||
InflaterBytesZlib();
|
||||
virtual ~InflaterBytesZlib() override;
|
||||
|
||||
virtual void setInput(const sal_Int8* pBuffer, sal_Int32 nLen) override;
|
||||
virtual bool finished() const override { return bFinished; }
|
||||
virtual sal_Int32 doInflateSegment(sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength) override;
|
||||
virtual void end() override final;
|
||||
};
|
||||
|
||||
} // namespace ZipUtils
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <comphelper/refcountedmutex.hxx>
|
||||
#include <package/Inflater.hxx>
|
||||
#include <memory>
|
||||
#include <rtl/ref.hxx>
|
||||
#include "ByteGrabber.hxx"
|
||||
#include "HashMaps.hxx"
|
||||
@@ -61,7 +62,7 @@ private:
|
||||
|
||||
EntryHash aEntries;
|
||||
ByteGrabber aGrabber;
|
||||
ZipUtils::Inflater aInflater;
|
||||
std::unique_ptr<ZipUtils::Inflater> aInflater;
|
||||
css::uno::Reference < css::io::XInputStream > xStream;
|
||||
const css::uno::Reference < css::uno::XComponentContext > m_xContext;
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <package/InflateZlib.hxx>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace com::sun::star::uno;
|
||||
using namespace ZipUtils;
|
||||
|
||||
InflateZlib::InflateZlib(bool bNoWrap)
|
||||
: bFinished(false),
|
||||
bNeedDict(false),
|
||||
nOffset(0),
|
||||
nLength(0),
|
||||
nLastInflateError(0),
|
||||
pStream(std::make_unique<z_stream>())
|
||||
{
|
||||
memset(pStream.get(), 0, sizeof(*pStream));
|
||||
sal_Int32 nRes = inflateInit2(pStream.get(), bNoWrap ? -MAX_WBITS : MAX_WBITS);
|
||||
switch (nRes)
|
||||
{
|
||||
case Z_OK:
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
pStream.reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InflateZlib::~InflateZlib()
|
||||
{
|
||||
end();
|
||||
}
|
||||
|
||||
void InflateZlib::setInput(const Sequence<sal_Int8>& rBuffer)
|
||||
{
|
||||
sInBuffer = rBuffer;
|
||||
nOffset = 0;
|
||||
nLength = rBuffer.getLength();
|
||||
}
|
||||
|
||||
sal_Int32 InflateZlib::doInflateSegment(Sequence<sal_Int8>& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
|
||||
{
|
||||
if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return doInflateBytes(rBuffer, nNewOffset, nNewLength);
|
||||
}
|
||||
|
||||
void InflateZlib::end()
|
||||
{
|
||||
if (pStream)
|
||||
{
|
||||
#if !defined Z_PREFIX
|
||||
inflateEnd(pStream.get());
|
||||
#else
|
||||
z_inflateEnd(pStream.get());
|
||||
#endif
|
||||
pStream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
sal_Int32 InflateZlib::doInflateBytes(Sequence<sal_Int8>& rBuffer, 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.getConstArray() + nOffset);
|
||||
pStream->avail_in = nLength;
|
||||
pStream->next_out = reinterpret_cast<unsigned char*>(rBuffer.getArray() + 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:
|
||||
if (nLength && nNewLength)
|
||||
nLastInflateError = nResult;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
@@ -1,239 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* This file incorporates work covered by the following license notice:
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
|
||||
*/
|
||||
|
||||
#include <package/Inflater.hxx>
|
||||
#include <zlib.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace com::sun::star::uno;
|
||||
using namespace ZipUtils;
|
||||
|
||||
/** Provides general purpose decompression using the ZLIB library */
|
||||
|
||||
Inflater::Inflater(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;
|
||||
}
|
||||
}
|
||||
|
||||
Inflater::~Inflater()
|
||||
{
|
||||
end();
|
||||
}
|
||||
|
||||
void Inflater::setInput( const Sequence< sal_Int8 >& rBuffer )
|
||||
{
|
||||
sInBuffer = rBuffer;
|
||||
nOffset = 0;
|
||||
nLength = rBuffer.getLength();
|
||||
}
|
||||
|
||||
|
||||
sal_Int32 Inflater::doInflateSegment( Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
|
||||
{
|
||||
if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength())
|
||||
{
|
||||
// do error handling
|
||||
}
|
||||
return doInflateBytes(rBuffer, nNewOffset, nNewLength);
|
||||
}
|
||||
|
||||
void Inflater::end( )
|
||||
{
|
||||
if (pStream)
|
||||
{
|
||||
#if !defined Z_PREFIX
|
||||
inflateEnd(pStream.get());
|
||||
#else
|
||||
z_inflateEnd(pStream.get());
|
||||
#endif
|
||||
pStream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
sal_Int32 Inflater::doInflateBytes (Sequence < sal_Int8 > &rBuffer, 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.getConstArray() + nOffset );
|
||||
pStream->avail_in = nLength;
|
||||
pStream->next_out = reinterpret_cast < unsigned char* > ( rBuffer.getArray() + 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;
|
||||
}
|
||||
|
||||
InflaterBytes::InflaterBytes()
|
||||
: bFinished(false),
|
||||
nOffset(0),
|
||||
nLength(0),
|
||||
sInBuffer(nullptr)
|
||||
{
|
||||
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(), -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 )
|
||||
{
|
||||
return 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:
|
||||
nOffset += nLength - pStream->avail_in;
|
||||
nLength = pStream->avail_in;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
// it is no error, if there is no input or no output
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
@@ -0,0 +1,105 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <InflaterBytesZlib.hxx>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace ZipUtils;
|
||||
|
||||
InflaterBytesZlib::InflaterBytesZlib()
|
||||
: bFinished(false),
|
||||
nOffset(0),
|
||||
nLength(0),
|
||||
sInBuffer(nullptr),
|
||||
pStream(std::make_unique<z_stream>())
|
||||
{
|
||||
memset(pStream.get(), 0, sizeof(*pStream));
|
||||
sal_Int32 nRes = inflateInit2(pStream.get(), -MAX_WBITS);
|
||||
switch (nRes)
|
||||
{
|
||||
case Z_OK:
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
pStream.reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InflaterBytesZlib::~InflaterBytesZlib() { end(); }
|
||||
|
||||
void InflaterBytesZlib::setInput(const sal_Int8* rBuffer, sal_Int32 nBufLen)
|
||||
{
|
||||
sInBuffer = rBuffer;
|
||||
nOffset = 0;
|
||||
nLength = nBufLen;
|
||||
}
|
||||
|
||||
sal_Int32 InflaterBytesZlib::doInflateSegment(sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength)
|
||||
{
|
||||
if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > nBufLen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return doInflateBytes(pOutBuffer, nNewOffset, nNewLength);
|
||||
}
|
||||
|
||||
void InflaterBytesZlib::end()
|
||||
{
|
||||
if (pStream)
|
||||
{
|
||||
#if !defined Z_PREFIX
|
||||
inflateEnd(pStream.get());
|
||||
#else
|
||||
z_inflateEnd(pStream.get());
|
||||
#endif
|
||||
pStream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
sal_Int32 InflaterBytesZlib::doInflateBytes(sal_Int8* pOutBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
|
||||
{
|
||||
if (!pStream)
|
||||
return 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:
|
||||
nOffset += nLength - pStream->avail_in;
|
||||
nLength = pStream->avail_in;
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
@@ -23,16 +23,16 @@
|
||||
|
||||
#include "XUnbufferedStream.hxx"
|
||||
#include <EncryptionData.hxx>
|
||||
#include <ZipFile.hxx>
|
||||
#include <package/InflateZlib.hxx>
|
||||
#include <EncryptedDataHeader.hxx>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
#include <o3tl/safeint.hxx>
|
||||
#include <osl/diagnose.h>
|
||||
#include <osl/mutex.hxx>
|
||||
#include <utility>
|
||||
#include <comphelper/diagnose_ex.hxx>
|
||||
#include <ZipFile.hxx>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
using namespace com::sun::star::packages::zip::ZipConstants;
|
||||
@@ -55,7 +55,7 @@ XUnbufferedStream::XUnbufferedStream(
|
||||
, mxZipSeek ( xNewZipStream, UNO_QUERY )
|
||||
, maEntry ( rEntry )
|
||||
, mnBlockSize( 1 )
|
||||
, maInflater ( true )
|
||||
, maInflater( std::make_unique<ZipUtils::InflateZlib>(true) )
|
||||
, mbRawStream ( nStreamMode == UNBUFF_STREAM_RAW || nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
|
||||
, mbWrappedRaw ( nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
|
||||
, mnHeaderToRead ( 0 )
|
||||
@@ -126,7 +126,7 @@ XUnbufferedStream::XUnbufferedStream(
|
||||
, mxZipStream ( xRawStream )
|
||||
, mxZipSeek ( xRawStream, UNO_QUERY )
|
||||
, mnBlockSize( 1 )
|
||||
, maInflater ( true )
|
||||
, maInflater( std::make_unique<ZipUtils::InflateZlib>(true) )
|
||||
, mbRawStream ( false )
|
||||
, mbWrappedRaw ( false )
|
||||
, mnHeaderToRead ( 0 )
|
||||
@@ -231,7 +231,7 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
nLastRead = maInflater.doInflateSegment( aData, nRead, aData.getLength() - nRead );
|
||||
nLastRead = maInflater->doInflateSegment( aData, nRead, aData.getLength() - nRead );
|
||||
if ( 0 != nLastRead && ( nRead + nLastRead == nRequestedBytes || mnZipCurrent >= mnZipEnd ) )
|
||||
break;
|
||||
nRead += nLastRead;
|
||||
@@ -239,10 +239,10 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
|
||||
throw RuntimeException(
|
||||
u"Should not be possible to read more than requested!"_ustr );
|
||||
|
||||
if ( maInflater.finished() || maInflater.getLastInflateError() )
|
||||
if ( maInflater->finished() || maInflater->getLastInflateError() )
|
||||
throw ZipIOException(u"The stream seems to be broken!"_ustr );
|
||||
|
||||
if ( maInflater.needsDictionary() )
|
||||
if ( maInflater->needsDictionary() )
|
||||
throw ZipIOException(u"Dictionaries are not supported!"_ustr );
|
||||
|
||||
sal_Int32 nDiff = static_cast< sal_Int32 >( mnZipEnd - mnZipCurrent );
|
||||
@@ -283,7 +283,7 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
|
||||
}
|
||||
}
|
||||
}
|
||||
maInflater.setInput ( maCompBuffer );
|
||||
maInflater->setInput ( maCompBuffer );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <cppuhelper/implbase.hxx>
|
||||
#include <rtl/ref.hxx>
|
||||
#include <package/Inflater.hxx>
|
||||
#include <memory>
|
||||
#include <ZipEntry.hxx>
|
||||
#include <CRC32.hxx>
|
||||
|
||||
@@ -54,7 +55,7 @@ class XUnbufferedStream final : public cppu::WeakImplHelper
|
||||
ZipEntry maEntry;
|
||||
sal_Int32 mnBlockSize;
|
||||
css::uno::Reference< css::xml::crypto::XCipherContext > m_xCipherContext;
|
||||
ZipUtils::Inflater maInflater;
|
||||
std::unique_ptr<ZipUtils::Inflater> maInflater;
|
||||
bool mbRawStream, mbWrappedRaw;
|
||||
sal_Int16 mnHeaderToRead;
|
||||
sal_Int64 mnZipCurrent, mnZipEnd, mnZipSize, mnMyCurrent;
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#include "MemoryByteGrabber.hxx"
|
||||
|
||||
#include <CRC32.hxx>
|
||||
#include <package/InflateZlib.hxx>
|
||||
#include <InflaterBytesZlib.hxx>
|
||||
|
||||
using namespace com::sun::star;
|
||||
using namespace com::sun::star::io;
|
||||
@@ -88,7 +90,7 @@ ZipFile::ZipFile( rtl::Reference< comphelper::RefCountedMutex > aMutexHolder,
|
||||
: m_aMutexHolder(std::move( aMutexHolder ))
|
||||
, m_Checks(checks)
|
||||
, aGrabber( xInput )
|
||||
, aInflater( true )
|
||||
, aInflater( std::make_unique<ZipUtils::InflateZlib>(true) )
|
||||
, xStream(xInput)
|
||||
, m_xContext (std::move( xContext ))
|
||||
, bRecoveryMode( bForceRecovery )
|
||||
@@ -1959,7 +1961,7 @@ void ZipFile::getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_I
|
||||
|
||||
CRC32 aCRC;
|
||||
sal_Int64 nRealSize = 0;
|
||||
ZipUtils::InflaterBytes aInflaterLocal;
|
||||
ZipUtils::InflaterBytesZlib aInflaterLocal;
|
||||
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 );
|
||||
@@ -1981,7 +1983,7 @@ void ZipFile::getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_I
|
||||
nLastInflated = aInflaterLocal.doInflateSegment( aData.data(), nBlockSize, 0, nBlockSize );
|
||||
aCRC.updateSegment( aData.data(), nLastInflated );
|
||||
nInBlock += nLastInflated;
|
||||
} while( !aInflater.finished() && nLastInflated );
|
||||
} while( !aInflaterLocal.finished() && nLastInflated );
|
||||
|
||||
nRealSize += nInBlock;
|
||||
}
|
||||
|
||||
@@ -5330,6 +5330,7 @@ include/osl/thread.hxx
|
||||
include/osl/time.h
|
||||
include/package/Deflater.hxx
|
||||
include/package/Inflater.hxx
|
||||
include/package/InflateZlib.hxx
|
||||
include/registry/reader.hxx
|
||||
include/registry/registry.hxx
|
||||
include/registry/typereg_reader.hxx
|
||||
@@ -7065,6 +7066,7 @@ package/inc/ByteGrabber.hxx
|
||||
package/inc/CRC32.hxx
|
||||
package/inc/EncryptionData.hxx
|
||||
package/inc/HashMaps.hxx
|
||||
package/inc/InflaterBytesZlib.hxx
|
||||
package/inc/ZipFile.hxx
|
||||
package/inc/ZipOutputEntry.hxx
|
||||
package/inc/ZipOutputStream.hxx
|
||||
@@ -7112,6 +7114,8 @@ package/source/zipapi/XBufferedThreadedStream.hxx
|
||||
package/source/zipapi/XUnbufferedStream.cxx
|
||||
package/source/zipapi/XUnbufferedStream.hxx
|
||||
package/source/zipapi/ZipFile.cxx
|
||||
package/source/zipapi/InflateZlib.cxx
|
||||
package/source/zipapi/InflaterBytesZlib.cxx
|
||||
package/source/zipapi/ZipOutputEntry.cxx
|
||||
package/source/zipapi/ZipOutputStream.cxx
|
||||
package/source/zipapi/blowfishcontext.cxx
|
||||
|
||||
Reference in New Issue
Block a user