filter/Library_xsltfilter.mk                |    1 
 filter/source/xsltfilter/OleHandler.cxx     |    3 
 include/package/InflateZlib.hxx             |   45 +++++
 include/package/Inflater.hxx                |   55 ++----
 package/Library_package2.mk                 |    3 
 package/inc/InflaterBytesZlib.hxx           |   41 ++++
 package/inc/ZipFile.hxx                     |    3 
 package/source/zipapi/InflateZlib.cxx       |  115 +++++++++++++
 package/source/zipapi/Inflater.cxx          |  239 ----------------------------
 package/source/zipapi/InflaterBytesZlib.cxx |  105 ++++++++++++
 package/source/zipapi/XUnbufferedStream.cxx |   16 -
 package/source/zipapi/XUnbufferedStream.hxx |    3 
 package/source/zipapi/ZipFile.cxx           |    8 
 solenv/clang-format/excludelist             |    4 
 14 files changed, 351 insertions(+), 290 deletions(-)

New commits:
commit 3e1aa5805cb2339a55ffce0448e0b3b5d8efd3a6
Author:     Akshay Kumar Dubey <akshaymani...@gmail.com>
AuthorDate: Sun Mar 30 16:27:05 2025 +0530
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue Apr 29 09:38:52 2025 +0200

    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.devansh...@gmail.com>
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Michael Meeks <michael.me...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins

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

Reply via email to