[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - 5 commits - include/xmloff solenv/bin sw/qa sw/source xmlsecurity/source

Xisco Fauli (via logerrit) logerrit at kemper.freedesktop.org
Thu Apr 1 08:08:39 UTC 2021


 include/xmloff/xmlnamespace.hxx              |    3 
 solenv/bin/hrcex                             |   13 
 solenv/bin/polib.py                          |    2 
 solenv/bin/uiex                              |   10 
 sw/qa/extras/uiwriter/data3/tdf140828.docx   |binary
 sw/qa/extras/uiwriter/uiwriter3.cxx          |   32 
 sw/qa/uitest/writer_dialogs/openDialogs.py   |    3 
 sw/qa/uitest/writer_tests7/tdf140863.py      |   75 +
 sw/source/core/doc/textboxhelper.cxx         |    5 
 sw/source/core/docnode/section.cxx           |   44 
 sw/source/core/text/porfly.cxx               |    4 
 xmlsecurity/source/helper/ooxmlsecparser.cxx | 1473 +++++++++++++++++++++++----
 xmlsecurity/source/helper/ooxmlsecparser.hxx |   74 -
 13 files changed, 1460 insertions(+), 278 deletions(-)

New commits:
commit 64b4af53d44243ff662a8b0cd404f134b589983e
Author:     Xisco Fauli <xiscofauli at libreoffice.org>
AuthorDate: Wed Mar 31 15:05:09 2021 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Thu Apr 1 10:07:48 2021 +0200

    tdf#140863: sw: Add UItest
    
    Change-Id: Ic1d3a56857dd68f436b870168ab394729a31d629
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113365
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofauli at libreoffice.org>

diff --git a/sw/qa/uitest/writer_dialogs/openDialogs.py b/sw/qa/uitest/writer_dialogs/openDialogs.py
index 4dbacaa1215e..086904cc3712 100644
--- a/sw/qa/uitest/writer_dialogs/openDialogs.py
+++ b/sw/qa/uitest/writer_dialogs/openDialogs.py
@@ -37,7 +37,8 @@ dialogs = [
     # {"command": ".uno:InsertBreak", "closeButton": "cancel"},
         # tested in uitest/writer_tests/insertBreakDialog.py
     {"command": ".uno:InsertObject", "closeButton": "cancel"},
-    {"command": ".uno:InsertSection", "closeButton": "cancel"},
+    # {"command": ".uno:InsertSection", "closeButton": "cancel"},
+        # tested in sw/qa/uitest/writer_tests7/tdf140863.py
     {"command": ".uno:InsertFrame", "closeButton": "cancel"},
     {"command": ".uno:InsertObjectFloatingFrame", "closeButton": "cancel"},
     {"command": ".uno:FontworkGalleryFloater", "closeButton": "cancel"},
diff --git a/sw/qa/uitest/writer_tests7/tdf140863.py b/sw/qa/uitest/writer_tests7/tdf140863.py
new file mode 100644
index 000000000000..f0355e4684ed
--- /dev/null
+++ b/sw/qa/uitest/writer_tests7/tdf140863.py
@@ -0,0 +1,75 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# 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/.
+#
+from uitest.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+
+class tdf140863(UITestCase):
+
+    def test_tdf140863(self):
+
+        self.ui_test.create_doc_in_start_center("writer")
+
+        # Insert one section
+        self.ui_test.execute_dialog_through_command(".uno:InsertSection")
+
+        xDialog = self.xUITest.getTopFocusWindow()
+
+        xOkBtn = xDialog.getChild("ok")
+        self.ui_test.close_dialog_through_button(xOkBtn)
+
+        xWriterDoc = self.xUITest.getTopFocusWindow()
+        xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+        # Insert a page break in the section
+        xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"}))
+        self.xUITest.executeCommand(".uno:InsertPagebreak")
+        self.assertEqual(get_state_as_dict(xWriterEdit)["CurrentPage"], "2")
+
+        document = self.ui_test.get_component()
+        self.assertEqual(1, len(document.TextSections))
+        self.assertTrue(document.TextSections.Section1.IsVisible)
+
+
+        self.ui_test.execute_dialog_through_command(".uno:EditRegion")
+
+        xDialog = self.xUITest.getTopFocusWindow()
+
+        xHide = xDialog.getChild('hide')
+        self.assertEqual('false', get_state_as_dict(xHide)['Selected'])
+
+        xHide.executeAction('CLICK', tuple())
+
+        xOkBtn = xDialog.getChild("ok")
+        self.ui_test.close_dialog_through_button(xOkBtn)
+
+        self.assertEqual(1, len(document.TextSections))
+        self.assertFalse(document.TextSections.Section1.IsVisible)
+        self.assertEqual(get_state_as_dict(xWriterEdit)["CurrentPage"], "1")
+
+        self.ui_test.execute_dialog_through_command(".uno:EditRegion")
+
+        xDialog = self.xUITest.getTopFocusWindow()
+
+        xHide = xDialog.getChild('hide')
+        self.assertEqual('true', get_state_as_dict(xHide)['Selected'])
+
+        xHide.executeAction('CLICK', tuple())
+
+        xOkBtn = xDialog.getChild("ok")
+        self.ui_test.close_dialog_through_button(xOkBtn)
+
+        self.assertEqual(1, len(document.TextSections))
+        self.assertTrue(document.TextSections.Section1.IsVisible)
+
+        # Without the fix in place, this test would have failed with
+        # AssertionError: '1' != '2'
+        self.assertEqual(get_state_as_dict(xWriterEdit)["CurrentPage"], "2")
+
+        self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
commit 60d3ed2874ecd556862aae26bc66e5a44fe14839
Author:     Bjoern Michaelsen <bjoern.michaelsen at libreoffice.org>
AuthorDate: Sun Nov 22 10:47:20 2020 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Thu Apr 1 10:07:37 2021 +0200

    tdf#140863: section.cxx: Remove remaining SwClientNotifyCalls
    
    Change-Id: I569c5952a7491c37c677ad6b6d5f803a50b2e701
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106341
    Tested-by: Jenkins
    Reviewed-by: Bjoern Michaelsen <bjoern.michaelsen at libreoffice.org>
    (cherry picked from commit 5fc6a601d7a1978db291fd0f7dcec638a7c25651)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113361
    Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>
    Tested-by: Xisco Fauli <xiscofauli at libreoffice.org>

diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx
index a3dad1262b23..00adf5a40f47 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -66,13 +66,6 @@
 using namespace ::com::sun::star;
 
 namespace {
-
-    void lcl_SwClientNotify(sw::BroadcastingModify& rModify, const SfxPoolItem* pOldNew)
-    {
-        const sw::LegacyModifyHint aHint(pOldNew, pOldNew);
-        rModify.SwClientNotifyCall(rModify, aHint);
-    }
-
     class SwIntrnlSectRefLink : public SwBaseLink
     {
         SwSectionFormat& m_rSectFormat;
@@ -318,8 +311,8 @@ void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
             // This should be shown by the bHiddenFlag.
 
             // Tell all Children that they are hidden
-            SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN );
-            lcl_SwClientNotify(*pFormat, &aMsgItem);
+            const SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN );
+            pFormat->CallSwClientNotify(sw::LegacyModifyHint(&aMsgItem, &aMsgItem));
 
             // Delete all Frames
             pFormat->DelFrames();
@@ -333,8 +326,8 @@ void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
         if( !pParentSect || !pParentSect->IsHiddenFlag() )
         {
             // Tell all Children that the Parent is not hidden anymore
-            SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN );
-            lcl_SwClientNotify(*pFormat, &aMsgItem);
+            const SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN );
+            pFormat->CallSwClientNotify(sw::LegacyModifyHint(&aMsgItem, &aMsgItem));
 
             pFormat->MakeFrames();
         }
