cool#16122 export to pdf produces bad PANTONE element

The name element in a PDF file needs escaping if it contains spaces, like the PANTONE element does.

Re-use the escaping logic in COSWriter, and while we are here, convert
the COSWriter function from 'const char*' to std::string_view.

Change-Id: I4f6fdb049e746688c393371e2fea30bbaf6da314
Signed-off-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/10095
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 765ae13aa2e7a954a1629314726207f551d83ff8)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/210955
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Noel Grandin
2026-09-14 20:21:00 +02:00
committed by Xisco Fauli
parent 7558a892f6
commit 40062dd0b8
6 changed files with 39 additions and 14 deletions
+1 -6
View File
@@ -223,12 +223,7 @@ public:
const OString& GetValue() const;
SAL_DLLPRIVATE sal_uInt64 GetLocation() const;
sal_uInt64 GetLength() const { return m_aValue.getLength(); }
void writeString(OStringBuffer& rBuffer) override
{
rBuffer.append("/");
rBuffer.append(m_aValue);
}
void writeString(OStringBuffer& rBuffer) override;
};
/// Dictionary object: a set of key-value pairs.
+1 -1
View File
@@ -167,7 +167,7 @@ public:
static void appendUnicodeTextString(const OUString& rString, OStringBuffer& rBuffer);
static void appendName(std::u16string_view rString, OStringBuffer& rBuffer);
static void appendName(const char* pString, OStringBuffer& rBuffer);
static void appendName(std::string_view aString, OStringBuffer& rBuffer);
};
}
Binary file not shown.
+25
View File
@@ -7156,6 +7156,31 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testDropCapPaint)
CPPUNIT_ASSERT_DOUBLES_EQUAL(114.53, aRect.at(4).getMinX(), /*delta*/ 2.0);
}
CPPUNIT_TEST_FIXTURE(PdfExportTest2, cool16122BadPantoneElement)
{
vcl::filter::PDFDocument aDocument;
loadFromFile(u"cool16122.odt");
save(TestFilter::PDF_WRITER);
// Parse the export result.
SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
// Previously this would have failed here with "PDFDocument::Tokenize: unexpected 'C' keyword at byte position 280"
CPPUNIT_ASSERT(aDocument.Read(aStream));
// But just to be sure, check that the PANTONE element round-trips properly
bool bFound = false;
for (const auto& rDocElement : aDocument.GetElements())
{
if (auto pObject = dynamic_cast<vcl::filter::PDFNameElement*>(rDocElement.get()))
if (pObject->GetValue() == "PANTONE 293 C")
{
bFound = true;
break;
}
}
CPPUNIT_ASSERT(bFound);
}
} // end anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
+6
View File
@@ -2918,6 +2918,12 @@ bool PDFNameElement::Read(SvStream& rStream)
return false;
}
void PDFNameElement::writeString(OStringBuffer& rBuffer)
{
rBuffer.append("/");
pdf::COSWriter::appendName(m_aValue, rBuffer); // this does the necessary escaping
}
const OString& PDFNameElement::GetValue() const { return m_aValue; }
sal_uInt64 PDFNameElement::GetLocation() const { return m_nLocation; }
+6 -7
View File
@@ -170,22 +170,21 @@ void COSWriter::appendName(std::u16string_view rStr, OStringBuffer& rBuffer)
}
}
void COSWriter::appendName(const char* pStr, OStringBuffer& rBuffer)
void COSWriter::appendName(std::string_view aStr, OStringBuffer& rBuffer)
{
// FIXME i59651 see above
while (pStr && *pStr)
for (const auto ch : aStr)
{
if ((*pStr >= 'A' && *pStr <= 'Z') || (*pStr >= 'a' && *pStr <= 'z')
|| (*pStr >= '0' && *pStr <= '9') || *pStr == '-')
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
|| ch == '-')
{
rBuffer.append(*pStr);
rBuffer.append(ch);
}
else
{
rBuffer.append('#');
appendHex(static_cast<sal_Int8>(*pStr), rBuffer);
appendHex(static_cast<sal_Int8>(ch), rBuffer);
}
pStr++;
}
}