summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dave@treblig.org>2021-11-14 15:26:51 +0000
committerStephan Bergmann <sbergman@redhat.com>2022-02-07 11:40:48 +0100
commit2a57ef5512a018bfcfac85a8cd63f2e528f7cdca (patch)
tree26d75e4a50dfb2880f5ae936ec80b349da608fa3 /vcl
parent372f5902200b46edd794c865f6d316a4a32d9cc6 (diff)
pdfwriter: Check URIs exported
Check the URIs that are exported. Change-Id: I2d8b00f767a61c5abdb9163701fe497bb258c790 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125203 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx96
1 files changed, 96 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 9bc315fcb2bd..4326b53b80bb 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -2978,6 +2978,102 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfImageHyperlink)
#endif
}
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testURIs)
+{
+ struct
+ {
+ OUString in;
+ OString out;
+ } URIs[] = { {
+ "http://example.com/",
+ "http://example.com/",
+ },
+ {
+ "file://localfile.odt/",
+ "file://localfile.odt/",
+ },
+ {
+ "git://git.example.org/project/example",
+ "git://git.example.org/project/example",
+ },
+ {
+ // The odt/pdf gets substituted due to 'ConvertOOoTargetToPDFTarget'
+ "filebypath.odt",
+ "filebypath.pdf",
+ },
+ {
+ // This also gets made relative due to 'ExportLinksRelativeFsys'
+ utl::TempFile::GetTempNameBaseDirectory() + "fileintempdir.odt",
+ "fileintempdir.pdf",
+ } };
+
+ // Create an empty document.
+ // Note: The test harness gets very upset if we try and create multiple
+ // documents, or recreate it; so reuse one instance for all the links
+ mxComponent = loadFromDesktop("private:factory/swriter");
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+ xText->insertString(xCursor, "Test pdf", /*bAbsorb=*/false);
+
+ // Set the name so it can do relative name replacement
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ xModel->attachResource(maTempFile.GetURL(), xModel->getArgs());
+
+ // Test the filename rewriting
+ uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence({
+ { "ExportLinksRelativeFsys", uno::makeAny(true) },
+ { "ConvertOOoTargetToPDFTarget", uno::makeAny(true) },
+ }));
+ aMediaDescriptor["FilterData"] <<= aFilterData;
+
+ for (unsigned int i = 0; i < (sizeof(URIs) / sizeof(URIs[0])); i++)
+ {
+ // Add a link (based on testNestedHyperlink in rtfexport3)
+ xCursor->gotoStart(/*bExpand=*/false);
+ xCursor->gotoEnd(/*bExpand=*/true);
+ uno::Reference<beans::XPropertySet> xCursorProps(xCursor, uno::UNO_QUERY);
+ xCursorProps->setPropertyValue("HyperLinkURL", uno::makeAny(URIs[i].in));
+
+ // Save as PDF.
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Use the filter rather than the pdfium route, as per the tdf105093 test, it's
+ // easier to parse the annotations
+ vcl::filter::PDFDocument aDocument;
+
+ // Parse the export result.
+ SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
+ CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+ // The document has one page.
+ std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+ auto pAnnots = dynamic_cast<vcl::filter::PDFArrayElement*>(aPages[0]->Lookup("Annots"));
+ CPPUNIT_ASSERT(pAnnots);
+
+ // There should be one annotation
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnnots->GetElements().size());
+ auto pAnnotReference
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pAnnots->GetElements()[0]);
+ CPPUNIT_ASSERT(pAnnotReference);
+ vcl::filter::PDFObjectElement* pAnnot = pAnnotReference->LookupObject();
+ CPPUNIT_ASSERT(pAnnot);
+ // We're expecting something like /Type /Annot /A << /Type /Action /S /URI /URI (path)
+ CPPUNIT_ASSERT_EQUAL(
+ OString("Annot"),
+ static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"))->GetValue());
+ auto pAction = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pAnnot->Lookup("A"));
+ CPPUNIT_ASSERT(pAction);
+ auto pURIElem
+ = dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pAction->LookupElement("URI"));
+ CPPUNIT_ASSERT(pURIElem);
+ // Check it matches
+ CPPUNIT_ASSERT_EQUAL(URIs[i].out, pURIElem->GetValue());
+ }
+}
} // end anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();