@@ -719,8 +712,8 @@ void SwSectionFormat::DelFrames()
     SwContentNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, true, false );
     if( pCNd )
     {
-        const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC );
-        lcl_SwClientNotify(*pCNd, &rItem);
+        const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get(RES_PAGEDESC);
+        pCNd->CallSwClientNotify(sw::LegacyModifyHint(&rItem, &rItem));
     }
 }
 
@@ -945,22 +938,19 @@ void SwSectionFormat::UpdateParent()
         bIsHidden = pPS->IsHiddenFlag();
     }
     SwIterator<SwSectionFormat,SwSectionFormat> aIter(*this);
-    for(SwSectionFormat* pLast = aIter.First(); pLast; pLast = aIter.Next())
-    {
-        if(!pProtect->IsContentProtected() != !pSection->IsProtectFlag())
-            lcl_SwClientNotify(*static_cast<sw::BroadcastingModify*>(pLast), static_cast<SfxPoolItem const *>(pProtect));
+    if(!pProtect->IsContentProtected() != !pSection->IsProtectFlag())
+        CallSwClientNotify(sw::LegacyModifyHint(pProtect, pProtect));
 
-        // edit in readonly sections
-        if(!pEditInReadonly->GetValue() != !pSection->IsEditInReadonlyFlag())
-            lcl_SwClientNotify(*static_cast<sw::BroadcastingModify*>(pLast), static_cast<SfxPoolItem const *>(pEditInReadonly));
+    // edit in readonly sections
+    if(!pEditInReadonly->GetValue() != !pSection->IsEditInReadonlyFlag())
+        CallSwClientNotify(sw::LegacyModifyHint(pEditInReadonly, pEditInReadonly));
 
-        if(bIsHidden == pSection->IsHiddenFlag())
-        {
-            SwMsgPoolItem aMsgItem( static_cast<sal_uInt16>(bIsHidden
-                        ? RES_SECTION_HIDDEN
-                        : RES_SECTION_NOT_HIDDEN ) );
-            lcl_SwClientNotify(*static_cast<sw::BroadcastingModify*>(pLast), &aMsgItem);
-        }
+    if(bIsHidden == pSection->IsHiddenFlag())
+    {
+        SwMsgPoolItem aMsgItem(static_cast<sal_uInt16>(bIsHidden
+                ? RES_SECTION_HIDDEN
+                : RES_SECTION_NOT_HIDDEN));
+        CallSwClientNotify(sw::LegacyModifyHint(&aMsgItem, &aMsgItem));
     }
 }
 
