vcl/qa/cppunit/pdfexport/data/tdf159895.odt |binary
 vcl/qa/cppunit/pdfexport/pdfexport2.cxx     |   61 ++++++++++++++++++++++++++++
 vcl/source/gdi/pdfwriter_impl.cxx           |   15 +++---
 3 files changed, 68 insertions(+), 8 deletions(-)

New commits:
commit 54374c97b86730d97f5ad622dc88c0798af4be1c
Author:     Tibor Nagy <[email protected]>
AuthorDate: Thu Aug 22 21:34:34 2024 +0200
Commit:     Nagy Tibor <[email protected]>
CommitDate: Fri Aug 23 16:25:43 2024 +0200

    tdf#159895 sw: fix "Stack empty" error in tagged PDF export
    
    Change-Id: I8a2e0d51d1cfe6d4b517f193c73e512600638cf0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172302
    Tested-by: Jenkins
    Reviewed-by: Nagy Tibor <[email protected]>

diff --git a/vcl/qa/cppunit/pdfexport/data/tdf159895.odt 
b/vcl/qa/cppunit/pdfexport/data/tdf159895.odt
new file mode 100644
index 000000000000..77091cf51cad
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf159895.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
index 9b08b1fa047a..4895845f4b8c 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -85,6 +85,67 @@ void PdfExportTest2::load(std::u16string_view rFile, 
vcl::filter::PDFDocument& r
     CPPUNIT_ASSERT(rDocument.Read(aStream));
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf159895)
+{
+    // Enable PDF/UA
+    uno::Sequence<beans::PropertyValue> 
aFilterData(comphelper::InitPropertySequence({
+        { "PDFUACompliance", uno::Any(true) },
+        { "ExportFormFields", uno::Any(true) },
+    }));
+    aMediaDescriptor[u"FilterData"_ustr] <<= aFilterData;
+
+    vcl::filter::PDFDocument aDocument;
+    load(u"tdf159895.odt", aDocument);
+
+    // The document has one page.
+    std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(size_t(1), aPages.size());
+
+    for (const auto& rDocElement : aDocument.GetElements())
+    {
+        auto pObj = 
dynamic_cast<vcl::filter::PDFObjectElement*>(rDocElement.get());
+        if (!pObj)
+            continue;
+
+        auto pType = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObj->Lookup("Type"_ostr));
+        if (pType && pType->GetValue() == "XObject")
+        {
+            auto pFilter = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObj->Lookup("Filter"_ostr));
+            CPPUNIT_ASSERT(pFilter);
+
+            vcl::filter::PDFStreamElement* pStream = pObj->GetStream();
+            CPPUNIT_ASSERT(pStream);
+            SvMemoryStream& rObjectStream = pStream->GetMemory();
+            // Uncompress it.
+            SvMemoryStream aUncompressed;
+            ZCodec aZCodec;
+            aZCodec.BeginCompression();
+            rObjectStream.Seek(0);
+            aZCodec.Decompress(rObjectStream, aUncompressed);
+            CPPUNIT_ASSERT(aZCodec.EndCompression());
+
+            auto pStart = static_cast<const char*>(aUncompressed.GetData());
+            const char* const pEnd = pStart + aUncompressed.GetSize();
+
+            OString sText;
+            while (true)
+            {
+                auto const pLine = ::std::find(pStart, pEnd, '
');
+                if (pLine == pEnd)
+                    break;
+
+                std::string_view const line(pStart, pLine - pStart);
+                pStart = pLine + 1;
+                if (!line.empty() && line[0] != '%')
+                {
+                    sText += line + "
"_ostr;
+                }
+            }
+            CPPUNIT_ASSERT_EQUAL("/Tx BMC
EMC
"_ostr, sText);
+        }
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf124272)
 {
     // Import the bugdoc and export as PDF.
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 434156491703..d986c93c3de3 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -4364,20 +4364,12 @@ void PDFWriterImpl::createDefaultListBoxAppearance( 
PDFWidget& rBox, const PDFWr
     Font aFont = drawFieldBorder( rBox, rWidget, rSettings );
     sal_Int32 nBest = getSystemFont( aFont );
 
-    beginRedirect( pListBoxStream, rBox.m_aRect );
-
     setLineColor( COL_TRANSPARENT );
     setFillColor( replaceColor( rWidget.BackgroundColor, 
rSettings.GetFieldColor() ) );
     drawRectangle( rBox.m_aRect );
 
-    // empty appearance, see createDefaultEditAppearance for reference
-    writeBuffer( "/Tx BMC
EMC
" );
-
-    endRedirect();
     pop();
 
-    rBox.m_aAppearances[ "N"_ostr ][ "Standard"_ostr ] = pListBoxStream;
-
     // prepare DA string
     OStringBuffer aDA( 256 );
     // prepare DA string
@@ -4394,6 +4386,13 @@ void PDFWriterImpl::createDefaultListBoxAppearance( 
PDFWidget& rBox, const PDFWr
     aDA.append( ' ' );
     m_aPages[ m_nCurrentPage ].appendMappedLength( sal_Int32( 
aFont.GetFontHeight() ), aDA );
     aDA.append( " Tf" );
+
+    beginRedirect(pListBoxStream, rBox.m_aRect);
+    // empty appearance, see createDefaultEditAppearance for reference
+    writeBuffer("/Tx BMC
EMC
");
+    endRedirect();
+
+    rBox.m_aAppearances["N"_ostr]["Standard"_ostr] = pListBoxStream;
     rBox.m_aDAString = aDA.makeStringAndClear();
 }
 

Reply via email to