[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - include/vcl vcl/qa vcl/source

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Wed Sep 8 08:10:01 UTC 2021


 include/vcl/filter/pdfdocument.hxx               |    1 
 vcl/qa/cppunit/pdfexport/data/WG7100-Preface.odt |binary
 vcl/qa/cppunit/pdfexport/data/master.odm         |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx           |   87 +++++++++++++++++++++++
 vcl/source/filter/ipdf/pdfdocument.cxx           |   17 ++++
 5 files changed, 105 insertions(+)

New commits:
commit c6b6e5b9cbb9ce78b11c26bf3d1a27c2f2cb76ac
Author:     Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Tue Sep 7 13:51:20 2021 +0200
Commit:     Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Wed Sep 8 10:09:27 2021 +0200

    tdf#142129 vcl: add unit test
    
    Reportedly bug was fixed by commit
    5fc6a601d7a1978db291fd0f7dcec638a7c25651
    
    Change-Id: Iee32cacff0c939bdf498e9dc8102eb2d22a5a1c9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121776
    Tested-by: Michael Stahl <michael.stahl at allotropia.de>
    Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>
    (cherry picked from commit 992f878e8c3424f7ce96a78ccf3a316b29ffd9ec)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121763
    Tested-by: Xisco Fauli <xiscofauli at libreoffice.org>
    Reviewed-by: Xisco Fauli <xiscofauli at libreoffice.org>

diff --git a/include/vcl/filter/pdfdocument.hxx b/include/vcl/filter/pdfdocument.hxx
index 26866544bf60..4b5d732617cc 100644
--- a/include/vcl/filter/pdfdocument.hxx
+++ b/include/vcl/filter/pdfdocument.hxx
@@ -546,6 +546,7 @@ public:
     //@{
     /// Decode a hex dump.
     static std::vector<unsigned char> DecodeHexString(PDFHexStringElement const* pElement);
+    static OUString DecodeHexStringUTF16BE(PDFHexStringElement const& rElement);
     static OString ReadKeyword(SvStream& rStream);
     static size_t FindStartXRef(SvStream& rStream);
     void ReadXRef(SvStream& rStream);
diff --git a/vcl/qa/cppunit/pdfexport/data/WG7100-Preface.odt b/vcl/qa/cppunit/pdfexport/data/WG7100-Preface.odt
new file mode 100644
index 000000000000..05e2bb18408a
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/WG7100-Preface.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/data/master.odm b/vcl/qa/cppunit/pdfexport/data/master.odm
new file mode 100644
index 000000000000..74016352b762
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/master.odm differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index bb203602714d..0da9bedd33ef 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -2791,6 +2791,93 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfUaMetadata)
     CPPUNIT_ASSERT_EQUAL(OString("1"), aPdfUaPart);
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142129)
+{
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "master.odm";
+    mxComponent = loadFromDesktop(aURL);
+
+    // update linked section
+    dispatchCommand(mxComponent, ".uno:UpdateAllLinks", {});
+
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+
+    // Enable Outlines export
+    uno::Sequence<beans::PropertyValue> aFilterData(
+        comphelper::InitPropertySequence({ { "ExportBookmarks", uno::Any(true) } }));
+    aMediaDescriptor["FilterData"] <<= aFilterData;
+    xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+    // Parse the export result.
+    vcl::filter::PDFDocument aDocument;
+    SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    auto* pCatalog = aDocument.GetCatalog();
+    CPPUNIT_ASSERT(pCatalog);
+    auto* pCatalogDictionary = pCatalog->GetDictionary();
+    CPPUNIT_ASSERT(pCatalogDictionary);
+    auto* pOutlinesObject = pCatalogDictionary->LookupObject("Outlines");
+    CPPUNIT_ASSERT(pOutlinesObject);
+    auto* pOutlinesDictionary = pOutlinesObject->GetDictionary();
+#if 0
+    // Type isn't actually written currently
+    auto* pType
+        = dynamic_cast<vcl::filter::PDFNameElement*>(pOutlinesDictionary->LookupElement("Type"));
+    CPPUNIT_ASSERT(pType);
+    CPPUNIT_ASSERT_EQUAL(OString("Outlines"), pType->GetValue());
+#endif
+
+    auto* pFirst = dynamic_cast<vcl::filter::PDFReferenceElement*>(
+        pOutlinesDictionary->LookupElement("First"));
+    CPPUNIT_ASSERT(pFirst);
+    auto* pFirstD = pFirst->LookupObject()->GetDictionary();
+    CPPUNIT_ASSERT(pFirstD);
+    //CPPUNIT_ASSERT_EQUAL(OString("Outlines"), dynamic_cast<vcl::filter::PDFNameElement*>(pFirstD->LookupElement("Type"))->GetValue());
+    CPPUNIT_ASSERT_EQUAL(OUString(u"Preface"), ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(
+                                                   *dynamic_cast<vcl::filter::PDFHexStringElement*>(
+                                                       pFirstD->LookupElement("Title"))));
+
+    auto* pFirst1
+        = dynamic_cast<vcl::filter::PDFReferenceElement*>(pFirstD->LookupElement("First"));
+    CPPUNIT_ASSERT(pFirst1);
+    auto* pFirst1D = pFirst1->LookupObject()->GetDictionary();
+    CPPUNIT_ASSERT(pFirst1D);
+    // here is a hidden section with headings "Copyright" etc.; check that
+    // there are no outline entries for it
+    //CPPUNIT_ASSERT_EQUAL(OString("Outlines"), dynamic_cast<vcl::filter::PDFNameElement*>(pFirst1D->LookupElement("Type"))->GetValue());
+    CPPUNIT_ASSERT_EQUAL(
+        OUString(u"Who is this book for?"),
+        ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(
+            *dynamic_cast<vcl::filter::PDFHexStringElement*>(pFirst1D->LookupElement("Title"))));
+
+    auto* pFirst2
+        = dynamic_cast<vcl::filter::PDFReferenceElement*>(pFirst1D->LookupElement("Next"));
+    auto* pFirst2D = pFirst2->LookupObject()->GetDictionary();
+    CPPUNIT_ASSERT(pFirst2D);
+    //CPPUNIT_ASSERT_EQUAL(OString("Outlines"), dynamic_cast<vcl::filter::PDFNameElement*>(pFirst2D->LookupElement("Type"))->GetValue());
+    CPPUNIT_ASSERT_EQUAL(
+        OUString(u"What\u2019s in this book?"),
+        ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(
+            *dynamic_cast<vcl::filter::PDFHexStringElement*>(pFirst2D->LookupElement("Title"))));
+
+    auto* pFirst3
+        = dynamic_cast<vcl::filter::PDFReferenceElement*>(pFirst2D->LookupElement("Next"));
+    auto* pFirst3D = pFirst3->LookupObject()->GetDictionary();
+    CPPUNIT_ASSERT(pFirst3D);
+    //CPPUNIT_ASSERT_EQUAL(OString("Outlines"), dynamic_cast<vcl::filter::PDFNameElement*>(pFirst3D->LookupElement("Type"))->GetValue());
+    CPPUNIT_ASSERT_EQUAL(
+        OUString(u"Minimum requirements for using LibreOffice"),
+        ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(
+            *dynamic_cast<vcl::filter::PDFHexStringElement*>(pFirst3D->LookupElement("Title"))));
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<vcl::filter::PDFElement*>(nullptr),
+                         pFirst3D->LookupElement("Next"));
+    CPPUNIT_ASSERT_EQUAL(static_cast<vcl::filter::PDFElement*>(nullptr),
+                         pFirstD->LookupElement("Next"));
+}
+
 CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfImageRotate180)
 {
     // Create an empty document.
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index e8bca353133d..f5fc63be558f 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -2052,6 +2052,23 @@ std::vector<unsigned char> PDFDocument::DecodeHexString(PDFHexStringElement cons
     return svl::crypto::DecodeHexString(pElement->GetValue());
 }
 
+OUString PDFDocument::DecodeHexStringUTF16BE(PDFHexStringElement const& rElement)
+{
+    std::vector<unsigned char> const encoded(DecodeHexString(&rElement));
+    // Text strings can be PDF-DocEncoding or UTF-16BE with mandatory BOM;
+    // only the latter supported is here
+    if (encoded.size() < 2 || encoded[0] != 0xFE || encoded[1] != 0xFF || (encoded.size() & 1) != 0)
+    {
+        return OUString();
+    }
+    OUStringBuffer buf(static_cast<unsigned int>(encoded.size() - 2));
+    for (size_t i = 2; i < encoded.size(); i += 2)
+    {
+        buf.append(sal_Unicode((static_cast<sal_uInt16>(encoded[i]) << 8) | encoded[i + 1]));
+    }
+    return buf.makeStringAndClear();
+}
+
 PDFCommentElement::PDFCommentElement(PDFDocument& rDoc)
     : m_rDoc(rDoc)
 {


More information about the Libreoffice-commits mailing list