From 6a7005675fb2e796864395a173290537d0645aa0 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sat, 11 Jul 2020 18:02:30 +0200 Subject: [PATCH] Adding some catalog entry - PDF 2.0 conformance --- PdfForQtLib/sources/pdfcatalog.cpp | 34 ++++++++++++++++++++++ PdfForQtLib/sources/pdfcatalog.h | 32 ++++++++++++++++++++ PdfForQtLib/sources/pdfsecurityhandler.cpp | 2 +- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/PdfForQtLib/sources/pdfcatalog.cpp b/PdfForQtLib/sources/pdfcatalog.cpp index 9f38dd0..529f628 100644 --- a/PdfForQtLib/sources/pdfcatalog.cpp +++ b/PdfForQtLib/sources/pdfcatalog.cpp @@ -170,6 +170,7 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume } catalogObject.m_formObject = catalogDictionary->get("AcroForm"); + catalogObject.m_extensions = PDFDeveloperExtensions::parse(catalogDictionary->get("Extensions"), document); catalogObject.m_documentSecurityStore = PDFDocumentSecurityStore::parse(catalogDictionary->get("DSS"), document); return catalogObject; @@ -539,4 +540,37 @@ PDFDocumentSecurityStore PDFDocumentSecurityStore::parse(const PDFObject& object return store; } +PDFDeveloperExtensions PDFDeveloperExtensions::parse(const PDFObject& object, const PDFDocument* document) +{ + PDFDeveloperExtensions extensions; + + if (const PDFDictionary* dictionary = document->getDictionaryFromObject(object)) + { + const size_t extensionsCount = dictionary->getCount(); + extensions.m_extensions.reserve(extensionsCount); + for (size_t i = 0; i < extensionsCount; ++i) + { + // Skip type entry + if (dictionary->getKey(i) == "Type") + { + continue; + } + + if (const PDFDictionary* extensionsDictionary = document->getDictionaryFromObject(dictionary->getValue(i))) + { + PDFDocumentDataLoaderDecorator loader(document); + + Extension extension; + extension.name = dictionary->getKey(i).getString(); + extension.baseVersion = loader.readNameFromDictionary(extensionsDictionary, "BaseName"); + extension.extensionLevel = loader.readIntegerFromDictionary(extensionsDictionary, "ExtensionLevel", 0); + extension.url = loader.readStringFromDictionary(extensionsDictionary, "URL"); + extensions.m_extensions.emplace_back(qMove(extension)); + } + } + } + + return extensions; +} + } // namespace pdf diff --git a/PdfForQtLib/sources/pdfcatalog.h b/PdfForQtLib/sources/pdfcatalog.h index e6ae735..e3fe5dc 100644 --- a/PdfForQtLib/sources/pdfcatalog.h +++ b/PdfForQtLib/sources/pdfcatalog.h @@ -225,6 +225,36 @@ private: std::map m_VRI; }; +/// Document extensions. Contains information about developer's extensions +/// used in document. +class PDFFORQTLIBSHARED_EXPORT PDFDeveloperExtensions +{ +public: + explicit PDFDeveloperExtensions() = default; + + struct Extension + { + QByteArray name; + QByteArray baseVersion; + PDFInteger extensionLevel = 0; + QByteArray url; + }; + + using Extensions = std::vector; + + /// Returns list of extensions + const Extensions& getExtensions() const { return m_extensions; } + + /// Parses extensions from catalog dictionary. If object cannot be parsed, or error occurs, + /// then empty object is returned, no exception is thrown. + /// \param object Extensions dictionary + /// \param document Document + static PDFDeveloperExtensions parse(const PDFObject& object, const PDFDocument* document); + +private: + Extensions m_extensions; +}; + class PDFFORQTLIBSHARED_EXPORT PDFCatalog { public: @@ -267,6 +297,7 @@ public: const QByteArray& getBaseURI() const { return m_baseURI; } const std::map& getEmbeddedFiles() const { return m_embeddedFiles; } const PDFObject& getFormObject() const { return m_formObject; } + const PDFDeveloperExtensions& getExtensions() const { return m_extensions; } const PDFDocumentSecurityStore& getDocumentSecurityStore() const { return m_documentSecurityStore; } /// Returns destination using the key. If destination with the key is not found, @@ -291,6 +322,7 @@ private: PageMode m_pageMode = PageMode::UseNone; QByteArray m_baseURI; PDFObject m_formObject; + PDFDeveloperExtensions m_extensions; PDFDocumentSecurityStore m_documentSecurityStore; // Maps from Names dictionary diff --git a/PdfForQtLib/sources/pdfsecurityhandler.cpp b/PdfForQtLib/sources/pdfsecurityhandler.cpp index 7bfb344..1048839 100644 --- a/PdfForQtLib/sources/pdfsecurityhandler.cpp +++ b/PdfForQtLib/sources/pdfsecurityhandler.cpp @@ -811,7 +811,7 @@ QByteArray PDFStandardSecurityHandler::createFileEncryptionKey(const QByteArray& const int keyByteLength = m_keyLength / 8; if (keyByteLength > MD5_DIGEST_LENGTH) { - throw PDFException(PDFTranslationContext::tr("Encryption key length (%1) exceeded maximal value of.").arg(keyByteLength).arg(MD5_DIGEST_LENGTH)); + throw PDFException(PDFTranslationContext::tr("Encryption key length (%1) exceeded maximal value of %2.").arg(keyByteLength).arg(MD5_DIGEST_LENGTH)); } if (m_R >= 3)