vcl/qa/cppunit/pdfexport/pdfexport.cxx | 4 ++-- vcl/qa/cppunit/pdfexport/pdfexport2.cxx | 16 ++++++++-------- vcl/source/filter/ipdf/pdfdocument.cxx | 23 ++++++++++++++++++++++- 3 files changed, 32 insertions(+), 11 deletions(-)
New commits: commit 82fa4b0966dd76923b2cce3fa5710dd920b27535 Author: Khaled Hosny <[email protected]> AuthorDate: Thu Feb 26 16:51:18 2026 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Fri Feb 27 09:05:31 2026 +0100 Parse hexadecimal escapes in vcl::filter::PDFNameElement We write these escapes rather liberally in COSWriter::appendName(), so we should parse them when reading. Change-Id: Ie9f7626de287fd5038ca198a7143a95c3471ce92 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200446 Tested-by: Jenkins Reviewed-by: Khaled Hosny <[email protected]> (cherry picked from commit 247430c3edd811744f525d09da00035702cbbf6a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200500 Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit 235ea4b4c472f40977434c6437aab795f034a1dc) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200525 diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 5a6415cd0f1f..dd5daeee6c06 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -2251,7 +2251,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157816) auto pTypeD2 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD2->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pTypeD2->GetValue()); auto pSD2 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD2->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Text#20body"_ostr, pSD2->GetValue()); + CPPUNIT_ASSERT_EQUAL("Text body"_ostr, pSD2->GetValue()); auto pKidsD2 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD2->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKidsD2); @@ -3302,7 +3302,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142806) auto pTypeD1 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD1->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pTypeD1->GetValue()); auto pSD1 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD1->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Text#20body"_ostr, pSD1->GetValue()); + CPPUNIT_ASSERT_EQUAL("Text body"_ostr, pSD1->GetValue()); auto pKidsD1 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD1->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKidsD1); diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx index bddf05c24b11..f64ae8e474f1 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx @@ -1962,7 +1962,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157817) auto pTypeT00 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT00->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pTypeT00->GetValue()); auto pST00 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT00->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Contents#20Heading"_ostr, pST00->GetValue()); + CPPUNIT_ASSERT_EQUAL("Contents Heading"_ostr, pST00->GetValue()); auto pRefKidT1 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsTv[1]); CPPUNIT_ASSERT(pRefKidT1); @@ -1984,7 +1984,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157817) auto pTypeT10 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT10->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pTypeT10->GetValue()); auto pST10 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT10->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Contents#201"_ostr, pST10->GetValue()); + CPPUNIT_ASSERT_EQUAL("Contents 1"_ostr, pST10->GetValue()); auto pKidsT10 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT10->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKidsT10); @@ -2021,7 +2021,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157817) auto pTypeT20 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT20->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pTypeT20->GetValue()); auto pST20 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT20->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Contents#201"_ostr, pST20->GetValue()); + CPPUNIT_ASSERT_EQUAL("Contents 1"_ostr, pST20->GetValue()); auto pKidsT20 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT20->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKidsT20); @@ -2058,7 +2058,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157817) auto pTypeT30 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT30->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pTypeT30->GetValue()); auto pST30 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT30->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Contents#201"_ostr, pST30->GetValue()); + CPPUNIT_ASSERT_EQUAL("Contents 1"_ostr, pST30->GetValue()); auto pKidsT30 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT30->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKidsT30); @@ -2984,7 +2984,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157397) auto pType12 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject12->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pType12->GetValue()); auto pS12 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject12->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Text#20body"_ostr, pS12->GetValue()); + CPPUNIT_ASSERT_EQUAL("Text body"_ostr, pS12->GetValue()); auto pKids12 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObject12->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKids12); @@ -3058,7 +3058,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157397) auto pType13 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject13->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pType13->GetValue()); auto pS13 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject13->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Text#20body"_ostr, pS13->GetValue()); + CPPUNIT_ASSERT_EQUAL("Text body"_ostr, pS13->GetValue()); auto pKids13 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObject13->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKids13); @@ -3131,7 +3131,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157397) auto pType14 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject14->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pType14->GetValue()); auto pS14 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject14->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Text#20body"_ostr, pS14->GetValue()); + CPPUNIT_ASSERT_EQUAL("Text body"_ostr, pS14->GetValue()); auto pKids14 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObject14->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKids14); @@ -3205,7 +3205,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf157397) auto pType16 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject16->Lookup("Type"_ostr)); CPPUNIT_ASSERT_EQUAL("StructElem"_ostr, pType16->GetValue()); auto pS16 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject16->Lookup("S"_ostr)); - CPPUNIT_ASSERT_EQUAL("Text#20body"_ostr, pS16->GetValue()); + CPPUNIT_ASSERT_EQUAL("Text body"_ostr, pS16->GetValue()); auto pKids16 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObject16->Lookup("K"_ostr)); CPPUNIT_ASSERT(pKids16); diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index 0b7c01a56ac1..7f79b1f394fd 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -2886,7 +2886,28 @@ bool PDFNameElement::Read(SvStream& rStream) SAL_INFO("vcl.filter", "PDFNameElement::Read: m_aValue is '" << m_aValue << "'"); return true; } - aBuf.append(ch); + // Parse hexadecimal escapes + if (ch == '#') + { + unsigned char hex1, hex2; + rStream.ReadUChar(hex1); + rStream.ReadUChar(hex2); + if (!rStream.eof() && rtl::isAsciiHexDigit(hex1) && rtl::isAsciiHexDigit(hex2)) + { + unsigned char hexBuf[2] = { hex1, hex2 }; + aBuf.append(static_cast<char>( + OString(reinterpret_cast<const char*>(hexBuf), 2).toInt32(16))); + } + else + { + SAL_WARN("vcl.filter", "PDFNameElement::Read: invalid hex escape"); + return false; + } + } + else + { + aBuf.append(ch); + } rStream.ReadChar(ch); }