commit 9661c7e48cef0f2e73aa024fcf5c0ecdbf0b037b
Author:     Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Tue Mar 30 17:37:31 2021 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Thu Apr 1 10:07:31 2021 +0200

    xmlsecurity: replace OOXMLSecParser implementation
    
    This is similar to 12b15be8f4f930a04d8056b9219ac969b42a9784 and following
    commits, but OOXMLSecParser has some differences to XSecParser, such as
    using a ds:Manifest, and requires a couple extra namespaces.
    
    Change-Id: I56e39d9609db8fcad50ca1632ff482c1f0a30ff5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113381
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    (cherry picked from commit cc1d19f7bbaefa5fb22ebd1344112755068b93c9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113359

diff --git a/include/xmloff/xmlnamespace.hxx b/include/xmloff/xmlnamespace.hxx
index cabdcc7578e2..91ff2aae4cf3 100644
--- a/include/xmloff/xmlnamespace.hxx
+++ b/include/xmloff/xmlnamespace.hxx
@@ -76,6 +76,9 @@ constexpr sal_uInt16 XML_NAMESPACE_DSIG =            39;
 constexpr sal_uInt16 XML_NAMESPACE_DS =              40;
 constexpr sal_uInt16 XML_NAMESPACE_XADES132 =        41;
 constexpr sal_uInt16 XML_NAMESPACE_XADES141 =        42;
+// OOXML digital signature extension namespaces, also based on xmldsig-core
+constexpr sal_uInt16 XML_NAMESPACE_MDSSI =           43;
+constexpr sal_uInt16 XML_NAMESPACE_MSODIGSIG =       44;
 
 // namespaces for ODF extended formats
 constexpr sal_uInt16 XML_NAMESPACE_EXT_BASE   = 50;
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx
index a25872fc057d..149e323eb8f6 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx
@@ -11,32 +11,1241 @@
 #include "ooxmlsecparser.hxx"
 #include <xmlsignaturehelper.hxx>
 #include <xsecctl.hxx>
+
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlimp.hxx>
+
+#include <com/sun/star/xml/sax/SAXException.hpp>
+
 #include <sal/log.hxx>
 
-using namespace com::sun::star;
+using namespace com::sun::star;
+
+class OOXMLSecParser::Context
+{
+    protected:
+        friend class OOXMLSecParser;
+        OOXMLSecParser & m_rParser;
+    private:
+        std::unique_ptr<SvXMLNamespaceMap> m_pOldNamespaceMap;
+
+    public:
+        Context(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : m_rParser(rParser)
+            , m_pOldNamespaceMap(std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual ~Context() = default;
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/)
+        {
+        }
+
+        virtual void EndElement()
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/);
+
+        virtual void Characters(OUString const& /*rChars*/)
+        {
+        }
+};
+
+// it's possible that an unsupported element has an Id attribute and a
+// ds:Reference digesting it - probably this means XSecController needs to know
+// about it. (For known elements, the Id attribute is only processed according
+// to the schema.)
+class OOXMLSecParser::UnknownContext
+    : public OOXMLSecParser::Context
+{
+    public:
+        UnknownContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+};
+
+auto OOXMLSecParser::Context::CreateChildContext(
+    std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+    sal_uInt16 const /*nNamespace*/, OUString const& /*rName*/)
+-> std::unique_ptr<Context>
+{
+    // default: create new base context
+    return std::make_unique<UnknownContext>(m_rParser, std::move(pOldNamespaceMap));
+}
+
+/**
+note: anything in ds:Object should be trusted *only* if there is a ds:Reference
+      to it so it is signed (exception: the xades:EncapsulatedX509Certificate).
+      ds:SignedInfo precedes all ds:Object.
+
+      There may be multiple ds:Signature for purpose of counter-signatures
+      but the way XAdES describes these, only the ds:SignatureValue element
+      would be referenced, so requiring a ds:Reference for anything in
+      ds:Object shouldn't cause issues.
+ */
+class OOXMLSecParser::ReferencedContextImpl
+    : public OOXMLSecParser::Context
+{
+    protected:
+        bool m_isReferenced;
+
+    public:
+        ReferencedContextImpl(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_isReferenced(isReferenced)
+        {
+        }
+
+        OUString CheckIdAttrReferenced(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
+        {
+            OUString const id(m_rParser.HandleIdAttr(xAttrs));
+            if (!id.isEmpty() && m_rParser.m_pXSecController->haveReferenceForId(id))
+            {
+                m_isReferenced = true;
+            }
+            return id;
+        }
+};
+
+class OOXMLSecParser::DsX509CertificateContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        DsX509CertificateContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::DsX509SerialNumberContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        DsX509SerialNumberContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::DsX509IssuerNameContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        DsX509IssuerNameContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::DsX509IssuerSerialContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rX509IssuerName;
+        OUString & m_rX509SerialNumber;
+
+    public:
+        DsX509IssuerSerialContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rIssuerName, OUString & rSerialNumber)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rX509IssuerName(rIssuerName)
+            , m_rX509SerialNumber(rSerialNumber)
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerName")
+            {
+                return std::make_unique<DsX509IssuerNameContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509IssuerName);
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509SerialNumber")
+            {
+                return std::make_unique<DsX509SerialNumberContext>(m_rParser, std::move(pOldNamespaceMap), m_rX509SerialNumber);
+            }
+            // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+/// can't be sure what is supposed to happen here because the spec is clear as mud
+class OOXMLSecParser::DsX509DataContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        // sigh... "No ordering is implied by the above constraints."
+        // so store the ball of mud in vectors and try to figure it out later.
+        std::vector<std::pair<OUString, OUString>> m_X509IssuerSerials;
+        std::vector<OUString> m_X509Certificates;
+
+    public:
+        DsX509DataContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setX509Data(m_X509IssuerSerials, m_X509Certificates);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509IssuerSerial")
+            {
+                m_X509IssuerSerials.emplace_back();
+                return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerSerials.back().first, m_X509IssuerSerials.back().second);
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509Certificate")
+            {
+                m_X509Certificates.emplace_back();
+                return std::make_unique<DsX509CertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_X509Certificates.back());
+            }
+            // missing: ds:X509SKI, ds:X509SubjectName, ds:X509CRL
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsKeyInfoContext
+    : public OOXMLSecParser::Context
+{
+    public:
+        DsKeyInfoContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "X509Data")
+            {
+                return std::make_unique<DsX509DataContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            // missing: ds:PGPData
+            // missing: ds:KeyName, ds:KeyValue, ds:RetrievalMethod, ds:SPKIData, ds:MgmtData
+            // (old code would read ds:Transform inside ds:RetrievalMethod but
+            // presumably that was a bug)
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+
+};
+
+class OOXMLSecParser::DsSignatureValueContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString m_Value;
+
+    public:
+        DsSignatureValueContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setSignatureValue(m_Value);
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_Value += rChars;
+        }
+};
+
+class OOXMLSecParser::DsDigestValueContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        DsDigestValueContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& /*xAttrs*/) override
+        {
+            m_rValue.clear();
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::DsDigestMethodContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        sal_Int32 & m_rReferenceDigestID;
+
+    public:
+        DsDigestMethodContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                sal_Int32 & rReferenceDigestID)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rReferenceDigestID(rReferenceDigestID)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+
+            SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
+            if (!ouAlgorithm.isEmpty())
+            {
+                SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1
+                             && ouAlgorithm != ALGO_XMLDSIGSHA256
+                             && ouAlgorithm != ALGO_XMLDSIGSHA512,
+                             "xmlsecurity.helper", "Algorithm neither SHA1, SHA256 nor SHA512");
+                if (ouAlgorithm == ALGO_XMLDSIGSHA1)
+                    m_rReferenceDigestID = css::xml::crypto::DigestID::SHA1;
+                else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
+                    m_rReferenceDigestID = css::xml::crypto::DigestID::SHA256;
+                else if (ouAlgorithm == ALGO_XMLDSIGSHA512)
+                    m_rReferenceDigestID = css::xml::crypto::DigestID::SHA512;
+                else
+                    m_rReferenceDigestID = 0;
+            }
+        }
+};
+
+class OOXMLSecParser::DsTransformContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        bool & m_rIsC14N;
+
+    public:
+        DsTransformContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool & rIsC14N)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rIsC14N(rIsC14N)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            OUString aAlgorithm = xAttrs->getValueByName("Algorithm");
+
+            if (aAlgorithm == ALGO_RELATIONSHIP)
+            {
+                m_rIsC14N = true;
+            }
+        }
+};
+
+class OOXMLSecParser::DsTransformsContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        bool & m_rIsC14N;
+
+    public:
+        DsTransformsContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool & rIsC14N)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rIsC14N(rIsC14N)
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Transform")
+            {
+                return std::make_unique<DsTransformContext>(m_rParser, std::move(pOldNamespaceMap), m_rIsC14N);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsReferenceContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString m_URI;
+        OUString m_Type;
+        OUString m_DigestValue;
+        bool m_IsC14N = false;
+        // Relevant for ODF. The digest algorithm selected by the DigestMethod
+        // element's Algorithm attribute. @see css::xml::crypto::DigestID.
+        sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA256;
+
+    public:
+        DsReferenceContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+
+            m_URI = xAttrs->getValueByName("URI");
+            SAL_WARN_IF(m_URI.isEmpty(), "xmlsecurity.helper", "URI is empty");
+            // Remember the type of this reference.
+            m_Type = xAttrs->getValueByName("Type");
+        }
+
+        virtual void EndElement() override
+        {
+            if (m_URI.startsWith("#"))
+            {
+                /*
+                * remove the first character '#' from the attribute value
+                */
+                m_rParser.m_pXSecController->addReference(m_URI.copy(1), m_nReferenceDigestID, m_Type);
+            }
+            else
+            {
+                if (m_IsC14N) // this is determined by nested ds:Transform
+                {
+                    m_rParser.m_pXSecController->addStreamReference(m_URI, false, m_nReferenceDigestID);
+                }
+                else
+            /*
+            * it must be an octet stream
+            */
+                {
+                    m_rParser.m_pXSecController->addStreamReference(m_URI, true, m_nReferenceDigestID);
+                }
+            }
+
+            m_rParser.m_pXSecController->setDigestValue(m_nReferenceDigestID, m_DigestValue);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Transforms")
+            {
+                return std::make_unique<DsTransformsContext>(m_rParser, std::move(pOldNamespaceMap), m_IsC14N);
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+            {
+                return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_nReferenceDigestID);
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+            {
+                return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_DigestValue);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsSignatureMethodContext
+    : public OOXMLSecParser::Context
+{
+    public:
+        DsSignatureMethodContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            OUString ouAlgorithm = xAttrs->getValueByName("Algorithm");
+            if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
+                || ouAlgorithm == ALGO_ECDSASHA512)
+            {
+                m_rParser.m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
+            }
+        }
+};
+
+class OOXMLSecParser::DsSignedInfoContext
+    : public OOXMLSecParser::Context
+{
+    public:
+        DsSignedInfoContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            m_rParser.HandleIdAttr(xAttrs);
+        }
+
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setReferenceCount();
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureMethod")
+            {
+                return std::make_unique<DsSignatureMethodContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
+            {
+                return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            // missing: ds:CanonicalizationMethod
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::XadesCertDigestContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rDigestValue;
+        sal_Int32 & m_rReferenceDigestID;
+
+    public:
+        XadesCertDigestContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rDigestValue, sal_Int32 & rReferenceDigestID)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rDigestValue(rDigestValue)
+            , m_rReferenceDigestID(rReferenceDigestID)
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestMethod")
+            {
+                return std::make_unique<DsDigestMethodContext>(m_rParser, std::move(pOldNamespaceMap), m_rReferenceDigestID);
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "DigestValue")
+            {
+                return std::make_unique<DsDigestValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rDigestValue);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::XadesCertContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    private:
+        sal_Int32 m_nReferenceDigestID = css::xml::crypto::DigestID::SHA1;
+        OUString m_CertDigest;
+        OUString m_X509IssuerName;
+        OUString m_X509SerialNumber;
+
+    public:
+        XadesCertContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void EndElement() override
+        {
+            if (m_isReferenced)
+            {
+                m_rParser.m_pXSecController->setX509CertDigest(m_CertDigest, m_nReferenceDigestID, m_X509IssuerName, m_X509SerialNumber);
+            }
+            else
+            {
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned xades:Cert");
+            }
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "CertDigest")
+            {
+                return std::make_unique<XadesCertDigestContext>(m_rParser, std::move(pOldNamespaceMap), m_CertDigest, m_nReferenceDigestID);
+            }
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "IssuerSerial")
+            {
+                return std::make_unique<DsX509IssuerSerialContext>(m_rParser, std::move(pOldNamespaceMap), m_X509IssuerName, m_X509SerialNumber);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::XadesSigningCertificateContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    public:
+        XadesSigningCertificateContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "Cert")
+            {
+                return std::make_unique<XadesCertContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::XadesSigningTimeContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    private:
+        OUString m_Value;
+
+    public:
+        XadesSigningTimeContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void EndElement() override
+        {
+            if (m_isReferenced)
+            {
+                m_rParser.m_pXSecController->setDate("", m_Value);
+            }
+            else
+            {
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned SigningTime");
+            }
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_Value += rChars;
+        }
+};
+
+class OOXMLSecParser::XadesSignedSignaturePropertiesContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    public:
+        XadesSignedSignaturePropertiesContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            CheckIdAttrReferenced(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningTime")
+            {
+                return std::make_unique<XadesSigningTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SigningCertificate")
+            {
+                return std::make_unique<XadesSigningCertificateContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            // missing: xades:SignaturePolicyIdentifier, xades:SignatureProductionPlace, xades:SignerRole
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::XadesSignedPropertiesContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    public:
+        XadesSignedPropertiesContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            CheckIdAttrReferenced(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedSignatureProperties")
+            {
+                return std::make_unique<XadesSignedSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            // missing: xades:SignedDataObjectProperties
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::XadesQualifyingPropertiesContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    public:
+        XadesQualifyingPropertiesContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            CheckIdAttrReferenced(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "SignedProperties")
+            {
+                return std::make_unique<XadesSignedPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            // missing: xades:UnsignedSignatureProperties
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::MsodigsigSetupIDContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        MsodigsigSetupIDContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::MsodigsigSignatureCommentsContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        MsodigsigSignatureCommentsContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::MsodigsigSignatureInfoV1Context
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    private:
+        OUString m_SetupID;
+        OUString m_SignatureComments;
+
+    public:
+        MsodigsigSignatureInfoV1Context(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            CheckIdAttrReferenced(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SetupID")
+            {
+                return std::make_unique<MsodigsigSetupIDContext>(m_rParser, std::move(pOldNamespaceMap), m_SetupID);
+            }
+            if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SignatureComments")
+            {
+                return std::make_unique<MsodigsigSignatureCommentsContext>(m_rParser, std::move(pOldNamespaceMap), m_SignatureComments);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+
+        virtual void EndElement() override
+        {
+            if (m_isReferenced)
+            {
+                if (!m_SetupID.isEmpty())
+                {
+                    m_rParser.m_pXSecController->setSignatureLineId(m_SetupID);
+                }
+                if (!m_SignatureComments.isEmpty())
+                {
+                    m_rParser.m_pXSecController->setDescription("", m_SignatureComments);
+
+                }
+            }
+            else
+            {
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureInfoV1");
+            }
+        }
+};
+
+class OOXMLSecParser::MdssiValueContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        MdssiValueContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_rValue += rChars;
+        }
+};
+
+class OOXMLSecParser::MdssiSignatureTimeContext
+    : public OOXMLSecParser::Context
+{
+    private:
+        OUString & m_rValue;
+
+    public:
+        MdssiSignatureTimeContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                OUString & rValue)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+            , m_rValue(rValue)
+        {
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_MDSSI && rName == "Value")
+            {
+                return std::make_unique<MdssiValueContext>(m_rParser, std::move(pOldNamespaceMap), m_rValue);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+
+class OOXMLSecParser::DsSignaturePropertyContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    private:
+        enum class SignatureProperty { Unknown, Date, Info };
+        SignatureProperty m_Property = SignatureProperty::Unknown;
+        OUString m_Id;
+        OUString m_Value;
+
+    public:
+        DsSignaturePropertyContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            m_Id = CheckIdAttrReferenced(xAttrs);
+        }
+
+        virtual void EndElement() override
+        {
+            if (m_isReferenced)
+            {
+                switch (m_Property)
+                {
+                    case SignatureProperty::Unknown:
+                        SAL_INFO("xmlsecurity.helper", "Unknown property in ds:Object ignored");
+                        break;
+                    case SignatureProperty::Info:
+                        break; // handled by child context
+                    case SignatureProperty::Date:
+                        m_rParser.m_pXSecController->setDate(m_Id, m_Value);
+                        break;
+                }
+            }
+            else
+            {
+                SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureProperty");
+            }
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_MDSSI && rName == "SignatureTime")
+            {
+                m_Property = SignatureProperty::Date;
+                return std::make_unique<MdssiSignatureTimeContext>(m_rParser, std::move(pOldNamespaceMap), m_Value);
+            }
+            if (nNamespace == XML_NAMESPACE_MSODIGSIG && rName == "SignatureInfoV1")
+            {
+                return std::make_unique<MsodigsigSignatureInfoV1Context>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsSignaturePropertiesContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    public:
+        DsSignaturePropertiesContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            CheckIdAttrReferenced(xAttrs);
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperty")
+            {
+                return std::make_unique<DsSignaturePropertyContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsManifestContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+    public:
+        DsManifestContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+                bool const isReferenced)
+            : ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), isReferenced)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            CheckIdAttrReferenced(xAttrs);
+        }
+
+#if 0
+        ???
+        virtual void EndElement() override
+        {
+            m_rParser.m_pXSecController->setReferenceCount();
+        }
+#endif
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Reference")
+            {
+                return std::make_unique<DsReferenceContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            // missing: ds:CanonicalizationMethod
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsObjectContext
+    : public OOXMLSecParser::ReferencedContextImpl
+{
+        enum class Mode { Default, ValidSignatureLineImage, InvalidSignatureLineImage };
+        Mode m_Mode = Mode::Default;
+        OUString m_Value;
+
+    public:
+        DsObjectContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            // init with "false" here - the Signature element can't be referenced by its child
+            : OOXMLSecParser::ReferencedContextImpl(rParser, std::move(pOldNamespaceMap), false)
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            OUString const id(CheckIdAttrReferenced(xAttrs));
+            if (id == "idValidSigLnImg")
+            {
+                m_Mode = Mode::ValidSignatureLineImage;
+            }
+            else if (id == "idInvalidSigLnImg")
+            {
+                m_Mode = Mode::InvalidSignatureLineImage;
+            }
+        }
+
+        virtual void EndElement() override
+        {
+            switch (m_Mode)
+            {
+                case Mode::ValidSignatureLineImage:
+                    if (m_isReferenced)
+                    {
+                        m_rParser.m_pXSecController->setValidSignatureImage(m_Value);
+                    }
+                    else
+                    {
+                        SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineValidImage");
+                    }
+                    break;
+                case Mode::InvalidSignatureLineImage:
+                    if (m_isReferenced)
+                    {
+                        m_rParser.m_pXSecController->setInvalidSignatureImage(m_Value);
+                    }
+                    else
+                    {
+                        SAL_INFO("xmlsecurity.helper", "ignoring unsigned SignatureLineInvalidImage");
+                    }
+                    break;
+                case Mode::Default:
+                    break;
+            }
+        }
+
+        virtual void Characters(OUString const& rChars) override
+        {
+            m_Value += rChars;
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureProperties")
+            {
+                return std::make_unique<DsSignaturePropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            if (nNamespace == XML_NAMESPACE_XADES132 && rName == "QualifyingProperties")
+            {
+                return std::make_unique<XadesQualifyingPropertiesContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Manifest")
+            {
+                return std::make_unique<DsManifestContext>(m_rParser, std::move(pOldNamespaceMap), m_isReferenced);
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
+class OOXMLSecParser::DsSignatureContext
+    : public OOXMLSecParser::Context
+{
+    public:
+        DsSignatureContext(OOXMLSecParser & rParser,
+                std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap)
+            : OOXMLSecParser::Context(rParser, std::move(pOldNamespaceMap))
+        {
+        }
+
+        virtual void StartElement(
+            css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs) override
+        {
+            OUString const ouIdAttr(m_rParser.HandleIdAttr(xAttrs));
+            m_rParser.m_rXMLSignatureHelper.StartVerifySignatureElement();
+            m_rParser.m_pXSecController->addSignature();
+            if (!ouIdAttr.isEmpty())
+            {
+                m_rParser.m_pXSecController->setId( ouIdAttr );
+            }
+        }
+
+        virtual std::unique_ptr<Context> CreateChildContext(
+            std::unique_ptr<SvXMLNamespaceMap> pOldNamespaceMap,
+            sal_uInt16 const nNamespace, OUString const& rName) override
+        {
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignedInfo")
+            {
+                return std::make_unique<DsSignedInfoContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "SignatureValue")
+            {
+                return std::make_unique<DsSignatureValueContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "KeyInfo")
+            {
+                return std::make_unique<DsKeyInfoContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            if (nNamespace == XML_NAMESPACE_DS && rName == "Object")
+            {
+                return std::make_unique<DsObjectContext>(m_rParser, std::move(pOldNamespaceMap));
+            }
+            return OOXMLSecParser::Context::CreateChildContext(std::move(pOldNamespaceMap), nNamespace, rName);
+        }
+};
+
 
 OOXMLSecParser::OOXMLSecParser(XMLSignatureHelper& rXMLSignatureHelper, XSecController* pXSecController)
-    : m_pXSecController(pXSecController)
-    ,m_bInDigestValue(false)
-    ,m_bInSignatureValue(false)
-    ,m_bInX509Certificate(false)
-    ,m_bInMdssiValue(false)
-    ,m_bInSignatureComments(false)
-    ,m_bInX509IssuerName(false)
-    ,m_bInX509SerialNumber(false)
-    ,m_bInCertDigest(false)
-    ,m_bInValidSignatureImage(false)
-    ,m_bInInvalidSignatureImage(false)
-    ,m_bInSignatureLineId(false)
-    ,m_bReferenceUnresolved(false)
+    : m_pNamespaceMap(new SvXMLNamespaceMap)
+    , m_pXSecController(pXSecController)
     ,m_rXMLSignatureHelper(rXMLSignatureHelper)
 {
+    using namespace xmloff::token;
+    m_pNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
+    m_pNamespaceMap->Add( "_ds", GetXMLToken(XML_N_DS), XML_NAMESPACE_DS );
+    m_pNamespaceMap->Add( "_xades132", GetXMLToken(XML_N_XADES132), XML_NAMESPACE_XADES132);
+    m_pNamespaceMap->Add( "_xades141", GetXMLToken(XML_N_XADES141), XML_NAMESPACE_XADES141);
+    m_pNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
+    m_pNamespaceMap->Add( "_mdssi", NS_MDSSI, XML_NAMESPACE_MDSSI );
+    m_pNamespaceMap->Add( "_msodigsig", "http://schemas.microsoft.com/office/2006/digsig", XML_NAMESPACE_MSODIGSIG );
+    m_pNamespaceMap->Add( "_office_libo",
+                         GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
 }
 
 OOXMLSecParser::~OOXMLSecParser()
 {
 }
 
+OUString OOXMLSecParser::HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs)
+{
+    OUString const aId = xAttrs->getValueByName("Id");
+    if (!aId.isEmpty())
+    {
+        m_pXSecController->collectToVerify(aId);
+    }
+    return aId;
+}
+
 void SAL_CALL OOXMLSecParser::startDocument()
 {
     if (m_xNextHandler.is())
@@ -51,231 +1260,69 @@ void SAL_CALL OOXMLSecParser::endDocument()
 
 void SAL_CALL OOXMLSecParser::startElement(const OUString& rName, const uno::Reference<xml::sax::XAttributeList>& xAttribs)
 {
-    OUString aId = xAttribs->getValueByName("Id");
-    if (!aId.isEmpty())
-        m_pXSecController->collectToVerify(aId);
+    assert(m_pNamespaceMap);
+    std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
+        SvXMLImport::processNSAttributes(m_pNamespaceMap, nullptr, xAttribs));
 
-    if (rName == "Signature")
-    {
-        m_rXMLSignatureHelper.StartVerifySignatureElement();
-        m_pXSecController->addSignature();
-        if (!aId.isEmpty())
-            m_pXSecController->setId(aId);
-    }
-    else if (rName == "SignatureMethod")
-    {
-        OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
-        if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256
-            || ouAlgorithm == ALGO_ECDSASHA512)
-            m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA);
-    }
-    else if (rName == "Reference")
-    {
-        OUString aURI = xAttribs->getValueByName("URI");
-        if (aURI.startsWith("#"))
-            m_pXSecController->addReference(aURI.copy(1), xml::crypto::DigestID::SHA1, OUString());
-        else
-        {
-            m_aReferenceURI = aURI;
-            m_bReferenceUnresolved = true;
-        }
-    }
-    else if (rName == "Transform")
-    {
-        if (m_bReferenceUnresolved)
-        {
-            OUString aAlgorithm = xAttribs->getValueByName("Algorithm");
-            if (aAlgorithm == ALGO_RELATIONSHIP)
-            {
-                m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/false, /*nDigestID=*/xml::crypto::DigestID::SHA256);
-                m_bReferenceUnresolved = false;
-            }
-        }
-    }
-    else if (rName == "DigestValue" && !m_bInCertDigest)
-    {
-        m_aDigestValue.clear();
-        m_bInDigestValue = true;
-    }
-    else if (rName == "SignatureValue")
-    {
-        m_aSignatureValue.clear();
-        m_bInSignatureValue = true;
-    }
-    else if (rName == "X509Certificate")
-    {
-        m_aX509Certificate.clear();
-        m_bInX509Certificate = true;
-    }
-    else if (rName == "mdssi:Value")
-    {
-        m_aMdssiValue.clear();
-        m_bInMdssiValue = true;
-    }
-    else if (rName == "SignatureComments")
-    {
-        m_aSignatureComments.clear();
-        m_bInSignatureComments = true;
-    }
-    else if (rName == "X509IssuerName")
-    {
-        m_aX509IssuerName.clear();
-        m_bInX509IssuerName = true;
-    }
-    else if (rName == "X509SerialNumber")
-    {
-        m_aX509SerialNumber.clear();
-        m_bInX509SerialNumber = true;
-    }
-    else if (rName == "xd:CertDigest")
-    {
-        m_aCertDigest.clear();
-        m_bInCertDigest = true;
-    }
-    else if (rName == "Object")
+    OUString localName;
+    sal_uInt16 const nPrefix(m_pNamespaceMap->GetKeyByAttrName(rName, &localName));
+
+    std::unique_ptr<Context> pContext;
+
+    if (m_ContextStack.empty())
     {
-        OUString sId = xAttribs->getValueByName("Id");
-        if (sId == "idValidSigLnImg")
-        {
-            m_aValidSignatureImage.clear();
-            m_bInValidSignatureImage = true;
-        }
-        else if (sId == "idInvalidSigLnImg")
+        if (nPrefix == XML_NAMESPACE_DS
+            && localName == "Signature")
         {
-            m_aInvalidSignatureImage.clear();
-            m_bInInvalidSignatureImage = true;
+            pContext.reset(new DsSignatureContext(*this, std::move(pRewindMap)));
         }
         else
         {
-            SAL_INFO("xmlsecurity.ooxml", "Unknown 'Object' child element: " << rName);
+            throw css::xml::sax::SAXException(
+                "xmlsecurity: unexpected root element", nullptr,
+                css::uno::Any());
         }
     }
-    else if (rName == "SetupID")
-    {
-        m_aSignatureLineId.clear();
-        m_bInSignatureLineId = true;
-    }
     else
     {
-        SAL_INFO("xmlsecurity.ooxml", "Unknown xml element: " << rName);
+        pContext = m_ContextStack.top()->CreateChildContext(
+                std::move(pRewindMap), nPrefix, localName);
     }
 
+    m_ContextStack.push(std::move(pContext));
+    assert(!pRewindMap);
+
+    m_ContextStack.top()->StartElement(xAttribs);
+
     if (m_xNextHandler.is())
+    {
         m_xNextHandler->startElement(rName, xAttribs);
+    }
+
 }
 
 void SAL_CALL OOXMLSecParser::endElement(const OUString& rName)
 {
-    if (rName == "SignedInfo")
-        m_pXSecController->setReferenceCount();
-    else if (rName == "Reference")
-    {
-        if (m_bReferenceUnresolved)
-        {
-            // No transform algorithm found, assume binary.
-            m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/true, /*nDigestID=*/xml::crypto::DigestID::SHA256);
-            m_bReferenceUnresolved = false;
-        }
-        m_pXSecController->setDigestValue(xml::crypto::DigestID::SHA256, m_aDigestValue);
-    }
-    else if (rName == "DigestValue" && !m_bInCertDigest)
-        m_bInDigestValue = false;
-    else if (rName == "SignatureValue")
-    {
-        m_pXSecController->setSignatureValue(m_aSignatureValue);
-        m_bInSignatureValue = false;
-    }
-    else if (rName == "X509Data")
-    {
-        std::vector<std::pair<OUString, OUString>> X509IssuerSerials;
-        std::vector<OUString> X509Certificates;
-        if (!m_aX509Certificate.isEmpty())
-        {
-            X509Certificates.emplace_back(m_aX509Certificate);
-        }
-        if (!m_aX509IssuerName.isEmpty() && !m_aX509SerialNumber.isEmpty())
-        {
-            X509IssuerSerials.emplace_back(m_aX509IssuerName, m_aX509SerialNumber);
-        }
-        m_pXSecController->setX509Data(X509IssuerSerials, X509Certificates);
-    }
-    else if (rName == "X509Certificate")
-    {
-        m_bInX509Certificate = false;
-    }
-    else if (rName == "mdssi:Value")
-    {
-        m_pXSecController->setDate("", m_aMdssiValue);
-        m_bInMdssiValue = false;
-    }
-    else if (rName == "SignatureComments")
-    {
-        m_pXSecController->setDescription("", m_aSignatureComments);
-        m_bInSignatureComments = false;
-    }
-    else if (rName == "X509IssuerName")
-    {
-        m_bInX509IssuerName = false;
-    }
-    else if (rName == "X509SerialNumber")
-    {
-        m_bInX509SerialNumber = false;
-    }
-    else if (rName == "xd:Cert")
-    {
-        m_pXSecController->setX509CertDigest(m_aCertDigest, css::xml::crypto::DigestID::SHA1, m_aX509IssuerName, m_aX509SerialNumber);
-    }
-    else if (rName == "xd:CertDigest")
-    {
-        m_bInCertDigest = false;
-    }
-    else if (rName == "Object")
+    assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+
+    m_ContextStack.top()->EndElement();
+
+    if (m_xNextHandler.is())
     {
-        if (m_bInValidSignatureImage)
-        {
-            m_pXSecController->setValidSignatureImage(m_aValidSignatureImage);
-            m_bInValidSignatureImage = false;
-        }
-        else if (m_bInInvalidSignatureImage)
-        {
-            m_pXSecController->setInvalidSignatureImage(m_aInvalidSignatureImage);
-            m_bInInvalidSignatureImage = false;
-        }
+        m_xNextHandler->endElement(rName);
     }
-    else if (rName == "SetupID")
+
+    if (m_ContextStack.top()->m_pOldNamespaceMap)
     {
-        m_pXSecController->setSignatureLineId(m_aSignatureLineId);
-        m_bInSignatureLineId = false;
+        m_pNamespaceMap = std::move(m_ContextStack.top()->m_pOldNamespaceMap);
     }
-
-    if (m_xNextHandler.is())
-        m_xNextHandler->endElement(rName);
+    m_ContextStack.pop();
 }
 
 void SAL_CALL OOXMLSecParser::characters(const OUString& rChars)
 {
-    if (m_bInDigestValue && !m_bInCertDigest)
-        m_aDigestValue += rChars;
-    else if (m_bInSignatureValue)
-        m_aSignatureValue += rChars;
-    else if (m_bInX509Certificate)
-        m_aX509Certificate += rChars;
-    else if (m_bInMdssiValue)
-        m_aMdssiValue += rChars;
-    else if (m_bInSignatureComments)
-        m_aSignatureComments += rChars;
-    else if (m_bInX509IssuerName)
-        m_aX509IssuerName += rChars;
-    else if (m_bInX509SerialNumber)
-        m_aX509SerialNumber += rChars;
-    else if (m_bInCertDigest)
-        m_aCertDigest += rChars;
-    else if (m_bInValidSignatureImage)
-        m_aValidSignatureImage += rChars;
-    else if (m_bInInvalidSignatureImage)
-        m_aInvalidSignatureImage += rChars;
-    else if (m_bInSignatureLineId)
-        m_aSignatureLineId += rChars;
+    assert(!m_ContextStack.empty()); // this should be checked by sax parser?
+    m_ContextStack.top()->Characters(rChars);
 
     if (m_xNextHandler.is())
         m_xNextHandler->characters(rChars);
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.hxx b/xmlsecurity/source/helper/ooxmlsecparser.hxx
index d3c199147255..ba0e274be6af 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.hxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.hxx
@@ -15,6 +15,10 @@
 
 #include <cppuhelper/implbase.hxx>
 
+#include <xmloff/namespacemap.hxx>
+
+#include <stack>
+
 class XSecController;
 class XMLSignatureHelper;
 
@@ -25,38 +29,62 @@ class OOXMLSecParser: public cppu::WeakImplHelper
     css::lang::XInitialization
     >
 {
+public:
+    class Context;
+private:
+    class UnknownContext;
+    class ReferencedContextImpl;
+    class DsX509CertificateContext;
+    class DsX509SerialNumberContext;
+    class DsX509IssuerNameContext;
+    class DsX509IssuerSerialContext;
+    class DsX509DataContext;
+    class DsKeyInfoContext;
+    class DsSignatureValueContext;
+    class DsDigestValueContext;
+    class DsDigestMethodContext;
+    class DsTransformContext;
+    class DsTransformsContext;
+    class DsReferenceContext;
+    class DsSignatureMethodContext;
+    class DsSignedInfoContext;
+    class XadesEncapsulatedX509CertificateContext;
+    class XadesCertificateValuesContext;
+    class XadesUnsignedSignaturePropertiesContext;
+    class XadesUnsignedPropertiesContext;
+    class XadesCertDigestContext;
+    class XadesCertContext;
+    class XadesSigningCertificateContext;
+    class XadesSigningTimeContext;
+    class XadesSignedSignaturePropertiesContext;
+    class XadesSignedPropertiesContext;
+    class XadesQualifyingPropertiesContext;
+    class MdssiValueContext;
+    class MdssiSignatureTimeContext;
+    class MsodigsigSetupIDContext;
+    class MsodigsigSignatureCommentsContext;
+    class MsodigsigSignatureInfoV1Context;
+    class DsSignaturePropertyContext;
+    class DsSignaturePropertiesContext;
+    class DsManifestContext;
+    class DsObjectContext;
+    class DsSignatureContext;
+    class DsigSignaturesContext;
+
+    std::stack<std::unique_ptr<Context>> m_ContextStack;
+    std::unique_ptr<SvXMLNamespaceMap> m_pNamespaceMap;
+
     XSecController* m_pXSecController;
     css::uno::Reference<css::xml::sax::XDocumentHandler> m_xNextHandler;
 
-    bool m_bInDigestValue;
-    OUString m_aDigestValue;
-    bool m_bInSignatureValue;
-    OUString m_aSignatureValue;
-    bool m_bInX509Certificate;
-    OUString m_aX509Certificate;
-    bool m_bInMdssiValue;
-    OUString m_aMdssiValue;
-    bool m_bInSignatureComments;
-    OUString m_aSignatureComments;
-    bool m_bInX509IssuerName;
-    OUString m_aX509IssuerName;
-    bool m_bInX509SerialNumber;
-    OUString m_aX509SerialNumber;
-    bool m_bInCertDigest;
-    OUString m_aCertDigest;
-    bool m_bInValidSignatureImage;
-    OUString m_aValidSignatureImage;
-    bool m_bInInvalidSignatureImage;
-    OUString m_aInvalidSignatureImage;
-    bool m_bInSignatureLineId;
-    OUString m_aSignatureLineId;
-
     /// Last seen <Reference URI="...">.
     OUString m_aReferenceURI;
     /// Already called addStreamReference() for this reference.
     bool m_bReferenceUnresolved;
     XMLSignatureHelper& m_rXMLSignatureHelper;
 
+    OUString HandleIdAttr(css::uno::Reference<css::xml::sax::XAttributeList> const& xAttrs);
+
 public:
     explicit OOXMLSecParser(XMLSignatureHelper& rXMLSignatureHelper, XSecController* pXSecController);
     virtual ~OOXMLSecParser() override;
commit fcdda95bfff8c9f8cdfe3878e203ae48f6f93607
Author:     Attila Bakos (NISZ) <bakos.attilakaroly at nisz.hu>
AuthorDate: Tue Mar 9 16:32:27 2021 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Thu Apr 1 10:07:25 2021 +0200

    tdf#140828 sw textbox: fix AS_CHAR regression
    
    Textboxes anchored as characters don't lose
    their text frames after changing the anchor
    "To character".
    
    Regression from commit 493a916a3113e877835c9bc7c93faef0d29f9a33
    (tdf#140158 tdf#138598 tdf#140598 sw: fix sync of AS_CHAR textboxes).
    
    Change-Id: I0e6d88c9dcdeff515744bc4c201a5640eb810d1b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112209
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>
    Signed-off-by: Xisco Fauli <xiscofauli at libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113321
    Tested-by: Jenkins
    Reviewed-by: Attila Bakos <bakos.attilakaroly at nisz.hu>

diff --git a/sw/qa/extras/uiwriter/data3/tdf140828.docx b/sw/qa/extras/uiwriter/data3/tdf140828.docx
new file mode 100755
index 000000000000..bfdabc5d77ea
Binary files /dev/null and b/sw/qa/extras/uiwriter/data3/tdf140828.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 71d742bf4359..f0444d3f3c7a 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -14,6 +14,7 @@
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <IDocumentDrawModelAccess.hxx>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/XTextFrame.hpp>
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
@@ -854,6 +855,37 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf76636_2)
     CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getColumns()->getCount());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf140828)
+{
+    load(DATA_DIRECTORY, "tdf140828.docx");
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    CPPUNIT_ASSERT_EQUAL(1, getShapes());
+    uno::Reference<drawing::XShape> xShp = getShape(1);
+    CPPUNIT_ASSERT(xShp);
+
+    uno::Reference<beans::XPropertySet> ShpProps(xShp, uno::UNO_QUERY_THROW);
+    dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {});
+    Scheduler::ProcessEventsToIdle();
+
+    dispatchCommand(mxComponent, ".uno:SetAnchorAtChar", {});
+    Scheduler::ProcessEventsToIdle();
+
+    CPPUNIT_ASSERT(ShpProps->getPropertyValue("AnchorType").get<text::TextContentAnchorType>()
+                   != text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER);
+
+    uno::Reference<text::XTextFrame> xTxBx(SwTextBoxHelper::getUnoTextFrame(xShp));
+    CPPUNIT_ASSERT(xTxBx);
+
+    uno::Reference<beans::XPropertySet> TxBxProps(xTxBx, uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(OUString("top left image"), xTxBx->getText()->getString());
+
+    CPPUNIT_ASSERT_MESSAGE("Bad Relative Orientation and Position!",
+                           TxBxProps->getPropertyValue("HoriOrientRelation").get<sal_Int16>()
+                               != text::RelOrientation::CHAR);
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132725)
 {
     load(DATA_DIRECTORY, "tdf132725.odt");
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index 5257d448bd55..6b9f87655d8d 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -165,8 +165,6 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape, bool bCopyText)
     if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
         syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)));
 
-    // TODO: Text dialog attr setting to frame
-
     const SwFormatAnchor& rAnch = pShape->GetAnchor();
     if (!((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && rAnch.GetPageNum() != 0)
           || ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA
@@ -723,6 +721,9 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
                     }
                     else // Otherwise copy the anchor type of the shape
                     {
+                        // tdf#140828: Do not keep CHAR rel-orientation:
+                        xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
+                                                       uno::Any(text::RelOrientation::FRAME));
                         xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
                     }
                     // After anchoring the position must be set as well:
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index cafa70c48227..9426359156f1 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -351,9 +351,11 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase,
             // Both rectangles are absolute, SwFormatHori/VertOrient's position
             // is relative to the print area of the anchor text frame.
             tools::Rectangle aTextRectangle = SwTextBoxHelper::getTextRectangle(pShape);
+            tools::Long nXoffs  = SwTextBoxHelper::getTextRectangle(pShape, false).getX();
 
             const auto aPos(pShape->GetAnchor().GetContentAnchor());
             SwFormatVertOrient aVert(pTextBox->GetVertOrient());
+            SwFormatHoriOrient aHori(pTextBox->GetHoriOrient());
 
             // tdf#138598 Replace vertical alignment of As_char textboxes in footer
             // tdf#140158 Remove horizontal positioning of As_char textboxes, because
@@ -373,10 +375,12 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase,
 
             SwFormatAnchor aNewTxBxAnchor(pTextBox->GetAnchor());
             aNewTxBxAnchor.SetAnchor(aPos);
+            aHori.SetPos(nXoffs);
 
             pTextBox->LockModify();
             pTextBox->SetFormatAttr(aNewTxBxAnchor);
             pTextBox->SetFormatAttr(aVert);
+            pTextBox->SetFormatAttr(aHori);
             pTextBox->UnlockModify();
         }
     }
commit ec693c088dd51fcf86dcf48de66d4ead0f6dcdbc
Author:     Christian Lohmaier <lohmaier+LibreOffice at googlemail.com>
AuthorDate: Mon Mar 29 15:55:45 2021 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Thu Apr 1 10:07:20 2021 +0200

    python3-ify hrcex & uiex (creation of pot files)
    
    Change-Id: I824c9ed536a1e852d6bd157fbd7d4766327b7bcd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113319
    Tested-by: Jenkins
    Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice at googlemail.com>
    (cherry picked from commit 9dfd55dffc4cca6617b4ee67be9a8bfe96601c00)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113353
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/solenv/bin/hrcex b/solenv/bin/hrcex
index 54cef2626a19..0645f79fcb37 100755
--- a/solenv/bin/hrcex
+++ b/solenv/bin/hrcex
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 
 import polib
 import binascii
@@ -22,17 +22,18 @@ for o, a in myopts:
         ofile = a
 
 with open(ofile, "a") as output:
-    xgettext = Popen(["xgettext", "-C", "--add-comments", "--keyword=NC_:1c,2", "--keyword=NNC_:1c,2,3", "--from-code=UTF-8", "--no-wrap", ifile, "-o", "-"], stdout=PIPE)
+    xgettext = Popen(["xgettext", "-C", "--add-comments", "--keyword=NC_:1c,2", "--keyword=NNC_:1c,2,3", "--from-code=UTF-8", "--no-wrap", ifile, "-o", "-"], stdout=PIPE, encoding="UTF-8")
     # while overall format is c++, all of the strings use custom placeholders and don't follow c-format
     # esp. plain percent sign never is escaped explicitly
-    input = check_output(['sed', '-e', '/^#, c-format$/d'], stdin=xgettext.stdout)
+    input = check_output(['sed', '-e', '/^#, c-format$/d'], stdin=xgettext.stdout, encoding="UTF-8")
     xgettext.wait()
+    xgettext.stdout.close()
     po = polib.pofile(input)
     if len(po) != 0:
-        print >> output, ""
+        print("", file=output)
         for entry in po:
             keyid = entry.msgctxt + '|' + entry.msgid
-            print >> output, '#. ' + polib.genKeyId(keyid)
+            print('#. ' + polib.genKeyId(keyid), file=output)
             for i, occurrence in enumerate(entry.occurrences):
                 entry.occurrences[i] = os.path.relpath(occurrence[0], os.environ['SRCDIR']), occurrence[1]
-            print >> output, entry
+            print(entry, file=output)
diff --git a/solenv/bin/polib.py b/solenv/bin/polib.py
index 5ab421365376..092e7dfdb8b3 100644
--- a/solenv/bin/polib.py
+++ b/solenv/bin/polib.py
@@ -1858,7 +1858,7 @@ def wrap(text, width=70, **kwargs):
 # }}}
 
 def genKeyId(inkey):
-    crc = binascii.crc32(bytes(inkey)) & 0xffffffff
+    crc = binascii.crc32(bytes(inkey, encoding="UTF-8")) & 0xffffffff
     # Use simple ASCII characters, exclude I, l, 1 and O, 0 to avoid confusing IDs
     symbols = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";
     outkey = ""
diff --git a/solenv/bin/uiex b/solenv/bin/uiex
index c9b00b2e062c..1f5faead4575 100755
--- a/solenv/bin/uiex
+++ b/solenv/bin/uiex
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 
 import polib
 import binascii
@@ -22,13 +22,13 @@ for o, a in myopts:
         ofile = a
 
 with open(ofile, "a") as output:
-    input = check_output(["xgettext", "--add-comments", "--no-wrap", ifile, "-o", "-"])
+    input = check_output(["xgettext", "--add-comments", "--no-wrap", ifile, "-o", "-"], encoding="UTF-8")
     po = polib.pofile(input)
     if len(po) != 0:
-        print >> output, ""
+        print("", file=output)
         for entry in po:
             keyid = entry.msgctxt + '|' + entry.msgid
-            print >> output, '#. ' + polib.genKeyId(keyid)
+            print('#. ' + polib.genKeyId(keyid), file=output)
             for i, occurrence in enumerate(entry.occurrences):
                 entry.occurrences[i] = os.path.relpath(occurrence[0], os.environ['SRCDIR']), occurrence[1]
-            print >> output, entry
+            print(entry, file=output)


More information about the Libreoffice-commits mailing list