tdf#135942: avoid collecting autostyles during writing them

This modifies the container over which iteration is performed.
Additionally, make sure that all nested table autostyles are
collected on the first phase.

Change-Id: I74c0bb1aaacad095226c21e6bf51cc8668133bb3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101096
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx
index 5c09d2a..50e6599 100644
--- a/include/xmloff/txtparae.hxx
+++ b/include/xmloff/txtparae.hxx
@@ -365,6 +365,8 @@ protected:
        const css::uno::Reference< css::beans::XPropertySet> & i_xPortion,
        bool i_bAutoStyles, bool i_isProgress, bool & rPrevCharIsSpace);

    bool isAutoStylesCollected() const { return mbCollected; }

    virtual void exportTableAutoStyles();

public:
diff --git a/sw/qa/extras/odfexport/data/nestedTableInFooter.odt b/sw/qa/extras/odfexport/data/nestedTableInFooter.odt
new file mode 100644
index 0000000..0356f04
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/nestedTableInFooter.odt
Binary files differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index e28ae25..ee25f99 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -2585,5 +2585,18 @@ DECLARE_ODFEXPORT_TEST(tdf124470, "tdf124470TableAndEmbeddedUsedFonts.odt")
    assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:family='paragraph']", 1);
}

DECLARE_ODFEXPORT_TEST(tdf135942, "nestedTableInFooter.odt")
{
    // All table autostyles should be collected, including nested, and must not crash.

    CPPUNIT_ASSERT_EQUAL(1, getPages());

    xmlDocUniquePtr pXmlDoc = parseExport("styles.xml");
    if (!pXmlDoc)
        return;

    assertXPath(pXmlDoc, "/office:document-styles/office:automatic-styles/style:style[@style:family='table']", 2);
}

CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/xml/xmltble.cxx b/sw/source/filter/xml/xmltble.cxx
index 506c4fb..68dbde3 100644
--- a/sw/source/filter/xml/xmltble.cxx
+++ b/sw/source/filter/xml/xmltble.cxx
@@ -1199,8 +1199,27 @@ void SwXMLTextParagraphExport::exportTable(
                // During the flat XML export (used e.g. by .sdw-export)
                // ALL flags are set at the same time.
                const bool bExportStyles = bool( GetExport().getExportFlags() & SvXMLExportFlags::STYLES );
                if ( bExportStyles || !pFormat->GetDoc()->IsInHeaderFooter( aIdx ) )
                if (!isAutoStylesCollected()
                    && (bExportStyles || !pFormat->GetDoc()->IsInHeaderFooter(aIdx)))
                {
                    maTableNodes.push_back(pTableNd);
                    // Collect all tables inside cells of this table, too
                    const auto aCellNames = pXTable->getCellNames();
                    for (const OUString& rCellName : aCellNames)
                    {
                        css::uno::Reference<css::container::XEnumerationAccess> xCell(
                            pXTable->getCellByName(rCellName), css::uno::UNO_QUERY);
                        if (!xCell)
                            continue;
                        auto xEnumeration = xCell->createEnumeration();
                        while (xEnumeration->hasMoreElements())
                        {
                            if (css::uno::Reference<css::text::XTextTable> xInnerTable{
                                    xEnumeration->nextElement(), css::uno::UNO_QUERY })
                                exportTable(xInnerTable, bAutoStyles, _bProgress);
                        }
                    }
                }
            }
            else
            {
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index a9354c0..eead9e4 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -3709,6 +3709,8 @@ void XMLTextParagraphExport::exportTableAutoStyles() {}

void XMLTextParagraphExport::exportTextAutoStyles()
{
    // tdf#135942: do not collect styles during their export: this may modify iterated containers
    mbCollected = true;
    exportTableAutoStyles();

    GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_PARAGRAPH );