summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Kumar Dubey <akshaymani513@gmail.com>2025-03-30 16:27:05 +0530
committerCaolán McNamara <caolan.mcnamara@collabora.com>2025-04-29 09:38:52 +0200
commit3e1aa5805cb2339a55ffce0448e0b3b5d8efd3a6 (patch)
tree7ddf543c9c27ee7fd89db8d853efbce5cb54f9b9
parentac6c7b4f826f053ce0ebe496b906a963c8c52342 (diff)
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
-rw-r--r--filter/Library_xsltfilter.mk1
-rw-r--r--filter/source/xsltfilter/OleHandler.cxx3
-rw-r--r--include/package/InflateZlib.hxx45
-rw-r--r--include/package/Inflater.hxx55
-rw-r--r--package/Library_package2.mk3
-rw-r--r--package/inc/InflaterBytesZlib.hxx41
-rw-r--r--package/inc/ZipFile.hxx3
-rw-r--r--package/source/zipapi/InflateZlib.cxx115
-rw-r--r--package/source/zipapi/Inflater.cxx239
-rw-r--r--package/source/zipapi/InflaterBytesZlib.cxx105
-rw-r--r--package/source/zipapi/XUnbufferedStream.cxx16
-rw-r--r--package/source/zipapi/XUnbufferedStream.hxx3
-rw-r--r--package/source/zipapi/ZipFile.cxx8
-rw-r--r--solenv/clang-format/excludelist4
14 files changed, 351 insertions, 290 deletions
diff --git a/filter/Library_xsltfilter.mk b/filter/Library_xsltfilter.mk
index 42f426c945ea..a7062bac0e86 100644
--- a/filter/Library_xsltfilter.mk
+++ b/filter/Library_xsltfilter.mk
@@ -41,6 +41,7 @@ $(eval $(call gb_Library_use_externals,xsltfilter,\
libxml2 \
libxslt \
libexslt \
+ zlib \
))
$(eval $(call gb_Library_add_exception_objects,xsltfilter,\
diff --git a/filter/source/xsltfilter/OleHandler.cxx b/filter/source/xsltfilter/OleHandler.cxx
index feab2eec414c..abd8a7e9f208 100644
--- a/filter/source/xsltfilter/OleHandler.cxx
+++ b/filter/source/xsltfilter/OleHandler.cxx
@@ -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);
diff --git a/include/package/InflateZlib.hxx b/include/package/InflateZlib.hxx
new file mode 100644
index 000000000000..f495453a779b
--- /dev/null
+++ b/include/package/InflateZlib.hxx
@@ -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: */
diff --git a/include/package/Inflater.hxx b/include/package/Inflater.hxx
index c529b471cb6f..8e5cbfae2650 100644
--- a/include/package/Inflater.hxx
+++ b/include/package/Inflater.hxx
@@ -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( );
-
- sal_Int32 getLastInflateError() const { return nLastInflateError; }
+ Inflater() = default;
+ virtual ~Inflater() = default;
+
+ 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
diff --git a/package/Library_package2.mk b/package/Library_package2.mk
index 16ef09af5f6d..a740d33fc757 100644
--- a/package/Library_package2.mk
+++ b/package/Library_package2.mk
@@ -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 \
diff --git a/package/inc/InflaterBytesZlib.hxx b/package/inc/InflaterBytesZlib.hxx
new file mode 100644
index 000000000000..50da895e1b7a
--- /dev/null
+++ b/package/inc/InflaterBytesZlib.hxx
@@ -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: */
diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx
index f496dfa2ce24..1252ae325df5 100644
--- a/package/inc/ZipFile.hxx
+++ b/package/inc/ZipFile.hxx
@@ -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;
diff --git a/package/source/zipapi/InflateZlib.cxx b/package/source/zipapi/InflateZlib.cxx
new file mode 100644
index 000000000000..a7b2bb3643f4
--- /dev/null
+++ b/package/source/zipapi/InflateZlib.cxx
@@ -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: */
diff --git a/package/source/zipapi/Inflater.cxx b/package/source/zipapi/Inflater.cxx
deleted file mode 100644
index 3c2a59d78111..000000000000
--- a/package/source/zipapi/Inflater.cxx
+++ /dev/null
@@ -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: */
diff --git a/package/source/zipapi/InflaterBytesZlib.cxx b/package/source/zipapi/InflaterBytesZlib.cxx
new file mode 100644
index 000000000000..941d4cfd2c57
--- /dev/null
+++ b/package/source/zipapi/InflaterBytesZlib.cxx
@@ -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: */
diff --git a/package/source/zipapi/XUnbufferedStream.cxx b/package/source/zipapi/XUnbufferedStream.cxx
index 192958412d93..a5161adc36f0 100644
--- a/package/source/zipapi/XUnbufferedStream.cxx
+++ b/package/source/zipapi/XUnbufferedStream.cxx
@@ -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 );
}
}
diff --git a/package/source/zipapi/XUnbufferedStream.hxx b/package/source/zipapi/XUnbufferedStream.hxx
index f3efe0aaecce..27c6ebc3a841 100644
--- a/package/source/zipapi/XUnbufferedStream.hxx
+++ b/package/source/zipapi/XUnbufferedStream.hxx
@@ -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;
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index 5ae674d7272f..fb304b8beaae 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -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;
}
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index 76cb39ca577c..1e4a8301319b 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -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