Kaydet (Commit) 17407f80 authored tarafından Miklos Vajna's avatar Miklos Vajna

Turn on clang-format for these files

I (tried to) keep these files consistent locally with astyle in the past,
switching to clang-format makes sure that the recent problem with introducing
inconsistencies in these files doesn't happen again.

(On the flip side, it's great to see that now others also touch this
PDF/pdfium code. :-) )

Change-Id: I6065eab77c584197a82fe48e7d3e81b445106efd
Reviewed-on: https://gerrit.libreoffice.org/51701Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst 45ea6ebd
...@@ -25,7 +25,6 @@ namespace vcl ...@@ -25,7 +25,6 @@ namespace vcl
{ {
namespace filter namespace filter
{ {
class PDFTrailerElement; class PDFTrailerElement;
class PDFHexStringElement; class PDFHexStringElement;
class PDFReferenceElement; class PDFReferenceElement;
...@@ -67,9 +66,9 @@ class VCL_DLLPUBLIC PDFObjectElement : public PDFElement ...@@ -67,9 +66,9 @@ class VCL_DLLPUBLIC PDFObjectElement : public PDFElement
/// The stream of this object, used when this is an object stream. /// The stream of this object, used when this is an object stream.
PDFStreamElement* m_pStreamElement; PDFStreamElement* m_pStreamElement;
/// Objects of an object stream. /// Objects of an object stream.
std::vector< std::unique_ptr<PDFObjectElement> > m_aStoredElements; std::vector<std::unique_ptr<PDFObjectElement>> m_aStoredElements;
/// Elements of an object in an object stream. /// Elements of an object in an object stream.
std::vector< std::unique_ptr<PDFElement> > m_aElements; std::vector<std::unique_ptr<PDFElement>> m_aElements;
/// Uncompressed buffer of an object in an object stream. /// Uncompressed buffer of an object in an object stream.
std::unique_ptr<SvMemoryStream> m_pStreamBuffer; std::unique_ptr<SvMemoryStream> m_pStreamBuffer;
/// List of all reference elements inside this object's dictionary and /// List of all reference elements inside this object's dictionary and
...@@ -105,7 +104,7 @@ public: ...@@ -105,7 +104,7 @@ public:
PDFArrayElement* GetArray() const; PDFArrayElement* GetArray() const;
/// Parse objects stored in this object stream. /// Parse objects stored in this object stream.
void ParseStoredObjects(); void ParseStoredObjects();
std::vector< std::unique_ptr<PDFElement> >& GetStoredElements(); std::vector<std::unique_ptr<PDFElement>>& GetStoredElements();
SvMemoryStream* GetStreamBuffer() const; SvMemoryStream* GetStreamBuffer() const;
void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer); void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer);
PDFDocument& GetDocument(); PDFDocument& GetDocument();
...@@ -117,6 +116,7 @@ class VCL_DLLPUBLIC PDFArrayElement : public PDFElement ...@@ -117,6 +116,7 @@ class VCL_DLLPUBLIC PDFArrayElement : public PDFElement
std::vector<PDFElement*> m_aElements; std::vector<PDFElement*> m_aElements;
/// The object that contains this array. /// The object that contains this array.
PDFObjectElement* m_pObject; PDFObjectElement* m_pObject;
public: public:
PDFArrayElement(PDFObjectElement* pObject); PDFArrayElement(PDFObjectElement* pObject);
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
...@@ -136,7 +136,8 @@ class VCL_DLLPUBLIC PDFReferenceElement : public PDFElement ...@@ -136,7 +136,8 @@ class VCL_DLLPUBLIC PDFReferenceElement : public PDFElement
PDFNumberElement& m_rObject; PDFNumberElement& m_rObject;
public: public:
PDFReferenceElement(PDFDocument& rDoc, PDFNumberElement& rObject, PDFNumberElement const& rGeneration); PDFReferenceElement(PDFDocument& rDoc, PDFNumberElement& rObject,
PDFNumberElement const& rGeneration);
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
/// Assuming the reference points to a number object, return its value. /// Assuming the reference points to a number object, return its value.
double LookupNumber(SvStream& rStream) const; double LookupNumber(SvStream& rStream) const;
...@@ -171,6 +172,7 @@ class VCL_DLLPUBLIC PDFNameElement : public PDFElement ...@@ -171,6 +172,7 @@ class VCL_DLLPUBLIC PDFNameElement : public PDFElement
sal_uInt64 m_nLocation = 0; sal_uInt64 m_nLocation = 0;
/// Length till the next token start. /// Length till the next token start.
sal_uInt64 m_nLength = 0; sal_uInt64 m_nLength = 0;
public: public:
PDFNameElement(); PDFNameElement();
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
...@@ -195,8 +197,10 @@ public: ...@@ -195,8 +197,10 @@ public:
PDFDictionaryElement(); PDFDictionaryElement();
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
static size_t Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary); static size_t Parse(const std::vector<std::unique_ptr<PDFElement>>& rElements,
static PDFElement* Lookup(const std::map<OString, PDFElement*>& rDictionary, const OString& rKey); PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary);
static PDFElement* Lookup(const std::map<OString, PDFElement*>& rDictionary,
const OString& rKey);
void SetKeyOffset(const OString& rKey, sal_uInt64 nOffset); void SetKeyOffset(const OString& rKey, sal_uInt64 nOffset);
sal_uInt64 GetKeyOffset(const OString& rKey) const; sal_uInt64 GetKeyOffset(const OString& rKey) const;
void SetKeyValueLength(const OString& rKey, sal_uInt64 nLength); void SetKeyValueLength(const OString& rKey, sal_uInt64 nLength);
...@@ -252,6 +256,7 @@ struct XRefEntry ...@@ -252,6 +256,7 @@ struct XRefEntry
class VCL_DLLPUBLIC PDFHexStringElement : public PDFElement class VCL_DLLPUBLIC PDFHexStringElement : public PDFElement
{ {
OString m_aValue; OString m_aValue;
public: public:
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
const OString& GetValue() const; const OString& GetValue() const;
...@@ -261,6 +266,7 @@ public: ...@@ -261,6 +266,7 @@ public:
class VCL_DLLPUBLIC PDFLiteralStringElement : public PDFElement class VCL_DLLPUBLIC PDFLiteralStringElement : public PDFElement
{ {
OString m_aValue; OString m_aValue;
public: public:
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
const OString& GetValue() const; const OString& GetValue() const;
...@@ -293,7 +299,7 @@ public: ...@@ -293,7 +299,7 @@ public:
class VCL_DLLPUBLIC PDFDocument class VCL_DLLPUBLIC PDFDocument
{ {
/// This vector owns all elements. /// This vector owns all elements.
std::vector< std::unique_ptr<PDFElement> > m_aElements; std::vector<std::unique_ptr<PDFElement>> m_aElements;
/// Object ID <-> object offset map. /// Object ID <-> object offset map.
std::map<size_t, XRefEntry> m_aXRef; std::map<size_t, XRefEntry> m_aXRef;
/// Object offset <-> Object pointer map. /// Object offset <-> Object pointer map.
...@@ -317,11 +323,13 @@ class VCL_DLLPUBLIC PDFDocument ...@@ -317,11 +323,13 @@ class VCL_DLLPUBLIC PDFDocument
/// Suggest a minimal, yet free signature ID to use for the next signature. /// Suggest a minimal, yet free signature ID to use for the next signature.
sal_uInt32 GetNextSignature(); sal_uInt32 GetNextSignature();
/// Write the signature object as part of signing. /// Write the signature object as part of signing.
sal_Int32 WriteSignatureObject(const OUString& rDescription, bool bAdES, sal_uInt64& rLastByteRangeOffset, sal_Int64& rContentOffset); sal_Int32 WriteSignatureObject(const OUString& rDescription, bool bAdES,
sal_uInt64& rLastByteRangeOffset, sal_Int64& rContentOffset);
/// Write the appearance object as part of signing. /// Write the appearance object as part of signing.
sal_Int32 WriteAppearanceObject(); sal_Int32 WriteAppearanceObject();
/// Write the annot object as part of signing. /// Write the annot object as part of signing.
sal_Int32 WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_Int32 nSignatureId, sal_Int32 nAppearanceId); sal_Int32 WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_Int32 nSignatureId,
sal_Int32 nAppearanceId);
/// Write the updated Page object as part of signing. /// Write the updated Page object as part of signing.
bool WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnotId); bool WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnotId);
/// Write the updated Catalog object as part of signing. /// Write the updated Catalog object as part of signing.
...@@ -345,7 +353,7 @@ public: ...@@ -345,7 +353,7 @@ public:
/// Instead of all whitespace, just skip CR and NL characters. /// Instead of all whitespace, just skip CR and NL characters.
static void SkipLineBreaks(SvStream& rStream); static void SkipLineBreaks(SvStream& rStream);
size_t GetObjectOffset(size_t nIndex) const; size_t GetObjectOffset(size_t nIndex) const;
const std::vector< std::unique_ptr<PDFElement> >& GetElements(); const std::vector<std::unique_ptr<PDFElement>>& GetElements();
std::vector<PDFObjectElement*> GetPages(); std::vector<PDFObjectElement*> GetPages();
/// Remember the end location of an EOF token. /// Remember the end location of an EOF token.
void PushBackEOF(size_t nOffset); void PushBackEOF(size_t nOffset);
...@@ -354,7 +362,9 @@ public: ...@@ -354,7 +362,9 @@ public:
/// Access to the input document, even after the input stream is gone. /// Access to the input document, even after the input stream is gone.
SvMemoryStream& GetEditBuffer(); SvMemoryStream& GetEditBuffer();
/// Tokenize elements from current offset. /// Tokenize elements from current offset.
bool Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< std::unique_ptr<PDFElement> >& rElements, PDFObjectElement* pObjectElement); bool Tokenize(SvStream& rStream, TokenizeMode eMode,
std::vector<std::unique_ptr<PDFElement>>& rElements,
PDFObjectElement* pObjectElement);
/// Register an object (owned directly or indirectly by m_aElements) as a provider for a given ID. /// Register an object (owned directly or indirectly by m_aElements) as a provider for a given ID.
void SetIDObject(size_t nID, PDFObjectElement* pObject); void SetIDObject(size_t nID, PDFObjectElement* pObject);
//@} //@}
...@@ -364,7 +374,8 @@ public: ...@@ -364,7 +374,8 @@ public:
/// Read elements from the start of the stream till its end. /// Read elements from the start of the stream till its end.
bool Read(SvStream& rStream); bool Read(SvStream& rStream);
/// Sign the read document with xCertificate in the edit buffer. /// Sign the read document with xCertificate in the edit buffer.
bool Sign(const css::uno::Reference<css::security::XCertificate>& xCertificate, const OUString& rDescription, bool bAdES); bool Sign(const css::uno::Reference<css::security::XCertificate>& xCertificate,
const OUString& rDescription, bool bAdES);
/// Serializes the contents of the edit buffer. /// Serializes the contents of the edit buffer.
bool Write(SvStream& rStream); bool Write(SvStream& rStream);
/// Get a list of signatures embedded into this document. /// Get a list of signatures embedded into this document.
......
...@@ -8009,7 +8009,6 @@ include/vcl/evntpost.hxx ...@@ -8009,7 +8009,6 @@ include/vcl/evntpost.hxx
include/vcl/exceptiontypes.hxx include/vcl/exceptiontypes.hxx
include/vcl/extoutdevdata.hxx include/vcl/extoutdevdata.hxx
include/vcl/field.hxx include/vcl/field.hxx
include/vcl/filter/pdfdocument.hxx
include/vcl/fixed.hxx include/vcl/fixed.hxx
include/vcl/fixedhyper.hxx include/vcl/fixedhyper.hxx
include/vcl/floatwin.hxx include/vcl/floatwin.hxx
...@@ -17652,7 +17651,6 @@ vcl/inc/outdev.h ...@@ -17652,7 +17651,6 @@ vcl/inc/outdev.h
vcl/inc/outdevstatestack.hxx vcl/inc/outdevstatestack.hxx
vcl/inc/pch/precompiled_vcl.cxx vcl/inc/pch/precompiled_vcl.cxx
vcl/inc/pch/precompiled_vcl.hxx vcl/inc/pch/precompiled_vcl.hxx
vcl/inc/pdfread.hxx
vcl/inc/print.h vcl/inc/print.h
vcl/inc/printdlg.hxx vcl/inc/printdlg.hxx
vcl/inc/printerinfomanager.hxx vcl/inc/printerinfomanager.hxx
...@@ -18098,8 +18096,6 @@ vcl/source/filter/igif/decode.cxx ...@@ -18098,8 +18096,6 @@ vcl/source/filter/igif/decode.cxx
vcl/source/filter/igif/decode.hxx vcl/source/filter/igif/decode.hxx
vcl/source/filter/igif/gifread.cxx vcl/source/filter/igif/gifread.cxx
vcl/source/filter/igif/gifread.hxx vcl/source/filter/igif/gifread.hxx
vcl/source/filter/ipdf/pdfdocument.cxx
vcl/source/filter/ipdf/pdfread.cxx
vcl/source/filter/ixbm/xbmread.cxx vcl/source/filter/ixbm/xbmread.cxx
vcl/source/filter/ixbm/xbmread.hxx vcl/source/filter/ixbm/xbmread.hxx
vcl/source/filter/ixpm/rgbtable.hxx vcl/source/filter/ixpm/rgbtable.hxx
...@@ -19669,7 +19665,6 @@ xmlsecurity/inc/pch/precompiled_xsec_gpg.cxx ...@@ -19669,7 +19665,6 @@ xmlsecurity/inc/pch/precompiled_xsec_gpg.cxx
xmlsecurity/inc/pch/precompiled_xsec_gpg.hxx xmlsecurity/inc/pch/precompiled_xsec_gpg.hxx
xmlsecurity/inc/pch/precompiled_xsec_xmlsec.cxx xmlsecurity/inc/pch/precompiled_xsec_xmlsec.cxx
xmlsecurity/inc/pch/precompiled_xsec_xmlsec.hxx xmlsecurity/inc/pch/precompiled_xsec_xmlsec.hxx
xmlsecurity/inc/pdfio/pdfdocument.hxx
xmlsecurity/inc/resourcemanager.hxx xmlsecurity/inc/resourcemanager.hxx
xmlsecurity/inc/xmlsec-wrapper.h xmlsecurity/inc/xmlsec-wrapper.h
xmlsecurity/inc/xmlsec/errorcallback.hxx xmlsecurity/inc/xmlsec/errorcallback.hxx
...@@ -19685,7 +19680,6 @@ xmlsecurity/inc/xsecfwdllapi.h ...@@ -19685,7 +19680,6 @@ xmlsecurity/inc/xsecfwdllapi.h
xmlsecurity/inc/xsecgpgdllapi.h xmlsecurity/inc/xsecgpgdllapi.h
xmlsecurity/inc/xsecxmlsecdllapi.h xmlsecurity/inc/xsecxmlsecdllapi.h
xmlsecurity/qa/certext/SanCertExt.cxx xmlsecurity/qa/certext/SanCertExt.cxx
xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
xmlsecurity/qa/unit/signing/signing.cxx xmlsecurity/qa/unit/signing/signing.cxx
xmlsecurity/qa/unit/xmlsecurity-dialogs-test.cxx xmlsecurity/qa/unit/xmlsecurity-dialogs-test.cxx
xmlsecurity/source/component/certificatecontainer.cxx xmlsecurity/source/component/certificatecontainer.cxx
...@@ -19736,7 +19730,6 @@ xmlsecurity/source/helper/xsecparser.cxx ...@@ -19736,7 +19730,6 @@ xmlsecurity/source/helper/xsecparser.cxx
xmlsecurity/source/helper/xsecparser.hxx xmlsecurity/source/helper/xsecparser.hxx
xmlsecurity/source/helper/xsecsign.cxx xmlsecurity/source/helper/xsecsign.cxx
xmlsecurity/source/helper/xsecverify.cxx xmlsecurity/source/helper/xsecverify.cxx
xmlsecurity/source/pdfio/pdfdocument.cxx
xmlsecurity/source/xmlsec/biginteger.cxx xmlsecurity/source/xmlsec/biginteger.cxx
xmlsecurity/source/xmlsec/certificateextension_certextn.cxx xmlsecurity/source/xmlsec/certificateextension_certextn.cxx
xmlsecurity/source/xmlsec/certificateextension_certextn.hxx xmlsecurity/source/xmlsec/certificateextension_certextn.hxx
...@@ -19789,4 +19782,3 @@ xmlsecurity/source/xmlsec/xmlsec_init.cxx ...@@ -19789,4 +19782,3 @@ xmlsecurity/source/xmlsec/xmlsec_init.cxx
xmlsecurity/source/xmlsec/xmlstreamio.cxx xmlsecurity/source/xmlsec/xmlstreamio.cxx
xmlsecurity/source/xmlsec/xsec_xmlsec.cxx xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
xmlsecurity/source/xmlsec/xsec_xmlsec.hxx xmlsecurity/source/xmlsec/xsec_xmlsec.hxx
xmlsecurity/workben/pdfverify.cxx
...@@ -18,14 +18,12 @@ class Graphic; ...@@ -18,14 +18,12 @@ class Graphic;
namespace vcl namespace vcl
{ {
/// Imports a PDF stream into rGraphic as a GDIMetaFile. /// Imports a PDF stream into rGraphic as a GDIMetaFile.
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap,
css::uno::Sequence<sal_Int8>& rPdfData, css::uno::Sequence<sal_Int8>& rPdfData,
sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN, sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN,
sal_uInt64 nSize = STREAM_SEEK_TO_END); sal_uInt64 nSize = STREAM_SEEK_TO_END);
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic); VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic);
} }
#endif // INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX #endif // INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX
......
...@@ -33,7 +33,6 @@ namespace vcl ...@@ -33,7 +33,6 @@ namespace vcl
{ {
namespace filter namespace filter
{ {
const int MAX_SIGNATURE_CONTENT_LENGTH = 50000; const int MAX_SIGNATURE_CONTENT_LENGTH = 50000;
class PDFTrailerElement; class PDFTrailerElement;
...@@ -56,6 +55,7 @@ class PDFEndDictionaryElement : public PDFElement ...@@ -56,6 +55,7 @@ class PDFEndDictionaryElement : public PDFElement
{ {
/// Offset before the '>>' token. /// Offset before the '>>' token.
sal_uInt64 m_nLocation = 0; sal_uInt64 m_nLocation = 0;
public: public:
PDFEndDictionaryElement(); PDFEndDictionaryElement();
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
...@@ -81,6 +81,7 @@ class PDFEndArrayElement : public PDFElement ...@@ -81,6 +81,7 @@ class PDFEndArrayElement : public PDFElement
{ {
/// Location before the ']' token. /// Location before the ']' token.
sal_uInt64 m_nOffset = 0; sal_uInt64 m_nOffset = 0;
public: public:
PDFEndArrayElement(); PDFEndArrayElement();
bool Read(SvStream& rStream) override; bool Read(SvStream& rStream) override;
...@@ -132,7 +133,8 @@ bool PDFDocument::RemoveSignature(size_t nPosition) ...@@ -132,7 +133,8 @@ bool PDFDocument::RemoveSignature(size_t nPosition)
if (aSignatures.size() != m_aEOFs.size() - 1) if (aSignatures.size() != m_aEOFs.size() - 1)
{ {
SAL_WARN("vcl.filter", "PDFDocument::RemoveSignature: no 1:1 mapping between signatures and incremental updates"); SAL_WARN("vcl.filter", "PDFDocument::RemoveSignature: no 1:1 mapping between signatures "
"and incremental updates");
return false; return false;
} }
...@@ -165,7 +167,9 @@ sal_uInt32 PDFDocument::GetNextSignature() ...@@ -165,7 +167,9 @@ sal_uInt32 PDFDocument::GetNextSignature()
return nRet + 1; return nRet + 1;
} }
sal_Int32 PDFDocument::WriteSignatureObject(const OUString& rDescription, bool bAdES, sal_uInt64& rLastByteRangeOffset, sal_Int64& rContentOffset) sal_Int32 PDFDocument::WriteSignatureObject(const OUString& rDescription, bool bAdES,
sal_uInt64& rLastByteRangeOffset,
sal_Int64& rContentOffset)
{ {
// Write signature object. // Write signature object.
sal_Int32 nSignatureId = m_aXRef.size(); sal_Int32 nSignatureId = m_aXRef.size();
...@@ -240,7 +244,8 @@ sal_Int32 PDFDocument::WriteAppearanceObject() ...@@ -240,7 +244,8 @@ sal_Int32 PDFDocument::WriteAppearanceObject()
return nAppearanceId; return nAppearanceId;
} }
sal_Int32 PDFDocument::WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_Int32 nSignatureId, sal_Int32 nAppearanceId) sal_Int32 PDFDocument::WriteAnnotObject(PDFObjectElement const& rFirstPage, sal_Int32 nSignatureId,
sal_Int32 nAppearanceId)
{ {
// Decide what identifier to use for the new signature. // Decide what identifier to use for the new signature.
sal_uInt32 nNextSignature = GetNextSignature(); sal_uInt32 nNextSignature = GetNextSignature();
...@@ -341,7 +346,9 @@ bool PDFDocument::WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnot ...@@ -341,7 +346,9 @@ bool PDFDocument::WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnot
if (!pAnnotsArray) if (!pAnnotsArray)
{ {
// No Annots key, just write the key with a single reference. // No Annots key, just write the key with a single reference.
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + rFirstPage.GetDictionaryOffset(), rFirstPage.GetDictionaryLength()); m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ rFirstPage.GetDictionaryOffset(),
rFirstPage.GetDictionaryLength());
m_aEditBuffer.WriteCharPtr("/Annots["); m_aEditBuffer.WriteCharPtr("/Annots[");
m_aEditBuffer.WriteUInt32AsString(nAnnotId); m_aEditBuffer.WriteUInt32AsString(nAnnotId);
m_aEditBuffer.WriteCharPtr(" 0 R]"); m_aEditBuffer.WriteCharPtr(" 0 R]");
...@@ -352,16 +359,23 @@ bool PDFDocument::WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnot ...@@ -352,16 +359,23 @@ bool PDFDocument::WritePageObject(PDFObjectElement& rFirstPage, sal_Int32 nAnnot
PDFDictionaryElement* pDictionary = rFirstPage.GetDictionary(); PDFDictionaryElement* pDictionary = rFirstPage.GetDictionary();
// Offset right before the end of the Annots array. // Offset right before the end of the Annots array.
sal_uInt64 nAnnotsEndOffset = pDictionary->GetKeyOffset("Annots") + pDictionary->GetKeyValueLength("Annots") - 1; sal_uInt64 nAnnotsEndOffset = pDictionary->GetKeyOffset("Annots")
+ pDictionary->GetKeyValueLength("Annots") - 1;
// Length of beginning of the dictionary -> Annots end. // Length of beginning of the dictionary -> Annots end.
sal_uInt64 nAnnotsBeforeEndLength = nAnnotsEndOffset - rFirstPage.GetDictionaryOffset(); sal_uInt64 nAnnotsBeforeEndLength = nAnnotsEndOffset - rFirstPage.GetDictionaryOffset();
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + rFirstPage.GetDictionaryOffset(), nAnnotsBeforeEndLength); m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ rFirstPage.GetDictionaryOffset(),
nAnnotsBeforeEndLength);
m_aEditBuffer.WriteCharPtr(" "); m_aEditBuffer.WriteCharPtr(" ");
m_aEditBuffer.WriteUInt32AsString(nAnnotId); m_aEditBuffer.WriteUInt32AsString(nAnnotId);
m_aEditBuffer.WriteCharPtr(" 0 R"); m_aEditBuffer.WriteCharPtr(" 0 R");
// Length of Annots end -> end of the dictionary. // Length of Annots end -> end of the dictionary.
sal_uInt64 nAnnotsAfterEndLength = rFirstPage.GetDictionaryOffset() + rFirstPage.GetDictionaryLength() - nAnnotsEndOffset; sal_uInt64 nAnnotsAfterEndLength = rFirstPage.GetDictionaryOffset()
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + nAnnotsEndOffset, nAnnotsAfterEndLength); + rFirstPage.GetDictionaryLength()
- nAnnotsEndOffset;
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ nAnnotsEndOffset,
nAnnotsAfterEndLength);
} }
m_aEditBuffer.WriteCharPtr(">>"); m_aEditBuffer.WriteCharPtr(">>");
m_aEditBuffer.WriteCharPtr("\nendobj\n\n"); m_aEditBuffer.WriteCharPtr("\nendobj\n\n");
...@@ -424,7 +438,8 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p ...@@ -424,7 +438,8 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p
if (!pAcroFormObject->Lookup("Fields")) if (!pAcroFormObject->Lookup("Fields"))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Sign: AcroForm object without required Fields key"); SAL_WARN("vcl.filter",
"PDFDocument::Sign: AcroForm object without required Fields key");
return false; return false;
} }
...@@ -436,7 +451,9 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p ...@@ -436,7 +451,9 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p
} }
// Offset right before the end of the Fields array. // Offset right before the end of the Fields array.
sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields") + pAcroFormDictionary->GetKeyValueLength("Fields") - strlen("]"); sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields")
+ pAcroFormDictionary->GetKeyValueLength("Fields")
- strlen("]");
// Length of beginning of the object dictionary -> Fields end. // Length of beginning of the object dictionary -> Fields end.
sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset; sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset;
if (pStreamBuffer) if (pStreamBuffer)
...@@ -445,7 +462,9 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p ...@@ -445,7 +462,9 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p
{ {
nFieldsBeforeEndLength -= pAcroFormObject->GetDictionaryOffset(); nFieldsBeforeEndLength -= pAcroFormObject->GetDictionaryOffset();
m_aEditBuffer.WriteCharPtr("<<"); m_aEditBuffer.WriteCharPtr("<<");
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + pAcroFormObject->GetDictionaryOffset(), nFieldsBeforeEndLength); m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ pAcroFormObject->GetDictionaryOffset(),
nFieldsBeforeEndLength);
} }
// Append our reference at the end of the Fields array. // Append our reference at the end of the Fields array.
...@@ -457,12 +476,18 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p ...@@ -457,12 +476,18 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p
if (pStreamBuffer) if (pStreamBuffer)
{ {
sal_uInt64 nFieldsAfterEndLength = pStreamBuffer->GetSize() - nFieldsEndOffset; sal_uInt64 nFieldsAfterEndLength = pStreamBuffer->GetSize() - nFieldsEndOffset;
m_aEditBuffer.WriteBytes(static_cast<const char*>(pStreamBuffer->GetData()) + nFieldsEndOffset, nFieldsAfterEndLength); m_aEditBuffer.WriteBytes(static_cast<const char*>(pStreamBuffer->GetData())
+ nFieldsEndOffset,
nFieldsAfterEndLength);
} }
else else
{ {
sal_uInt64 nFieldsAfterEndLength = pAcroFormObject->GetDictionaryOffset() + pAcroFormObject->GetDictionaryLength() - nFieldsEndOffset; sal_uInt64 nFieldsAfterEndLength = pAcroFormObject->GetDictionaryOffset()
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + nFieldsEndOffset, nFieldsAfterEndLength); + pAcroFormObject->GetDictionaryLength()
- nFieldsEndOffset;
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ nFieldsEndOffset,
nFieldsAfterEndLength);
m_aEditBuffer.WriteCharPtr(">>"); m_aEditBuffer.WriteCharPtr(">>");
} }
...@@ -480,7 +505,9 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p ...@@ -480,7 +505,9 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p
if (!pAcroFormDictionary) if (!pAcroFormDictionary)
{ {
// No AcroForm key, assume no signatures. // No AcroForm key, assume no signatures.
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + pCatalog->GetDictionaryOffset(), pCatalog->GetDictionaryLength()); m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ pCatalog->GetDictionaryOffset(),
pCatalog->GetDictionaryLength());
m_aEditBuffer.WriteCharPtr("/AcroForm<</Fields[\n"); m_aEditBuffer.WriteCharPtr("/AcroForm<</Fields[\n");
m_aEditBuffer.WriteUInt32AsString(nAnnotId); m_aEditBuffer.WriteUInt32AsString(nAnnotId);
m_aEditBuffer.WriteCharPtr(" 0 R\n]/SigFlags 3>>\n"); m_aEditBuffer.WriteCharPtr(" 0 R\n]/SigFlags 3>>\n");
...@@ -503,16 +530,22 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p ...@@ -503,16 +530,22 @@ bool PDFDocument::WriteCatalogObject(sal_Int32 nAnnotId, PDFReferenceElement*& p
} }
// Offset right before the end of the Fields array. // Offset right before the end of the Fields array.
sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields") + pAcroFormDictionary->GetKeyValueLength("Fields") - 1; sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields")
+ pAcroFormDictionary->GetKeyValueLength("Fields") - 1;
// Length of beginning of the Catalog dictionary -> Fields end. // Length of beginning of the Catalog dictionary -> Fields end.
sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset - pCatalog->GetDictionaryOffset(); sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset - pCatalog->GetDictionaryOffset();
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + pCatalog->GetDictionaryOffset(), nFieldsBeforeEndLength); m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ pCatalog->GetDictionaryOffset(),
nFieldsBeforeEndLength);
m_aEditBuffer.WriteCharPtr(" "); m_aEditBuffer.WriteCharPtr(" ");
m_aEditBuffer.WriteUInt32AsString(nAnnotId); m_aEditBuffer.WriteUInt32AsString(nAnnotId);
m_aEditBuffer.WriteCharPtr(" 0 R"); m_aEditBuffer.WriteCharPtr(" 0 R");
// Length of Fields end -> end of the Catalog dictionary. // Length of Fields end -> end of the Catalog dictionary.
sal_uInt64 nFieldsAfterEndLength = pCatalog->GetDictionaryOffset() + pCatalog->GetDictionaryLength() - nFieldsEndOffset; sal_uInt64 nFieldsAfterEndLength = pCatalog->GetDictionaryOffset()
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + nFieldsEndOffset, nFieldsAfterEndLength); + pCatalog->GetDictionaryLength() - nFieldsEndOffset;
m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData())
+ nFieldsEndOffset,
nFieldsAfterEndLength);
} }
m_aEditBuffer.WriteCharPtr(">>\nendobj\n\n"); m_aEditBuffer.WriteCharPtr(">>\nendobj\n\n");
} }
...@@ -559,15 +592,15 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p ...@@ -559,15 +592,15 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p
unsigned char nType = 0; unsigned char nType = 0;
switch (rEntry.m_eType) switch (rEntry.m_eType)
{ {
case XRefEntryType::FREE: case XRefEntryType::FREE:
nType = 0; nType = 0;
break; break;
case XRefEntryType::NOT_COMPRESSED: case XRefEntryType::NOT_COMPRESSED:
nType = 1; nType = 1;
break; break;
case XRefEntryType::COMPRESSED: case XRefEntryType::COMPRESSED:
nType = 2; nType = 2;
break; break;
} }
aOrigLine[nPos++] = nType; aOrigLine[nPos++] = nType;
...@@ -598,7 +631,8 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p ...@@ -598,7 +631,8 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p
} }
m_aEditBuffer.WriteUInt32AsString(nXRefStreamId); m_aEditBuffer.WriteUInt32AsString(nXRefStreamId);
m_aEditBuffer.WriteCharPtr(" 0 obj\n<</DecodeParms<</Columns 5/Predictor 12>>/Filter/FlateDecode"); m_aEditBuffer.WriteCharPtr(
" 0 obj\n<</DecodeParms<</Columns 5/Predictor 12>>/Filter/FlateDecode");
// ID. // ID.
auto pID = dynamic_cast<PDFArrayElement*>(m_pXRefStream->Lookup("ID")); auto pID = dynamic_cast<PDFArrayElement*>(m_pXRefStream->Lookup("ID"));
...@@ -751,14 +785,16 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p ...@@ -751,14 +785,16 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p
} }
} }
bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificate, const OUString& rDescription, bool bAdES) bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificate,
const OUString& rDescription, bool bAdES)
{ {
m_aEditBuffer.Seek(STREAM_SEEK_TO_END); m_aEditBuffer.Seek(STREAM_SEEK_TO_END);
m_aEditBuffer.WriteCharPtr("\n"); m_aEditBuffer.WriteCharPtr("\n");
sal_uInt64 nSignatureLastByteRangeOffset = 0; sal_uInt64 nSignatureLastByteRangeOffset = 0;
sal_Int64 nSignatureContentOffset = 0; sal_Int64 nSignatureContentOffset = 0;
sal_Int32 nSignatureId = WriteSignatureObject(rDescription, bAdES, nSignatureLastByteRangeOffset, nSignatureContentOffset); sal_Int32 nSignatureId = WriteSignatureObject(
rDescription, bAdES, nSignatureLastByteRangeOffset, nSignatureContentOffset);
sal_Int32 nAppearanceId = WriteAppearanceObject(); sal_Int32 nAppearanceId = WriteAppearanceObject();
...@@ -796,7 +832,8 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat ...@@ -796,7 +832,8 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
// Finalize the signature, now that we know the total file size. // Finalize the signature, now that we know the total file size.
// Calculate the length of the last byte range. // Calculate the length of the last byte range.
sal_uInt64 nFileEnd = m_aEditBuffer.Tell(); sal_uInt64 nFileEnd = m_aEditBuffer.Tell();
sal_Int64 nLastByteRangeLength = nFileEnd - (nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1); sal_Int64 nLastByteRangeLength
= nFileEnd - (nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1);
// Write the length to the buffer. // Write the length to the buffer.
m_aEditBuffer.Seek(nSignatureLastByteRangeOffset); m_aEditBuffer.Seek(nSignatureLastByteRangeOffset);
OStringBuffer aByteRangeBuffer; OStringBuffer aByteRangeBuffer;
...@@ -847,7 +884,9 @@ bool PDFDocument::Write(SvStream& rStream) ...@@ -847,7 +884,9 @@ bool PDFDocument::Write(SvStream& rStream)
return rStream.good(); return rStream.good();
} }
bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< std::unique_ptr<PDFElement> >& rElements, PDFObjectElement* pObjectElement) bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode,
std::vector<std::unique_ptr<PDFElement>>& rElements,
PDFObjectElement* pObjectElement)
{ {
// Last seen object token. // Last seen object token.
PDFObjectElement* pObject = pObjectElement; PDFObjectElement* pObject = pObjectElement;
...@@ -873,322 +912,346 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s ...@@ -873,322 +912,346 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
switch (ch) switch (ch)
{ {
case '%': case '%':
{
auto pComment = new PDFCommentElement(*this);
rElements.push_back(std::unique_ptr<PDFElement>(pComment));
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFCommentElement::Read() failed");
return false;
}
if (eMode == TokenizeMode::EOF_TOKEN && !m_aEOFs.empty() && m_aEOFs.back() == rStream.Tell())
{
// Found EOF and partial parsing requested, we're done.
return true;
}
break;
}
case '<':
{
// Dictionary or hex string.
rStream.ReadChar(ch);
rStream.SeekRel(-2);
if (ch == '<')
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFDictionaryElement()));
++nDictionaryDepth;
}
else
rElements.push_back(std::unique_ptr<PDFElement>(new PDFHexStringElement));
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFDictionaryElement::Read() failed");
return false;
}
break;
}
case '>':
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndDictionaryElement()));
--nDictionaryDepth;
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFEndDictionaryElement::Read() failed");
return false;
}
break;
}
case '[':
{
auto pArr = new PDFArrayElement(pObject);
rElements.push_back(std::unique_ptr<PDFElement>(pArr));
if (nDictionaryDepth == 0 && nArrayDepth == 0)
{ {
// The array is attached directly, inform the object. auto pComment = new PDFCommentElement(*this);
pArray = pArr; rElements.push_back(std::unique_ptr<PDFElement>(pComment));
if (pObject) rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{ {
pObject->SetArray(pArray); SAL_WARN("vcl.filter",
pObject->SetArrayOffset(rStream.Tell()); "PDFDocument::Tokenize: PDFCommentElement::Read() failed");
return false;
} }
if (eMode == TokenizeMode::EOF_TOKEN && !m_aEOFs.empty()
&& m_aEOFs.back() == rStream.Tell())
{
// Found EOF and partial parsing requested, we're done.
return true;
}
break;
} }
++nArrayDepth; case '<':
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFArrayElement::Read() failed"); // Dictionary or hex string.
return false; rStream.ReadChar(ch);
} rStream.SeekRel(-2);
break; if (ch == '<')
}
case ']':
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndArrayElement()));
--nArrayDepth;
if (nArrayDepth == 0)
pArray = nullptr;
rStream.SeekRel(-1);
if (nDictionaryDepth == 0 && nArrayDepth == 0)
{
if (pObject)
{ {
pObject->SetArrayLength(rStream.Tell() - pObject->GetArrayOffset()); rElements.push_back(std::unique_ptr<PDFElement>(new PDFDictionaryElement()));
++nDictionaryDepth;
}
else
rElements.push_back(std::unique_ptr<PDFElement>(new PDFHexStringElement));
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFDictionaryElement::Read() failed");
return false;
} }
break;
} }
if (!rElements.back()->Read(rStream)) case '>':
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFEndArrayElement::Read() failed"); rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndDictionaryElement()));
return false; --nDictionaryDepth;
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFEndDictionaryElement::Read() failed");
return false;
}
break;
} }
break; case '[':
}
case '/':
{
auto pNameElement = new PDFNameElement();
rElements.push_back(std::unique_ptr<PDFElement>(pNameElement));
rStream.SeekRel(-1);
if (!pNameElement->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFNameElement::Read() failed"); auto pArr = new PDFArrayElement(pObject);
return false; rElements.push_back(std::unique_ptr<PDFElement>(pArr));
if (nDictionaryDepth == 0 && nArrayDepth == 0)
{
// The array is attached directly, inform the object.
pArray = pArr;
if (pObject)
{
pObject->SetArray(pArray);
pObject->SetArrayOffset(rStream.Tell());
}
}
++nArrayDepth;
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFArrayElement::Read() failed");
return false;
}
break;
} }
if (pObject && pObjectKey && pObjectKey->GetValue() == "Type" && pNameElement->GetValue() == "ObjStm") case ']':
pObjectStream = pObject;
else
pObjectKey = pNameElement;
break;
}
case '(':
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFLiteralStringElement));
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFLiteralStringElement::Read() failed"); rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndArrayElement()));
return false; --nArrayDepth;
if (nArrayDepth == 0)
pArray = nullptr;
rStream.SeekRel(-1);
if (nDictionaryDepth == 0 && nArrayDepth == 0)
{
if (pObject)
{
pObject->SetArrayLength(rStream.Tell() - pObject->GetArrayOffset());
}
}
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFEndArrayElement::Read() failed");
return false;
}
break;
} }
break; case '/':
}
default:
{
if (rtl::isAsciiDigit(static_cast<unsigned char>(ch)) || ch == '-')
{ {
// Numbering object: an integer or a real. auto pNameElement = new PDFNameElement();
auto pNumberElement = new PDFNumberElement(); rElements.push_back(std::unique_ptr<PDFElement>(pNameElement));
rElements.push_back(std::unique_ptr<PDFElement>(pNumberElement));
rStream.SeekRel(-1); rStream.SeekRel(-1);
if (!pNumberElement->Read(rStream)) if (!pNameElement->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFNumberElement::Read() failed"); SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFNameElement::Read() failed");
return false; return false;
} }
if (bInStartXRef) if (pObject && pObjectKey && pObjectKey->GetValue() == "Type"
&& pNameElement->GetValue() == "ObjStm")
pObjectStream = pObject;
else
pObjectKey = pNameElement;
break;
}
case '(':
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFLiteralStringElement));
rStream.SeekRel(-1);
if (!rElements.back()->Read(rStream))
{ {
bInStartXRef = false; SAL_WARN("vcl.filter",
m_aStartXRefs.push_back(pNumberElement->GetValue()); "PDFDocument::Tokenize: PDFLiteralStringElement::Read() failed");
return false;
auto it = m_aOffsetObjects.find(pNumberElement->GetValue());
if (it != m_aOffsetObjects.end())
m_pXRefStream = it->second;
} }
else if (bInObject && !nDictionaryDepth && !nArrayDepth && pObject) break;
// Number element inside an object, but outside a
// dictionary / array: remember it.
pObject->SetNumberElement(pNumberElement);
} }
else if (rtl::isAsciiAlpha(static_cast<unsigned char>(ch))) default:
{ {
// Possible keyword, like "obj". if (rtl::isAsciiDigit(static_cast<unsigned char>(ch)) || ch == '-')
rStream.SeekRel(-1);
OString aKeyword = ReadKeyword(rStream);
bool bObj = aKeyword == "obj";
if (bObj || aKeyword == "R")
{ {
size_t nElements = rElements.size(); // Numbering object: an integer or a real.
if (nElements < 2) auto pNumberElement = new PDFNumberElement();
rElements.push_back(std::unique_ptr<PDFElement>(pNumberElement));
rStream.SeekRel(-1);
if (!pNumberElement->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: expected at least two tokens before 'obj' or 'R' keyword"); SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFNumberElement::Read() failed");
return false; return false;
} }
if (bInStartXRef)
auto pObjectNumber = dynamic_cast<PDFNumberElement*>(rElements[nElements - 2].get());
auto pGenerationNumber = dynamic_cast<PDFNumberElement*>(rElements[nElements - 1].get());
if (!pObjectNumber || !pGenerationNumber)
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: missing object or generation number before 'obj' or 'R' keyword"); bInStartXRef = false;
return false; m_aStartXRefs.push_back(pNumberElement->GetValue());
}
if (bObj) auto it = m_aOffsetObjects.find(pNumberElement->GetValue());
{ if (it != m_aOffsetObjects.end())
pObject = new PDFObjectElement(*this, pObjectNumber->GetValue(), pGenerationNumber->GetValue()); m_pXRefStream = it->second;
rElements.push_back(std::unique_ptr<PDFElement>(pObject));
m_aOffsetObjects[pObjectNumber->GetLocation()] = pObject;
m_aIDObjects[pObjectNumber->GetValue()] = pObject;
bInObject = true;
}
else
{
auto pReference = new PDFReferenceElement(*this, *pObjectNumber, *pGenerationNumber);
rElements.push_back(std::unique_ptr<PDFElement>(pReference));
if (pArray)
// Reference is part of a direct (non-dictionary) array, inform the array.
pArray->PushBack(rElements.back().get());
if (bInObject && nDictionaryDepth > 0 && pObject)
// Inform the object about a new in-dictionary reference.
pObject->AddDictionaryReference(pReference);
}
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFElement::Read() failed");
return false;
} }
else if (bInObject && !nDictionaryDepth && !nArrayDepth && pObject)
// Number element inside an object, but outside a
// dictionary / array: remember it.
pObject->SetNumberElement(pNumberElement);
} }
else if (aKeyword == "stream") else if (rtl::isAsciiAlpha(static_cast<unsigned char>(ch)))
{ {
// Look up the length of the stream from the parent object's dictionary. // Possible keyword, like "obj".
size_t nLength = 0; rStream.SeekRel(-1);
for (size_t nElement = 0; nElement < rElements.size(); ++nElement) OString aKeyword = ReadKeyword(rStream);
bool bObj = aKeyword == "obj";
if (bObj || aKeyword == "R")
{ {
// Iterate in reverse order. size_t nElements = rElements.size();
size_t nIndex = rElements.size() - nElement - 1; if (nElements < 2)
PDFElement* pElement = rElements[nIndex].get();
auto pObj = dynamic_cast<PDFObjectElement*>(pElement);
if (!pObj)
continue;
PDFElement* pLookup = pObj->Lookup("Length");
auto pReference = dynamic_cast<PDFReferenceElement*>(pLookup);
if (pReference)
{ {
// Length is provided as a reference. SAL_WARN("vcl.filter", "PDFDocument::Tokenize: expected at least two "
nLength = pReference->LookupNumber(rStream); "tokens before 'obj' or 'R' keyword");
break; return false;
} }
auto pNumber = dynamic_cast<PDFNumberElement*>(pLookup); auto pObjectNumber
if (pNumber) = dynamic_cast<PDFNumberElement*>(rElements[nElements - 2].get());
auto pGenerationNumber
= dynamic_cast<PDFNumberElement*>(rElements[nElements - 1].get());
if (!pObjectNumber || !pGenerationNumber)
{ {
// Length is provided directly. SAL_WARN("vcl.filter", "PDFDocument::Tokenize: missing object or "
nLength = pNumber->GetValue(); "generation number before 'obj' or 'R' keyword");
break; return false;
} }
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: found no Length key for stream keyword"); if (bObj)
return false; {
pObject = new PDFObjectElement(*this, pObjectNumber->GetValue(),
pGenerationNumber->GetValue());
rElements.push_back(std::unique_ptr<PDFElement>(pObject));
m_aOffsetObjects[pObjectNumber->GetLocation()] = pObject;
m_aIDObjects[pObjectNumber->GetValue()] = pObject;
bInObject = true;
}
else
{
auto pReference = new PDFReferenceElement(*this, *pObjectNumber,
*pGenerationNumber);
rElements.push_back(std::unique_ptr<PDFElement>(pReference));
if (pArray)
// Reference is part of a direct (non-dictionary) array, inform the array.
pArray->PushBack(rElements.back().get());
if (bInObject && nDictionaryDepth > 0 && pObject)
// Inform the object about a new in-dictionary reference.
pObject->AddDictionaryReference(pReference);
}
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFElement::Read() failed");
return false;
}
} }
else if (aKeyword == "stream")
PDFDocument::SkipLineBreaks(rStream);
auto pStreamElement = new PDFStreamElement(nLength);
if (pObject)
pObject->SetStream(pStreamElement);
rElements.push_back(std::unique_ptr<PDFElement>(pStreamElement));
if (!rElements.back()->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFStreamElement::Read() failed"); // Look up the length of the stream from the parent object's dictionary.
return false; size_t nLength = 0;
for (size_t nElement = 0; nElement < rElements.size(); ++nElement)
{
// Iterate in reverse order.
size_t nIndex = rElements.size() - nElement - 1;
PDFElement* pElement = rElements[nIndex].get();
auto pObj = dynamic_cast<PDFObjectElement*>(pElement);
if (!pObj)
continue;
PDFElement* pLookup = pObj->Lookup("Length");
auto pReference = dynamic_cast<PDFReferenceElement*>(pLookup);
if (pReference)
{
// Length is provided as a reference.
nLength = pReference->LookupNumber(rStream);
break;
}
auto pNumber = dynamic_cast<PDFNumberElement*>(pLookup);
if (pNumber)
{
// Length is provided directly.
nLength = pNumber->GetValue();
break;
}
SAL_WARN(
"vcl.filter",
"PDFDocument::Tokenize: found no Length key for stream keyword");
return false;
}
PDFDocument::SkipLineBreaks(rStream);
auto pStreamElement = new PDFStreamElement(nLength);
if (pObject)
pObject->SetStream(pStreamElement);
rElements.push_back(std::unique_ptr<PDFElement>(pStreamElement));
if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFStreamElement::Read() failed");
return false;
}
} }
} else if (aKeyword == "endstream")
else if (aKeyword == "endstream")
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndStreamElement));
if (!rElements.back()->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFEndStreamElement::Read() failed"); rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndStreamElement));
return false; if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFEndStreamElement::Read() failed");
return false;
}
} }
} else if (aKeyword == "endobj")
else if (aKeyword == "endobj")
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndObjectElement));
if (!rElements.back()->Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: PDFEndObjectElement::Read() failed"); rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndObjectElement));
return false; if (!rElements.back()->Read(rStream))
{
SAL_WARN("vcl.filter",
"PDFDocument::Tokenize: PDFEndObjectElement::Read() failed");
return false;
}
if (eMode == TokenizeMode::END_OF_OBJECT)
{
// Found endobj and only object parsing was requested, we're done.
return true;
}
if (pObjectStream)
{
// We're at the end of an object stream, parse the stored objects.
pObjectStream->ParseStoredObjects();
pObjectStream = nullptr;
pObjectKey = nullptr;
}
bInObject = false;
} }
if (eMode == TokenizeMode::END_OF_OBJECT) else if (aKeyword == "true" || aKeyword == "false")
rElements.push_back(std::unique_ptr<PDFElement>(
new PDFBooleanElement(aKeyword.toBoolean())));
else if (aKeyword == "null")
rElements.push_back(std::unique_ptr<PDFElement>(new PDFNullElement));
else if (aKeyword == "xref")
// Allow 'f' and 'n' keywords.
bInXRef = true;
else if (bInXRef && (aKeyword == "f" || aKeyword == "n"))
{ {
// Found endobj and only object parsing was requested, we're done.
return true;
} }
else if (aKeyword == "trailer")
if (pObjectStream)
{ {
// We're at the end of an object stream, parse the stored objects. auto pTrailer = new PDFTrailerElement(*this);
pObjectStream->ParseStoredObjects();
pObjectStream = nullptr;
pObjectKey = nullptr;
}
bInObject = false;
}
else if (aKeyword == "true" || aKeyword == "false")
rElements.push_back(std::unique_ptr<PDFElement>(new PDFBooleanElement(aKeyword.toBoolean())));
else if (aKeyword == "null")
rElements.push_back(std::unique_ptr<PDFElement>(new PDFNullElement));
else if (aKeyword == "xref")
// Allow 'f' and 'n' keywords.
bInXRef = true;
else if (bInXRef && (aKeyword == "f" || aKeyword == "n"))
{
}
else if (aKeyword == "trailer")
{
auto pTrailer = new PDFTrailerElement(*this);
// Make it possible to find this trailer later by offset. // Make it possible to find this trailer later by offset.
pTrailer->Read(rStream); pTrailer->Read(rStream);
m_aOffsetTrailers[pTrailer->GetLocation()] = pTrailer; m_aOffsetTrailers[pTrailer->GetLocation()] = pTrailer;
// When reading till the first EOF token only, remember // When reading till the first EOF token only, remember
// just the first trailer token. // just the first trailer token.
if (eMode != TokenizeMode::EOF_TOKEN || !m_pTrailer) if (eMode != TokenizeMode::EOF_TOKEN || !m_pTrailer)
m_pTrailer = pTrailer; m_pTrailer = pTrailer;
rElements.push_back(std::unique_ptr<PDFElement>(pTrailer)); rElements.push_back(std::unique_ptr<PDFElement>(pTrailer));
} }
else if (aKeyword == "startxref") else if (aKeyword == "startxref")
{ {
bInStartXRef = true; bInStartXRef = true;
}
else
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: unexpected '"
<< aKeyword << "' keyword at byte position "
<< rStream.Tell());
return false;
}
} }
else else
{ {
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: unexpected '" << aKeyword << "' keyword at byte position " << rStream.Tell()); if (!rtl::isAsciiWhiteSpace(static_cast<unsigned char>(ch)))
return false; {
} SAL_WARN("vcl.filter", "PDFDocument::Tokenize: unexpected character: "
} << ch << " at byte position " << rStream.Tell());
else return false;
{ }
if (!rtl::isAsciiWhiteSpace(static_cast<unsigned char>(ch)))
{
SAL_WARN("vcl.filter", "PDFDocument::Tokenize: unexpected character: " << ch << " at byte position " << rStream.Tell());
return false;
} }
break;
} }
break;
}
} }
} }
...@@ -1206,7 +1269,8 @@ bool PDFDocument::Read(SvStream& rStream) ...@@ -1206,7 +1269,8 @@ bool PDFDocument::Read(SvStream& rStream)
std::vector<sal_Int8> aHeader(5); std::vector<sal_Int8> aHeader(5);
rStream.Seek(0); rStream.Seek(0);
rStream.ReadBytes(aHeader.data(), aHeader.size()); rStream.ReadBytes(aHeader.data(), aHeader.size());
if (aHeader[0] != '%' || aHeader[1] != 'P' || aHeader[2] != 'D' || aHeader[3] != 'F' || aHeader[4] != '-') if (aHeader[0] != '%' || aHeader[1] != 'P' || aHeader[2] != 'D' || aHeader[3] != 'F'
|| aHeader[4] != '-')
{ {
SAL_WARN("vcl.filter", "PDFDocument::Read: header mismatch"); SAL_WARN("vcl.filter", "PDFDocument::Read: header mismatch");
return false; return false;
...@@ -1332,7 +1396,8 @@ size_t PDFDocument::FindStartXRef(SvStream& rStream) ...@@ -1332,7 +1396,8 @@ size_t PDFDocument::FindStartXRef(SvStream& rStream)
rStream.SeekRel(itLastValid - aBuf.begin() + aPrefix.getLength()); rStream.SeekRel(itLastValid - aBuf.begin() + aPrefix.getLength());
if (rStream.eof()) if (rStream.eof())
{ {
SAL_WARN("vcl.filter", "PDFDocument::FindStartXRef: unexpected end of stream after startxref"); SAL_WARN("vcl.filter",
"PDFDocument::FindStartXRef: unexpected end of stream after startxref");
return 0; return 0;
} }
...@@ -1415,7 +1480,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1415,7 +1480,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
if (pFilter->GetValue() != "FlateDecode") if (pFilter->GetValue() != "FlateDecode")
{ {
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: unexpected filter: " << pFilter->GetValue()); SAL_WARN("vcl.filter",
"PDFDocument::ReadXRefStream: unexpected filter: " << pFilter->GetValue());
return; return;
} }
...@@ -1474,7 +1540,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1474,7 +1540,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
auto pFirstObject = dynamic_cast<PDFNumberElement*>(rIndexElements[i]); auto pFirstObject = dynamic_cast<PDFNumberElement*>(rIndexElements[i]);
if (!pFirstObject) if (!pFirstObject)
{ {
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: Index has no first object"); SAL_WARN("vcl.filter",
"PDFDocument::ReadXRefStream: Index has no first object");
return; return;
} }
nFirstObject = pFirstObject->GetValue(); nFirstObject = pFirstObject->GetValue();
...@@ -1484,7 +1551,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1484,7 +1551,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
auto pNumberOfObjects = dynamic_cast<PDFNumberElement*>(rIndexElements[i]); auto pNumberOfObjects = dynamic_cast<PDFNumberElement*>(rIndexElements[i]);
if (!pNumberOfObjects) if (!pNumberOfObjects)
{ {
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: Index has no number of objects"); SAL_WARN("vcl.filter",
"PDFDocument::ReadXRefStream: Index has no number of objects");
return; return;
} }
aFirstObjects.push_back(nFirstObject); aFirstObjects.push_back(nFirstObject);
...@@ -1517,7 +1585,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1517,7 +1585,8 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
if (nPredictor > 1 && nLineLength - 1 != nColumns) if (nPredictor > 1 && nLineLength - 1 != nColumns)
{ {
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: /DecodeParms/Columns is inconsistent with /W"); SAL_WARN("vcl.filter",
"PDFDocument::ReadXRefStream: /DecodeParms/Columns is inconsistent with /W");
return; return;
} }
...@@ -1538,7 +1607,9 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1538,7 +1607,9 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
aStream.ReadBytes(aOrigLine.data(), aOrigLine.size()); aStream.ReadBytes(aOrigLine.data(), aOrigLine.size());
if (nPredictor > 1 && aOrigLine[0] + 10 != nPredictor) if (nPredictor > 1 && aOrigLine[0] + 10 != nPredictor)
{ {
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: in-stream predictor is inconsistent with /DecodeParms/Predictor for object #" << nIndex); SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: in-stream predictor is "
"inconsistent with /DecodeParms/Predictor for object #"
<< nIndex);
return; return;
} }
...@@ -1546,17 +1617,18 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1546,17 +1617,18 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
{ {
switch (nPredictor) switch (nPredictor)
{ {
case 1: case 1:
// No prediction. // No prediction.
break; break;
case 12: case 12:
// PNG prediction: up (on all rows). // PNG prediction: up (on all rows).
aFilteredLine[i] = aFilteredLine[i] + aOrigLine[i]; aFilteredLine[i] = aFilteredLine[i] + aOrigLine[i];
break; break;
default: default:
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: unexpected predictor: " << nPredictor); SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: unexpected predictor: "
return; << nPredictor);
break; return;
break;
} }
} }
...@@ -1597,15 +1669,15 @@ void PDFDocument::ReadXRefStream(SvStream& rStream) ...@@ -1597,15 +1669,15 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
XRefEntry aEntry; XRefEntry aEntry;
switch (nType) switch (nType)
{ {
case 0: case 0:
aEntry.m_eType = XRefEntryType::FREE; aEntry.m_eType = XRefEntryType::FREE;
break; break;
case 1: case 1:
aEntry.m_eType = XRefEntryType::NOT_COMPRESSED; aEntry.m_eType = XRefEntryType::NOT_COMPRESSED;
break; break;
case 2: case 2:
aEntry.m_eType = XRefEntryType::COMPRESSED; aEntry.m_eType = XRefEntryType::COMPRESSED;
break; break;
} }
aEntry.m_nOffset = nStreamOffset; aEntry.m_nOffset = nStreamOffset;
m_aXRef[nIndex] = aEntry; m_aXRef[nIndex] = aEntry;
...@@ -1732,17 +1804,15 @@ size_t PDFDocument::GetObjectOffset(size_t nIndex) const ...@@ -1732,17 +1804,15 @@ size_t PDFDocument::GetObjectOffset(size_t nIndex) const
auto it = m_aXRef.find(nIndex); auto it = m_aXRef.find(nIndex);
if (it == m_aXRef.end() || it->second.m_eType == XRefEntryType::COMPRESSED) if (it == m_aXRef.end() || it->second.m_eType == XRefEntryType::COMPRESSED)
{ {
SAL_WARN("vcl.filter", "PDFDocument::GetObjectOffset: wanted to look up index #" << nIndex << ", but failed"); SAL_WARN("vcl.filter", "PDFDocument::GetObjectOffset: wanted to look up index #"
<< nIndex << ", but failed");
return 0; return 0;
} }
return it->second.m_nOffset; return it->second.m_nOffset;
} }
const std::vector< std::unique_ptr<PDFElement> >& PDFDocument::GetElements() const std::vector<std::unique_ptr<PDFElement>>& PDFDocument::GetElements() { return m_aElements; }
{
return m_aElements;
}
/// Visits the page tree recursively, looking for page objects. /// Visits the page tree recursively, looking for page objects.
static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& rRet) static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& rRet)
...@@ -1780,7 +1850,6 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages() ...@@ -1780,7 +1850,6 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages()
PDFReferenceElement* pRoot = nullptr; PDFReferenceElement* pRoot = nullptr;
PDFTrailerElement* pTrailer = nullptr; PDFTrailerElement* pTrailer = nullptr;
if (!m_aTrailerOffsets.empty()) if (!m_aTrailerOffsets.empty())
{ {
...@@ -1812,7 +1881,8 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages() ...@@ -1812,7 +1881,8 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages()
PDFObjectElement* pPages = pCatalog->LookupObject("Pages"); PDFObjectElement* pPages = pCatalog->LookupObject("Pages");
if (!pPages) if (!pPages)
{ {
SAL_WARN("vcl.filter", "PDFDocument::GetPages: catalog (obj " << pCatalog->GetObjectValue() << ") has no pages"); SAL_WARN("vcl.filter", "PDFDocument::GetPages: catalog (obj " << pCatalog->GetObjectValue()
<< ") has no pages");
return aRet; return aRet;
} }
...@@ -1821,10 +1891,7 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages() ...@@ -1821,10 +1891,7 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages()
return aRet; return aRet;
} }
void PDFDocument::PushBackEOF(size_t nOffset) void PDFDocument::PushBackEOF(size_t nOffset) { m_aEOFs.push_back(nOffset); }
{
m_aEOFs.push_back(nOffset);
}
std::vector<PDFObjectElement*> PDFDocument::GetSignatureWidgets() std::vector<PDFObjectElement*> PDFDocument::GetSignatureWidgets()
{ {
...@@ -1924,16 +1991,14 @@ bool PDFNumberElement::Read(SvStream& rStream) ...@@ -1924,16 +1991,14 @@ bool PDFNumberElement::Read(SvStream& rStream)
{ {
return false; return false;
} }
if (!rtl::isAsciiDigit(static_cast<unsigned char>(ch)) && ch != '-' if (!rtl::isAsciiDigit(static_cast<unsigned char>(ch)) && ch != '-' && ch != '.')
&& ch != '.')
{ {
rStream.SeekRel(-1); rStream.SeekRel(-1);
return false; return false;
} }
while (!rStream.eof()) while (!rStream.eof())
{ {
if (!rtl::isAsciiDigit(static_cast<unsigned char>(ch)) && ch != '-' if (!rtl::isAsciiDigit(static_cast<unsigned char>(ch)) && ch != '-' && ch != '.')
&& ch != '.')
{ {
rStream.SeekRel(-1); rStream.SeekRel(-1);
m_nLength = rStream.Tell() - m_nOffset; m_nLength = rStream.Tell() - m_nOffset;
...@@ -1948,29 +2013,15 @@ bool PDFNumberElement::Read(SvStream& rStream) ...@@ -1948,29 +2013,15 @@ bool PDFNumberElement::Read(SvStream& rStream)
return false; return false;
} }
sal_uInt64 PDFNumberElement::GetLocation() const sal_uInt64 PDFNumberElement::GetLocation() const { return m_nOffset; }
{
return m_nOffset;
}
sal_uInt64 PDFNumberElement::GetLength() const sal_uInt64 PDFNumberElement::GetLength() const { return m_nLength; }
{
return m_nLength;
}
PDFBooleanElement::PDFBooleanElement(bool /*bValue*/) PDFBooleanElement::PDFBooleanElement(bool /*bValue*/) {}
{
}
bool PDFBooleanElement::Read(SvStream& /*rStream*/) bool PDFBooleanElement::Read(SvStream& /*rStream*/) { return true; }
{
return true;
}
bool PDFNullElement::Read(SvStream& /*rStream*/) bool PDFNullElement::Read(SvStream& /*rStream*/) { return true; }
{
return true;
}
bool PDFHexStringElement::Read(SvStream& rStream) bool PDFHexStringElement::Read(SvStream& rStream)
{ {
...@@ -1989,7 +2040,8 @@ bool PDFHexStringElement::Read(SvStream& rStream) ...@@ -1989,7 +2040,8 @@ bool PDFHexStringElement::Read(SvStream& rStream)
if (ch == '>') if (ch == '>')
{ {
m_aValue = aBuf.makeStringAndClear(); m_aValue = aBuf.makeStringAndClear();
SAL_INFO("vcl.filter", "PDFHexStringElement::Read: m_aValue length is " << m_aValue.getLength()); SAL_INFO("vcl.filter",
"PDFHexStringElement::Read: m_aValue length is " << m_aValue.getLength());
return true; return true;
} }
aBuf.append(ch); aBuf.append(ch);
...@@ -1999,10 +2051,7 @@ bool PDFHexStringElement::Read(SvStream& rStream) ...@@ -1999,10 +2051,7 @@ bool PDFHexStringElement::Read(SvStream& rStream)
return false; return false;
} }
const OString& PDFHexStringElement::GetValue() const const OString& PDFHexStringElement::GetValue() const { return m_aValue; }
{
return m_aValue;
}
bool PDFLiteralStringElement::Read(SvStream& rStream) bool PDFLiteralStringElement::Read(SvStream& rStream)
{ {
...@@ -2032,7 +2081,8 @@ bool PDFLiteralStringElement::Read(SvStream& rStream) ...@@ -2032,7 +2081,8 @@ bool PDFLiteralStringElement::Read(SvStream& rStream)
{ {
// ')' of the outermost '(' is reached. // ')' of the outermost '(' is reached.
m_aValue = aBuf.makeStringAndClear(); m_aValue = aBuf.makeStringAndClear();
SAL_INFO("vcl.filter", "PDFLiteralStringElement::Read: m_aValue is '" << m_aValue << "'"); SAL_INFO("vcl.filter",
"PDFLiteralStringElement::Read: m_aValue is '" << m_aValue << "'");
return true; return true;
} }
aBuf.append(ch); aBuf.append(ch);
...@@ -2043,10 +2093,7 @@ bool PDFLiteralStringElement::Read(SvStream& rStream) ...@@ -2043,10 +2093,7 @@ bool PDFLiteralStringElement::Read(SvStream& rStream)
return false; return false;
} }
const OString& PDFLiteralStringElement::GetValue() const const OString& PDFLiteralStringElement::GetValue() const { return m_aValue; }
{
return m_aValue;
}
PDFTrailerElement::PDFTrailerElement(PDFDocument& rDoc) PDFTrailerElement::PDFTrailerElement(PDFDocument& rDoc)
: m_rDoc(rDoc) : m_rDoc(rDoc)
...@@ -2067,40 +2114,36 @@ PDFElement* PDFTrailerElement::Lookup(const OString& rDictionaryKey) ...@@ -2067,40 +2114,36 @@ PDFElement* PDFTrailerElement::Lookup(const OString& rDictionaryKey)
return PDFDictionaryElement::Lookup(m_aDictionary, rDictionaryKey); return PDFDictionaryElement::Lookup(m_aDictionary, rDictionaryKey);
} }
sal_uInt64 PDFTrailerElement::GetLocation() const sal_uInt64 PDFTrailerElement::GetLocation() const { return m_nOffset; }
{
return m_nOffset;
}
double PDFNumberElement::GetValue() const double PDFNumberElement::GetValue() const { return m_fValue; }
{
return m_fValue;
}
PDFObjectElement::PDFObjectElement(PDFDocument& rDoc, double fObjectValue, double fGenerationValue) PDFObjectElement::PDFObjectElement(PDFDocument& rDoc, double fObjectValue, double fGenerationValue)
: m_rDoc(rDoc), : m_rDoc(rDoc)
m_fObjectValue(fObjectValue), , m_fObjectValue(fObjectValue)
m_fGenerationValue(fGenerationValue), , m_fGenerationValue(fGenerationValue)
m_pNumberElement(nullptr), , m_pNumberElement(nullptr)
m_nDictionaryOffset(0), , m_nDictionaryOffset(0)
m_nDictionaryLength(0), , m_nDictionaryLength(0)
m_pDictionaryElement(nullptr), , m_pDictionaryElement(nullptr)
m_nArrayOffset(0), , m_nArrayOffset(0)
m_nArrayLength(0), , m_nArrayLength(0)
m_pArrayElement(nullptr), , m_pArrayElement(nullptr)
m_pStreamElement(nullptr) , m_pStreamElement(nullptr)
{ {
} }
bool PDFObjectElement::Read(SvStream& /*rStream*/) bool PDFObjectElement::Read(SvStream& /*rStream*/)
{ {
SAL_INFO("vcl.filter", "PDFObjectElement::Read: " << m_fObjectValue << " " << m_fGenerationValue << " obj"); SAL_INFO("vcl.filter",
"PDFObjectElement::Read: " << m_fObjectValue << " " << m_fGenerationValue << " obj");
return true; return true;
} }
PDFDictionaryElement::PDFDictionaryElement() = default; PDFDictionaryElement::PDFDictionaryElement() = default;
size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary) size_t PDFDictionaryElement::Parse(const std::vector<std::unique_ptr<PDFElement>>& rElements,
PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary)
{ {
// The index of last parsed element, in case of nested dictionaries. // The index of last parsed element, in case of nested dictionaries.
size_t nRet = 0; size_t nRet = 0;
...@@ -2168,7 +2211,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement ...@@ -2168,7 +2211,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
{ {
// Last dictionary end, track length and stop parsing. // Last dictionary end, track length and stop parsing.
if (pThisObject) if (pThisObject)
pThisObject->SetDictionaryLength(pEndDictionary->GetLocation() - nDictionaryOffset); pThisObject->SetDictionaryLength(pEndDictionary->GetLocation()
- nDictionaryOffset);
nRet = i; nRet = i;
break; break;
} }
...@@ -2184,7 +2228,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement ...@@ -2184,7 +2228,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
if (pThisDictionary) if (pThisDictionary)
{ {
pThisDictionary->SetKeyOffset(aName, nNameOffset); pThisDictionary->SetKeyOffset(aName, nNameOffset);
pThisDictionary->SetKeyValueLength(aName, pNumber->GetLocation() + pNumber->GetLength() - nNameOffset); pThisDictionary->SetKeyValueLength(
aName, pNumber->GetLocation() + pNumber->GetLength() - nNameOffset);
} }
aName.clear(); aName.clear();
aNumbers.clear(); aNumbers.clear();
...@@ -2211,7 +2256,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement ...@@ -2211,7 +2256,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
if (pThisDictionary) if (pThisDictionary)
{ {
pThisDictionary->SetKeyOffset(aName, nNameOffset); pThisDictionary->SetKeyOffset(aName, nNameOffset);
pThisDictionary->SetKeyValueLength(aName, pName->GetLocation() + pName->GetLength() - nNameOffset); pThisDictionary->SetKeyValueLength(
aName, pName->GetLocation() + pName->GetLength() - nNameOffset);
} }
aName.clear(); aName.clear();
} }
...@@ -2257,7 +2303,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement ...@@ -2257,7 +2303,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
if (pThisDictionary) if (pThisDictionary)
{ {
pThisDictionary->SetKeyOffset(aName, nNameOffset); pThisDictionary->SetKeyOffset(aName, nNameOffset);
pThisDictionary->SetKeyValueLength(aName, pReference->GetOffset() - nNameOffset); pThisDictionary->SetKeyValueLength(aName,
pReference->GetOffset() - nNameOffset);
} }
aName.clear(); aName.clear();
} }
...@@ -2330,7 +2377,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement ...@@ -2330,7 +2377,8 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
return nRet; return nRet;
} }
PDFElement* PDFDictionaryElement::Lookup(const std::map<OString, PDFElement*>& rDictionary, const OString& rKey) PDFElement* PDFDictionaryElement::Lookup(const std::map<OString, PDFElement*>& rDictionary,
const OString& rKey)
{ {
auto it = rDictionary.find(rKey); auto it = rDictionary.find(rKey);
if (it == rDictionary.end()) if (it == rDictionary.end())
...@@ -2341,10 +2389,13 @@ PDFElement* PDFDictionaryElement::Lookup(const std::map<OString, PDFElement*>& r ...@@ -2341,10 +2389,13 @@ PDFElement* PDFDictionaryElement::Lookup(const std::map<OString, PDFElement*>& r
PDFObjectElement* PDFDictionaryElement::LookupObject(const OString& rDictionaryKey) PDFObjectElement* PDFDictionaryElement::LookupObject(const OString& rDictionaryKey)
{ {
auto pKey = dynamic_cast<PDFReferenceElement*>(PDFDictionaryElement::Lookup(m_aItems, rDictionaryKey)); auto pKey = dynamic_cast<PDFReferenceElement*>(
PDFDictionaryElement::Lookup(m_aItems, rDictionaryKey));
if (!pKey) if (!pKey)
{ {
SAL_WARN("vcl.filter", "PDFDictionaryElement::LookupObject: no such key with reference value: " << rDictionaryKey); SAL_WARN("vcl.filter",
"PDFDictionaryElement::LookupObject: no such key with reference value: "
<< rDictionaryKey);
return nullptr; return nullptr;
} }
...@@ -2376,17 +2427,15 @@ PDFObjectElement* PDFObjectElement::LookupObject(const OString& rDictionaryKey) ...@@ -2376,17 +2427,15 @@ PDFObjectElement* PDFObjectElement::LookupObject(const OString& rDictionaryKey)
auto pKey = dynamic_cast<PDFReferenceElement*>(Lookup(rDictionaryKey)); auto pKey = dynamic_cast<PDFReferenceElement*>(Lookup(rDictionaryKey));
if (!pKey) if (!pKey)
{ {
SAL_WARN("vcl.filter", "PDFObjectElement::LookupObject: no such key with reference value: " << rDictionaryKey); SAL_WARN("vcl.filter", "PDFObjectElement::LookupObject: no such key with reference value: "
<< rDictionaryKey);
return nullptr; return nullptr;
} }
return pKey->LookupObject(); return pKey->LookupObject();
} }
double PDFObjectElement::GetObjectValue() const double PDFObjectElement::GetObjectValue() const { return m_fObjectValue; }
{
return m_fObjectValue;
}
void PDFObjectElement::SetDictionaryOffset(sal_uInt64 nDictionaryOffset) void PDFObjectElement::SetDictionaryOffset(sal_uInt64 nDictionaryOffset)
{ {
...@@ -2401,15 +2450,9 @@ sal_uInt64 PDFObjectElement::GetDictionaryOffset() ...@@ -2401,15 +2450,9 @@ sal_uInt64 PDFObjectElement::GetDictionaryOffset()
return m_nDictionaryOffset; return m_nDictionaryOffset;
} }
void PDFObjectElement::SetArrayOffset(sal_uInt64 nArrayOffset) void PDFObjectElement::SetArrayOffset(sal_uInt64 nArrayOffset) { m_nArrayOffset = nArrayOffset; }
{
m_nArrayOffset = nArrayOffset;
}
sal_uInt64 PDFObjectElement::GetArrayOffset() sal_uInt64 PDFObjectElement::GetArrayOffset() { return m_nArrayOffset; }
{
return m_nArrayOffset;
}
void PDFDictionaryElement::SetKeyOffset(const OString& rKey, sal_uInt64 nOffset) void PDFDictionaryElement::SetKeyOffset(const OString& rKey, sal_uInt64 nOffset)
{ {
...@@ -2439,10 +2482,7 @@ sal_uInt64 PDFDictionaryElement::GetKeyValueLength(const OString& rKey) const ...@@ -2439,10 +2482,7 @@ sal_uInt64 PDFDictionaryElement::GetKeyValueLength(const OString& rKey) const
return it->second; return it->second;
} }
const std::map<OString, PDFElement*>& PDFDictionaryElement::GetItems() const const std::map<OString, PDFElement*>& PDFDictionaryElement::GetItems() const { return m_aItems; }
{
return m_aItems;
}
void PDFObjectElement::SetDictionaryLength(sal_uInt64 nDictionaryLength) void PDFObjectElement::SetDictionaryLength(sal_uInt64 nDictionaryLength)
{ {
...@@ -2457,15 +2497,9 @@ sal_uInt64 PDFObjectElement::GetDictionaryLength() ...@@ -2457,15 +2497,9 @@ sal_uInt64 PDFObjectElement::GetDictionaryLength()
return m_nDictionaryLength; return m_nDictionaryLength;
} }
void PDFObjectElement::SetArrayLength(sal_uInt64 nArrayLength) void PDFObjectElement::SetArrayLength(sal_uInt64 nArrayLength) { m_nArrayLength = nArrayLength; }
{
m_nArrayLength = nArrayLength;
}
sal_uInt64 PDFObjectElement::GetArrayLength() sal_uInt64 PDFObjectElement::GetArrayLength() { return m_nArrayLength; }
{
return m_nArrayLength;
}
PDFDictionaryElement* PDFObjectElement::GetDictionary() PDFDictionaryElement* PDFObjectElement::GetDictionary()
{ {
...@@ -2484,10 +2518,7 @@ void PDFObjectElement::SetNumberElement(PDFNumberElement* pNumberElement) ...@@ -2484,10 +2518,7 @@ void PDFObjectElement::SetNumberElement(PDFNumberElement* pNumberElement)
m_pNumberElement = pNumberElement; m_pNumberElement = pNumberElement;
} }
PDFNumberElement* PDFObjectElement::GetNumberElement() const PDFNumberElement* PDFObjectElement::GetNumberElement() const { return m_pNumberElement; }
{
return m_pNumberElement;
}
const std::vector<PDFReferenceElement*>& PDFObjectElement::GetDictionaryReferences() const const std::vector<PDFReferenceElement*>& PDFObjectElement::GetDictionaryReferences() const
{ {
...@@ -2507,25 +2538,16 @@ const std::map<OString, PDFElement*>& PDFObjectElement::GetDictionaryItems() ...@@ -2507,25 +2538,16 @@ const std::map<OString, PDFElement*>& PDFObjectElement::GetDictionaryItems()
return m_aDictionary; return m_aDictionary;
} }
void PDFObjectElement::SetArray(PDFArrayElement* pArrayElement) void PDFObjectElement::SetArray(PDFArrayElement* pArrayElement) { m_pArrayElement = pArrayElement; }
{
m_pArrayElement = pArrayElement;
}
void PDFObjectElement::SetStream(PDFStreamElement* pStreamElement) void PDFObjectElement::SetStream(PDFStreamElement* pStreamElement)
{ {
m_pStreamElement = pStreamElement; m_pStreamElement = pStreamElement;
} }
PDFStreamElement* PDFObjectElement::GetStream() const PDFStreamElement* PDFObjectElement::GetStream() const { return m_pStreamElement; }
{
return m_pStreamElement;
}
PDFArrayElement* PDFObjectElement::GetArray() const PDFArrayElement* PDFObjectElement::GetArray() const { return m_pArrayElement; }
{
return m_pArrayElement;
}
void PDFObjectElement::ParseStoredObjects() void PDFObjectElement::ParseStoredObjects()
{ {
...@@ -2541,7 +2563,8 @@ void PDFObjectElement::ParseStoredObjects() ...@@ -2541,7 +2563,8 @@ void PDFObjectElement::ParseStoredObjects()
if (!pType) if (!pType)
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: missing unexpected type"); SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: missing unexpected type");
else else
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: unexpected type: " << pType->GetValue()); SAL_WARN("vcl.filter",
"PDFDocument::ReadXRefStream: unexpected type: " << pType->GetValue());
return; return;
} }
...@@ -2551,7 +2574,8 @@ void PDFObjectElement::ParseStoredObjects() ...@@ -2551,7 +2574,8 @@ void PDFObjectElement::ParseStoredObjects()
if (!pFilter) if (!pFilter)
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: missing filter"); SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: missing filter");
else else
SAL_WARN("vcl.filter", "PDFDocument::ReadXRefStream: unexpected filter: " << pFilter->GetValue()); SAL_WARN("vcl.filter",
"PDFDocument::ReadXRefStream: unexpected filter: " << pFilter->GetValue());
return; return;
} }
...@@ -2606,7 +2630,8 @@ void PDFObjectElement::ParseStoredObjects() ...@@ -2606,7 +2630,8 @@ void PDFObjectElement::ParseStoredObjects()
PDFNumberElement aObjNum; PDFNumberElement aObjNum;
if (!aObjNum.Read(aStream)) if (!aObjNum.Read(aStream))
{ {
SAL_WARN("vcl.filter", "PDFObjectElement::ParseStoredObjects: failed to read object number"); SAL_WARN("vcl.filter",
"PDFObjectElement::ParseStoredObjects: failed to read object number");
return; return;
} }
aObjNums.push_back(aObjNum.GetValue()); aObjNums.push_back(aObjNum.GetValue());
...@@ -2616,7 +2641,8 @@ void PDFObjectElement::ParseStoredObjects() ...@@ -2616,7 +2641,8 @@ void PDFObjectElement::ParseStoredObjects()
PDFNumberElement aByteOffset; PDFNumberElement aByteOffset;
if (!aByteOffset.Read(aStream)) if (!aByteOffset.Read(aStream))
{ {
SAL_WARN("vcl.filter", "PDFObjectElement::ParseStoredObjects: failed to read byte offset"); SAL_WARN("vcl.filter",
"PDFObjectElement::ParseStoredObjects: failed to read byte offset");
return; return;
} }
aOffsets.push_back(pFirst->GetValue() + aByteOffset.GetValue()); aOffsets.push_back(pFirst->GetValue() + aByteOffset.GetValue());
...@@ -2645,7 +2671,8 @@ void PDFObjectElement::ParseStoredObjects() ...@@ -2645,7 +2671,8 @@ void PDFObjectElement::ParseStoredObjects()
aStream.ReadBytes(aBuf.data(), aBuf.size()); aStream.ReadBytes(aBuf.data(), aBuf.size());
SvMemoryStream aStoredStream(aBuf.data(), aBuf.size(), StreamMode::READ); SvMemoryStream aStoredStream(aBuf.data(), aBuf.size(), StreamMode::READ);
m_rDoc.Tokenize(aStoredStream, TokenizeMode::STORED_OBJECT, pStored->GetStoredElements(), pStored); m_rDoc.Tokenize(aStoredStream, TokenizeMode::STORED_OBJECT, pStored->GetStoredElements(),
pStored);
// This is how references know the object is stored inside this object stream. // This is how references know the object is stored inside this object stream.
m_rDoc.SetIDObject(nObjNum, pStored); m_rDoc.SetIDObject(nObjNum, pStored);
...@@ -2657,65 +2684,53 @@ void PDFObjectElement::ParseStoredObjects() ...@@ -2657,65 +2684,53 @@ void PDFObjectElement::ParseStoredObjects()
} }
} }
std::vector< std::unique_ptr<PDFElement> >& PDFObjectElement::GetStoredElements() std::vector<std::unique_ptr<PDFElement>>& PDFObjectElement::GetStoredElements()
{ {
return m_aElements; return m_aElements;
} }
SvMemoryStream* PDFObjectElement::GetStreamBuffer() const SvMemoryStream* PDFObjectElement::GetStreamBuffer() const { return m_pStreamBuffer.get(); }
{
return m_pStreamBuffer.get();
}
void PDFObjectElement::SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer) void PDFObjectElement::SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer)
{ {
m_pStreamBuffer = std::move(pStreamBuffer); m_pStreamBuffer = std::move(pStreamBuffer);
} }
PDFDocument& PDFObjectElement::GetDocument() PDFDocument& PDFObjectElement::GetDocument() { return m_rDoc; }
{
return m_rDoc;
}
PDFReferenceElement::PDFReferenceElement(PDFDocument& rDoc, PDFNumberElement& rObject, PDFNumberElement const& rGeneration) PDFReferenceElement::PDFReferenceElement(PDFDocument& rDoc, PDFNumberElement& rObject,
: m_rDoc(rDoc), PDFNumberElement const& rGeneration)
m_fObjectValue(rObject.GetValue()), : m_rDoc(rDoc)
m_fGenerationValue(rGeneration.GetValue()), , m_fObjectValue(rObject.GetValue())
m_rObject(rObject) , m_fGenerationValue(rGeneration.GetValue())
, m_rObject(rObject)
{ {
} }
PDFNumberElement& PDFReferenceElement::GetObjectElement() const PDFNumberElement& PDFReferenceElement::GetObjectElement() const { return m_rObject; }
{
return m_rObject;
}
bool PDFReferenceElement::Read(SvStream& rStream) bool PDFReferenceElement::Read(SvStream& rStream)
{ {
SAL_INFO("vcl.filter", "PDFReferenceElement::Read: " << m_fObjectValue << " " << m_fGenerationValue << " R"); SAL_INFO("vcl.filter",
"PDFReferenceElement::Read: " << m_fObjectValue << " " << m_fGenerationValue << " R");
m_nOffset = rStream.Tell(); m_nOffset = rStream.Tell();
return true; return true;
} }
sal_uInt64 PDFReferenceElement::GetOffset() const sal_uInt64 PDFReferenceElement::GetOffset() const { return m_nOffset; }
{
return m_nOffset;
}
double PDFReferenceElement::LookupNumber(SvStream& rStream) const double PDFReferenceElement::LookupNumber(SvStream& rStream) const
{ {
size_t nOffset = m_rDoc.GetObjectOffset(m_fObjectValue); size_t nOffset = m_rDoc.GetObjectOffset(m_fObjectValue);
if (nOffset == 0) if (nOffset == 0)
{ {
SAL_WARN("vcl.filter", "PDFReferenceElement::LookupNumber: found no offset for object #" << m_fObjectValue); SAL_WARN("vcl.filter", "PDFReferenceElement::LookupNumber: found no offset for object #"
<< m_fObjectValue);
return 0; return 0;
} }
sal_uInt64 nOrigPos = rStream.Tell(); sal_uInt64 nOrigPos = rStream.Tell();
comphelper::ScopeGuard g([&]() comphelper::ScopeGuard g([&]() { rStream.Seek(nOrigPos); });
{
rStream.Seek(nOrigPos);
});
rStream.Seek(nOffset); rStream.Seek(nOffset);
{ {
...@@ -2724,7 +2739,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const ...@@ -2724,7 +2739,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const
bool bRet = aNumber.Read(rStream); bool bRet = aNumber.Read(rStream);
if (!bRet || aNumber.GetValue() != m_fObjectValue) if (!bRet || aNumber.GetValue() != m_fObjectValue)
{ {
SAL_WARN("vcl.filter", "PDFReferenceElement::LookupNumber: offset points to not matching object"); SAL_WARN("vcl.filter",
"PDFReferenceElement::LookupNumber: offset points to not matching object");
return 0; return 0;
} }
} }
...@@ -2735,7 +2751,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const ...@@ -2735,7 +2751,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const
bool bRet = aNumber.Read(rStream); bool bRet = aNumber.Read(rStream);
if (!bRet || aNumber.GetValue() != m_fGenerationValue) if (!bRet || aNumber.GetValue() != m_fGenerationValue)
{ {
SAL_WARN("vcl.filter", "PDFReferenceElement::LookupNumber: offset points to not matching generation"); SAL_WARN("vcl.filter",
"PDFReferenceElement::LookupNumber: offset points to not matching generation");
return 0; return 0;
} }
} }
...@@ -2745,7 +2762,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const ...@@ -2745,7 +2762,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const
OString aKeyword = PDFDocument::ReadKeyword(rStream); OString aKeyword = PDFDocument::ReadKeyword(rStream);
if (aKeyword != "obj") if (aKeyword != "obj")
{ {
SAL_WARN("vcl.filter", "PDFReferenceElement::LookupNumber: offset doesn't point to an obj keyword"); SAL_WARN("vcl.filter",
"PDFReferenceElement::LookupNumber: offset doesn't point to an obj keyword");
return 0; return 0;
} }
} }
...@@ -2754,7 +2772,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const ...@@ -2754,7 +2772,8 @@ double PDFReferenceElement::LookupNumber(SvStream& rStream) const
PDFNumberElement aNumber; PDFNumberElement aNumber;
if (!aNumber.Read(rStream)) if (!aNumber.Read(rStream))
{ {
SAL_WARN("vcl.filter", "PDFReferenceElement::LookupNumber: failed to read referenced number"); SAL_WARN("vcl.filter",
"PDFReferenceElement::LookupNumber: failed to read referenced number");
return 0; return 0;
} }
...@@ -2777,20 +2796,11 @@ PDFObjectElement* PDFDocument::LookupObject(size_t nObjectNumber) ...@@ -2777,20 +2796,11 @@ PDFObjectElement* PDFDocument::LookupObject(size_t nObjectNumber)
return nullptr; return nullptr;
} }
SvMemoryStream& PDFDocument::GetEditBuffer() SvMemoryStream& PDFDocument::GetEditBuffer() { return m_aEditBuffer; }
{
return m_aEditBuffer;
}
int PDFReferenceElement::GetObjectValue() const int PDFReferenceElement::GetObjectValue() const { return m_fObjectValue; }
{
return m_fObjectValue;
}
int PDFReferenceElement::GetGenerationValue() const int PDFReferenceElement::GetGenerationValue() const { return m_fGenerationValue; }
{
return m_fGenerationValue;
}
bool PDFDictionaryElement::Read(SvStream& rStream) bool PDFDictionaryElement::Read(SvStream& rStream)
{ {
...@@ -2824,10 +2834,7 @@ bool PDFDictionaryElement::Read(SvStream& rStream) ...@@ -2824,10 +2834,7 @@ bool PDFDictionaryElement::Read(SvStream& rStream)
PDFEndDictionaryElement::PDFEndDictionaryElement() = default; PDFEndDictionaryElement::PDFEndDictionaryElement() = default;
sal_uInt64 PDFEndDictionaryElement::GetLocation() const sal_uInt64 PDFEndDictionaryElement::GetLocation() const { return m_nLocation; }
{
return m_nLocation;
}
bool PDFEndDictionaryElement::Read(SvStream& rStream) bool PDFEndDictionaryElement::Read(SvStream& rStream)
{ {
...@@ -2882,8 +2889,8 @@ bool PDFNameElement::Read(SvStream& rStream) ...@@ -2882,8 +2889,8 @@ bool PDFNameElement::Read(SvStream& rStream)
rStream.ReadChar(ch); rStream.ReadChar(ch);
while (!rStream.eof()) while (!rStream.eof())
{ {
if (rtl::isAsciiWhiteSpace(static_cast<unsigned char>(ch)) || ch == '/' if (rtl::isAsciiWhiteSpace(static_cast<unsigned char>(ch)) || ch == '/' || ch == '['
|| ch == '[' || ch == ']' || ch == '<' || ch == '>' || ch == '(') || ch == ']' || ch == '<' || ch == '>' || ch == '(')
{ {
rStream.SeekRel(-1); rStream.SeekRel(-1);
m_aValue = aBuf.makeStringAndClear(); m_aValue = aBuf.makeStringAndClear();
...@@ -2897,24 +2904,15 @@ bool PDFNameElement::Read(SvStream& rStream) ...@@ -2897,24 +2904,15 @@ bool PDFNameElement::Read(SvStream& rStream)
return false; return false;
} }
const OString& PDFNameElement::GetValue() const const OString& PDFNameElement::GetValue() const { return m_aValue; }
{
return m_aValue;
}
sal_uInt64 PDFNameElement::GetLocation() const sal_uInt64 PDFNameElement::GetLocation() const { return m_nLocation; }
{
return m_nLocation;
}
sal_uInt64 PDFNameElement::GetLength() const sal_uInt64 PDFNameElement::GetLength() const { return m_nLength; }
{
return m_nLength;
}
PDFStreamElement::PDFStreamElement(size_t nLength) PDFStreamElement::PDFStreamElement(size_t nLength)
: m_nLength(nLength), : m_nLength(nLength)
m_nOffset(0) , m_nOffset(0)
{ {
} }
...@@ -2929,25 +2927,13 @@ bool PDFStreamElement::Read(SvStream& rStream) ...@@ -2929,25 +2927,13 @@ bool PDFStreamElement::Read(SvStream& rStream)
return rStream.good(); return rStream.good();
} }
SvMemoryStream& PDFStreamElement::GetMemory() SvMemoryStream& PDFStreamElement::GetMemory() { return m_aMemory; }
{
return m_aMemory;
}
sal_uInt64 PDFStreamElement::GetOffset() const sal_uInt64 PDFStreamElement::GetOffset() const { return m_nOffset; }
{
return m_nOffset;
}
bool PDFEndStreamElement::Read(SvStream& /*rStream*/) bool PDFEndStreamElement::Read(SvStream& /*rStream*/) { return true; }
{
return true;
}
bool PDFEndObjectElement::Read(SvStream& /*rStream*/) bool PDFEndObjectElement::Read(SvStream& /*rStream*/) { return true; }
{
return true;
}
PDFArrayElement::PDFArrayElement(PDFObjectElement* pObject) PDFArrayElement::PDFArrayElement(PDFObjectElement* pObject)
: m_pObject(pObject) : m_pObject(pObject)
...@@ -2972,14 +2958,12 @@ bool PDFArrayElement::Read(SvStream& rStream) ...@@ -2972,14 +2958,12 @@ bool PDFArrayElement::Read(SvStream& rStream)
void PDFArrayElement::PushBack(PDFElement* pElement) void PDFArrayElement::PushBack(PDFElement* pElement)
{ {
if (m_pObject) if (m_pObject)
SAL_INFO("vcl.filter", "PDFArrayElement::PushBack: object is " << m_pObject->GetObjectValue()); SAL_INFO("vcl.filter",
"PDFArrayElement::PushBack: object is " << m_pObject->GetObjectValue());
m_aElements.push_back(pElement); m_aElements.push_back(pElement);
} }
const std::vector<PDFElement*>& PDFArrayElement::GetElements() const std::vector<PDFElement*>& PDFArrayElement::GetElements() { return m_aElements; }
{
return m_aElements;
}
PDFEndArrayElement::PDFEndArrayElement() = default; PDFEndArrayElement::PDFEndArrayElement() = default;
...@@ -2999,10 +2983,7 @@ bool PDFEndArrayElement::Read(SvStream& rStream) ...@@ -2999,10 +2983,7 @@ bool PDFEndArrayElement::Read(SvStream& rStream)
return true; return true;
} }
sal_uInt64 PDFEndArrayElement::GetOffset() const sal_uInt64 PDFEndArrayElement::GetOffset() const { return m_nOffset; }
{
return m_nOffset;
}
} // namespace filter } // namespace filter
} // namespace vcl } // namespace vcl
......
...@@ -25,7 +25,6 @@ using namespace com::sun::star; ...@@ -25,7 +25,6 @@ using namespace com::sun::star;
namespace namespace
{ {
#if HAVE_FEATURE_PDFIUM #if HAVE_FEATURE_PDFIUM
/// Callback class to be used with FPDF_SaveWithVersion(). /// Callback class to be used with FPDF_SaveWithVersion().
...@@ -33,7 +32,8 @@ struct CompatibleWriter : public FPDF_FILEWRITE ...@@ -33,7 +32,8 @@ struct CompatibleWriter : public FPDF_FILEWRITE
{ {
public: public:
CompatibleWriter(); CompatibleWriter();
static int WriteBlockCallback(FPDF_FILEWRITE* pFileWrite, const void* pData, unsigned long nSize); static int WriteBlockCallback(FPDF_FILEWRITE* pFileWrite, const void* pData,
unsigned long nSize);
SvMemoryStream m_aStream; SvMemoryStream m_aStream;
}; };
...@@ -44,7 +44,8 @@ CompatibleWriter::CompatibleWriter() ...@@ -44,7 +44,8 @@ CompatibleWriter::CompatibleWriter()
FPDF_FILEWRITE::WriteBlock = CompatibleWriter::WriteBlockCallback; FPDF_FILEWRITE::WriteBlock = CompatibleWriter::WriteBlockCallback;
} }
int CompatibleWriter::WriteBlockCallback(FPDF_FILEWRITE* pFileWrite, const void* pData, unsigned long nSize) int CompatibleWriter::WriteBlockCallback(FPDF_FILEWRITE* pFileWrite, const void* pData,
unsigned long nSize)
{ {
auto pImpl = static_cast<CompatibleWriter*>(pFileWrite); auto pImpl = static_cast<CompatibleWriter*>(pFileWrite);
pImpl->m_aStream.WriteBytes(pData, nSize); pImpl->m_aStream.WriteBytes(pData, nSize);
...@@ -52,15 +53,11 @@ int CompatibleWriter::WriteBlockCallback(FPDF_FILEWRITE* pFileWrite, const void* ...@@ -52,15 +53,11 @@ int CompatibleWriter::WriteBlockCallback(FPDF_FILEWRITE* pFileWrite, const void*
} }
/// Convert to inch, then assume 96 DPI. /// Convert to inch, then assume 96 DPI.
double pointToPixel(double fPoint) double pointToPixel(double fPoint) { return fPoint / 72 * 96; }
{
return fPoint / 72 * 96;
}
/// Does PDF to bitmap conversion using pdfium. /// Does PDF to bitmap conversion using pdfium.
size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps, size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps, sal_uInt64 nPos,
sal_uInt64 nPos, sal_uInt64 nSize, sal_uInt64 nSize, const size_t nFirstPage = 0, int nPages = 1)
const size_t nFirstPage = 0, int nPages = 1)
{ {
FPDF_LIBRARY_CONFIG aConfig; FPDF_LIBRARY_CONFIG aConfig;
aConfig.version = 2; aConfig.version = 2;
...@@ -75,7 +72,8 @@ size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps, ...@@ -75,7 +72,8 @@ size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps,
aInBuffer.WriteStream(rStream, nSize); aInBuffer.WriteStream(rStream, nSize);
// Load the buffer using pdfium. // Load the buffer using pdfium.
FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr); FPDF_DOCUMENT pPdfDocument
= FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr);
if (!pPdfDocument) if (!pPdfDocument)
return 0; return 0;
...@@ -99,7 +97,8 @@ size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps, ...@@ -99,7 +97,8 @@ size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps,
const FPDF_DWORD nColor = FPDFPage_HasTransparency(pPdfPage) ? 0x00000000 : 0xFFFFFFFF; const FPDF_DWORD nColor = FPDFPage_HasTransparency(pPdfPage) ? 0x00000000 : 0xFFFFFFFF;
FPDFBitmap_FillRect(pPdfBitmap, 0, 0, nPageWidth, nPageHeight, nColor); FPDFBitmap_FillRect(pPdfBitmap, 0, 0, nPageWidth, nPageHeight, nColor);
FPDF_RenderPageBitmap(pPdfBitmap, pPdfPage, /*start_x=*/0, /*start_y=*/0, nPageWidth, nPageHeight, /*rotate=*/0, /*flags=*/0); FPDF_RenderPageBitmap(pPdfBitmap, pPdfPage, /*start_x=*/0, /*start_y=*/0, nPageWidth,
nPageHeight, /*rotate=*/0, /*flags=*/0);
// Save the buffer as a bitmap. // Save the buffer as a bitmap.
Bitmap aBitmap(Size(nPageWidth, nPageHeight), 24); Bitmap aBitmap(Size(nPageWidth, nPageHeight), 24);
...@@ -139,7 +138,8 @@ bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize) ...@@ -139,7 +138,8 @@ bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize)
if (nRead < 8) if (nRead < 8)
return false; return false;
if (aFirstBytes[0] != '%' || aFirstBytes[1] != 'P' || aFirstBytes[2] != 'D' || aFirstBytes[3] != 'F' || aFirstBytes[4] != '-') if (aFirstBytes[0] != '%' || aFirstBytes[1] != 'P' || aFirstBytes[2] != 'D'
|| aFirstBytes[3] != 'F' || aFirstBytes[4] != '-')
return false; return false;
sal_Int32 nMajor = OString(aFirstBytes[5]).toInt32(); sal_Int32 nMajor = OString(aFirstBytes[5]).toInt32();
...@@ -149,8 +149,8 @@ bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize) ...@@ -149,8 +149,8 @@ bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize)
/// Takes care of transparently downgrading the version of the PDF stream in /// Takes care of transparently downgrading the version of the PDF stream in
/// case it's too new for our PDF export. /// case it's too new for our PDF export.
bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 nPos,
sal_uInt64 nPos, sal_uInt64 nSize) sal_uInt64 nSize)
{ {
bool bCompatible = isCompatible(rInStream, nPos, nSize); bool bCompatible = isCompatible(rInStream, nPos, nSize);
rInStream.Seek(nPos); rInStream.Seek(nPos);
...@@ -172,7 +172,8 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, ...@@ -172,7 +172,8 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
aInBuffer.WriteStream(rInStream, nSize); aInBuffer.WriteStream(rInStream, nSize);
// Load the buffer using pdfium. // Load the buffer using pdfium.
FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr); FPDF_DOCUMENT pPdfDocument
= FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr);
if (!pPdfDocument) if (!pPdfDocument)
return false; return false;
...@@ -191,29 +192,25 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, ...@@ -191,29 +192,25 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
return rOutStream.good(); return rOutStream.good();
} }
#else #else
size_t generatePreview(SvStream&, std::vector<Bitmap>&, size_t generatePreview(SvStream&, std::vector<Bitmap>&, sal_uInt64 nPos, sal_uInt64 nSize,
sal_uInt64 nPos, sal_uInt64 nSize, size_t nFirstPage = 0, int nLastPage = 0)
size_t nFirstPage = 0, int nLastPage = 0)
{ {
return false; return false;
} }
bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 nPos,
sal_uInt64 nPos, sal_uInt64 nSize) sal_uInt64 nSize)
{ {
rInStream.Seek(nPos); rInStream.Seek(nPos);
rOutStream.WriteStream(rInStream, nSize); rOutStream.WriteStream(rInStream, nSize);
return rOutStream.good(); return rOutStream.good();
} }
#endif // HAVE_FEATURE_PDFIUM #endif // HAVE_FEATURE_PDFIUM
} }
namespace vcl namespace vcl
{ {
bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, css::uno::Sequence<sal_Int8>& rPdfData,
bool ImportPDF(SvStream& rStream, Bitmap& rBitmap,
css::uno::Sequence<sal_Int8>& rPdfData,
sal_uInt64 nPos, sal_uInt64 nSize) sal_uInt64 nPos, sal_uInt64 nSize)
{ {
// Get the preview of the first page. // Get the preview of the first page.
...@@ -236,7 +233,6 @@ bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, ...@@ -236,7 +233,6 @@ bool ImportPDF(SvStream& rStream, Bitmap& rBitmap,
return true; return true;
} }
bool ImportPDF(SvStream& rStream, Graphic& rGraphic) bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
{ {
uno::Sequence<sal_Int8> aPdfData; uno::Sequence<sal_Int8> aPdfData;
...@@ -246,7 +242,6 @@ bool ImportPDF(SvStream& rStream, Graphic& rGraphic) ...@@ -246,7 +242,6 @@ bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
rGraphic.setPdfData(aPdfData); rGraphic.setPdfData(aPdfData);
return bRet; return bRet;
} }
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -27,13 +27,14 @@ namespace xmlsecurity ...@@ -27,13 +27,14 @@ namespace xmlsecurity
{ {
namespace pdfio namespace pdfio
{ {
/** /**
* @param rInformation The actual result. * @param rInformation The actual result.
* @param bLast If this is the last signature in the file, so it covers the whole file physically. * @param bLast If this is the last signature in the file, so it covers the whole file physically.
* @return If we can determinate a result. * @return If we can determinate a result.
*/ */
XMLSECURITY_DLLPUBLIC bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, SignatureInformation& rInformation, bool bLast); XMLSECURITY_DLLPUBLIC bool ValidateSignature(SvStream& rStream,
vcl::filter::PDFObjectElement* pSignature,
SignatureInformation& rInformation, bool bLast);
} // namespace pdfio } // namespace pdfio
} // namespace xmlsecurity } // namespace xmlsecurity
......
...@@ -47,7 +47,8 @@ class PDFSigningTest : public test::BootstrapFixture ...@@ -47,7 +47,8 @@ class PDFSigningTest : public test::BootstrapFixture
* Read a pdf and make sure that it has the expected number of valid * Read a pdf and make sure that it has the expected number of valid
* signatures. * signatures.
*/ */
std::vector<SignatureInformation> verify(const OUString& rURL, size_t nCount, const OString& rExpectedSubFilter); std::vector<SignatureInformation> verify(const OUString& rURL, size_t nCount,
const OString& rExpectedSubFilter);
public: public:
PDFSigningTest(); PDFSigningTest();
...@@ -102,9 +103,7 @@ public: ...@@ -102,9 +103,7 @@ public:
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
PDFSigningTest::PDFSigningTest() PDFSigningTest::PDFSigningTest() {}
{
}
void PDFSigningTest::setUp() void PDFSigningTest::setUp()
{ {
...@@ -115,8 +114,8 @@ void PDFSigningTest::setUp() ...@@ -115,8 +114,8 @@ void PDFSigningTest::setUp()
#ifndef _WIN32 #ifndef _WIN32
// Set up cert8.db and key3.db in workdir/CppunitTest/ // Set up cert8.db and key3.db in workdir/CppunitTest/
OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY); OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY);
OUString aTargetDir = m_directories.getURLFromWorkdir( OUString aTargetDir
"/CppunitTest/xmlsecurity_pdfsigning.test.user/"); = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
osl::File::copy(aSourceDir + "cert8.db", aTargetDir + "cert8.db"); osl::File::copy(aSourceDir + "cert8.db", aTargetDir + "cert8.db");
osl::File::copy(aSourceDir + "key3.db", aTargetDir + "key3.db"); osl::File::copy(aSourceDir + "key3.db", aTargetDir + "key3.db");
OUString aTargetPath; OUString aTargetPath;
...@@ -125,10 +124,13 @@ void PDFSigningTest::setUp() ...@@ -125,10 +124,13 @@ void PDFSigningTest::setUp()
#endif #endif
} }
std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, size_t nCount, const OString& rExpectedSubFilter) std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, size_t nCount,
const OString& rExpectedSubFilter)
{ {
uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); = xml::crypto::SEInitializer::create(mxComponentContext);
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
std::vector<SignatureInformation> aRet; std::vector<SignatureInformation> aRet;
SvFileStream aStream(rURL, StreamMode::READ); SvFileStream aStream(rURL, StreamMode::READ);
...@@ -140,14 +142,16 @@ std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, s ...@@ -140,14 +142,16 @@ std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, s
{ {
SignatureInformation aInfo(i); SignatureInformation aInfo(i);
bool bLast = i == aSignatures.size() - 1; bool bLast = i == aSignatures.size() - 1;
CPPUNIT_ASSERT(xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, bLast)); CPPUNIT_ASSERT(
xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, bLast));
aRet.push_back(aInfo); aRet.push_back(aInfo);
if (!rExpectedSubFilter.isEmpty()) if (!rExpectedSubFilter.isEmpty())
{ {
vcl::filter::PDFObjectElement* pValue = aSignatures[i]->LookupObject("V"); vcl::filter::PDFObjectElement* pValue = aSignatures[i]->LookupObject("V");
CPPUNIT_ASSERT(pValue); CPPUNIT_ASSERT(pValue);
auto pSubFilter = dynamic_cast<vcl::filter::PDFNameElement*>(pValue->Lookup("SubFilter")); auto pSubFilter
= dynamic_cast<vcl::filter::PDFNameElement*>(pValue->Lookup("SubFilter"));
CPPUNIT_ASSERT(pSubFilter); CPPUNIT_ASSERT(pSubFilter);
CPPUNIT_ASSERT_EQUAL(rExpectedSubFilter, pSubFilter->GetValue()); CPPUNIT_ASSERT_EQUAL(rExpectedSubFilter, pSubFilter->GetValue());
} }
...@@ -156,11 +160,14 @@ std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, s ...@@ -156,11 +160,14 @@ std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, s
return aRet; return aRet;
} }
bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_t nOriginalSignatureCount) bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL,
size_t nOriginalSignatureCount)
{ {
// Make sure that input has nOriginalSignatureCount signatures. // Make sure that input has nOriginalSignatureCount signatures.
uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); = xml::crypto::SEInitializer::create(mxComponentContext);
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
vcl::filter::PDFDocument aDocument; vcl::filter::PDFDocument aDocument;
{ {
SvFileStream aStream(rInURL, StreamMode::READ); SvFileStream aStream(rInURL, StreamMode::READ);
...@@ -172,8 +179,10 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_ ...@@ -172,8 +179,10 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_
bool bSignSuccessful = false; bool bSignSuccessful = false;
// Sign it and write out the result. // Sign it and write out the result.
{ {
uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = xSecurityContext->getSecurityEnvironment(); uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment
uno::Sequence<uno::Reference<security::XCertificate>> aCertificates = xSecurityEnvironment->getPersonalCertificates(); = xSecurityContext->getSecurityEnvironment();
uno::Sequence<uno::Reference<security::XCertificate>> aCertificates
= xSecurityEnvironment->getPersonalCertificates();
DateTime now(DateTime::SYSTEM); DateTime now(DateTime::SYSTEM);
for (auto& cert : aCertificates) for (auto& cert : aCertificates)
{ {
...@@ -183,7 +192,8 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_ ...@@ -183,7 +192,8 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_
// Only try certificates that are already active and not expired // Only try certificates that are already active and not expired
if ((now > aNotValidAfter) || (now < aNotValidBefore)) if ((now > aNotValidAfter) || (now < aNotValidBefore))
{ {
SAL_WARN("xmlsecurity.pdfio.test", "Skipping a certificate that is not yet valid or already not valid"); SAL_WARN("xmlsecurity.pdfio.test",
"Skipping a certificate that is not yet valid or already not valid");
} }
else else
{ {
...@@ -194,7 +204,8 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_ ...@@ -194,7 +204,8 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, size_
DWORD dwErr = GetLastError(); DWORD dwErr = GetLastError();
if (HRESULT_FROM_WIN32(dwErr) == CRYPT_E_NO_KEY_PROPERTY) if (HRESULT_FROM_WIN32(dwErr) == CRYPT_E_NO_KEY_PROPERTY)
{ {
SAL_WARN("xmlsecurity.pdfio.test", "Skipping a certificate without a private key"); SAL_WARN("xmlsecurity.pdfio.test",
"Skipping a certificate without a private key");
continue; // The certificate does not have a private key - not a valid certificate continue; // The certificate does not have a private key - not a valid certificate
} }
} }
...@@ -220,7 +231,8 @@ void PDFSigningTest::testPDFAdd() ...@@ -220,7 +231,8 @@ void PDFSigningTest::testPDFAdd()
{ {
OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY); OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY);
OUString aInURL = aSourceDir + "no.pdf"; OUString aInURL = aSourceDir + "no.pdf";
OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/"); OUString aTargetDir
= m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
OUString aOutURL = aTargetDir + "add.pdf"; OUString aOutURL = aTargetDir + "add.pdf";
bool bHadCertificates = sign(aInURL, aOutURL, 0); bool bHadCertificates = sign(aInURL, aOutURL, 0);
...@@ -242,7 +254,8 @@ void PDFSigningTest::testPDFAdd2() ...@@ -242,7 +254,8 @@ void PDFSigningTest::testPDFAdd2()
// Sign. // Sign.
OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY); OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY);
OUString aInURL = aSourceDir + "no.pdf"; OUString aInURL = aSourceDir + "no.pdf";
OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/"); OUString aTargetDir
= m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
OUString aOutURL = aTargetDir + "add.pdf"; OUString aOutURL = aTargetDir + "add.pdf";
bool bHadCertificates = sign(aInURL, aOutURL, 0); bool bHadCertificates = sign(aInURL, aOutURL, 0);
...@@ -258,8 +271,10 @@ void PDFSigningTest::testPDFAdd2() ...@@ -258,8 +271,10 @@ void PDFSigningTest::testPDFAdd2()
void PDFSigningTest::testPDFRemove() void PDFSigningTest::testPDFRemove()
{ {
// Make sure that good.pdf has 1 valid signature. // Make sure that good.pdf has 1 valid signature.
uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); = xml::crypto::SEInitializer::create(mxComponentContext);
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
vcl::filter::PDFDocument aDocument; vcl::filter::PDFDocument aDocument;
{ {
OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY); OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY);
...@@ -269,11 +284,13 @@ void PDFSigningTest::testPDFRemove() ...@@ -269,11 +284,13 @@ void PDFSigningTest::testPDFRemove()
std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets(); std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aSignatures.size()); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aSignatures.size());
SignatureInformation aInfo(0); SignatureInformation aInfo(0);
CPPUNIT_ASSERT(xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[0], aInfo, /*bLast=*/true)); CPPUNIT_ASSERT(
xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[0], aInfo, /*bLast=*/true));
} }
// Remove the signature and write out the result as remove.pdf. // Remove the signature and write out the result as remove.pdf.
OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/"); OUString aTargetDir
= m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
OUString aOutURL = aTargetDir + "remove.pdf"; OUString aOutURL = aTargetDir + "remove.pdf";
{ {
CPPUNIT_ASSERT(aDocument.RemoveSignature(0)); CPPUNIT_ASSERT(aDocument.RemoveSignature(0));
...@@ -292,16 +309,22 @@ void PDFSigningTest::testPDFRemoveAll() ...@@ -292,16 +309,22 @@ void PDFSigningTest::testPDFRemoveAll()
// Make sure that good2.pdf has 2 valid signatures. Unlike in // Make sure that good2.pdf has 2 valid signatures. Unlike in
// testPDFRemove(), here intentionally test DocumentSignatureManager and // testPDFRemove(), here intentionally test DocumentSignatureManager and
// PDFSignatureHelper code as well. // PDFSignatureHelper code as well.
uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); = xml::crypto::SEInitializer::create(mxComponentContext);
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
// Copy the test document to a temporary file, as it'll be modified. // Copy the test document to a temporary file, as it'll be modified.
OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/"); OUString aTargetDir
= m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
OUString aOutURL = aTargetDir + "remove-all.pdf"; OUString aOutURL = aTargetDir + "remove-all.pdf";
CPPUNIT_ASSERT_EQUAL(osl::File::RC::E_None, osl::File::copy(m_directories.getURLFromSrc(DATA_DIRECTORY) + "2good.pdf", aOutURL)); CPPUNIT_ASSERT_EQUAL(
osl::File::RC::E_None,
osl::File::copy(m_directories.getURLFromSrc(DATA_DIRECTORY) + "2good.pdf", aOutURL));
// Load the test document as a storage and read its two signatures. // Load the test document as a storage and read its two signatures.
DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content); DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content);
SvStream* pStream = utl::UcbStreamHelper::CreateStream(aOutURL, StreamMode::READ | StreamMode::WRITE); SvStream* pStream
= utl::UcbStreamHelper::CreateStream(aOutURL, StreamMode::READ | StreamMode::WRITE);
uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream)); uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream));
aManager.mxSignatureStream = xStream; aManager.mxSignatureStream = xStream;
aManager.read(/*bUseTempStream=*/false); aManager.read(/*bUseTempStream=*/false);
...@@ -322,20 +345,24 @@ void PDFSigningTest::testPDFRemoveAll() ...@@ -322,20 +345,24 @@ void PDFSigningTest::testPDFRemoveAll()
void PDFSigningTest::testTdf107782() void PDFSigningTest::testTdf107782()
{ {
uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); = xml::crypto::SEInitializer::create(mxComponentContext);
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
// Load the test document as a storage and read its signatures. // Load the test document as a storage and read its signatures.
DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content); DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content);
OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf107782.pdf"; OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf107782.pdf";
SvStream* pStream = utl::UcbStreamHelper::CreateStream(aURL, StreamMode::READ | StreamMode::WRITE); SvStream* pStream
= utl::UcbStreamHelper::CreateStream(aURL, StreamMode::READ | StreamMode::WRITE);
uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream)); uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream));
aManager.mxSignatureStream = xStream; aManager.mxSignatureStream = xStream;
aManager.read(/*bUseTempStream=*/false); aManager.read(/*bUseTempStream=*/false);
CPPUNIT_ASSERT(aManager.mpPDFSignatureHelper); CPPUNIT_ASSERT(aManager.mpPDFSignatureHelper);
// This failed with an std::bad_alloc exception on Windows. // This failed with an std::bad_alloc exception on Windows.
aManager.mpPDFSignatureHelper->GetDocumentSignatureInformations(aManager.getSecurityEnvironment()); aManager.mpPDFSignatureHelper->GetDocumentSignatureInformations(
aManager.getSecurityEnvironment());
} }
void PDFSigningTest::testPDF14Adobe() void PDFSigningTest::testPDF14Adobe()
...@@ -343,7 +370,9 @@ void PDFSigningTest::testPDF14Adobe() ...@@ -343,7 +370,9 @@ void PDFSigningTest::testPDF14Adobe()
// Two signatures, first is SHA1, the second is SHA256. // Two signatures, first is SHA1, the second is SHA256.
// This was 0, as we failed to find the Annots key's value when it was a // This was 0, as we failed to find the Annots key's value when it was a
// reference-to-array, not an array. // reference-to-array, not an array.
std::vector<SignatureInformation> aInfos = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf14adobe.pdf", 2, /*rExpectedSubFilter=*/OString()); std::vector<SignatureInformation> aInfos
= verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf14adobe.pdf", 2,
/*rExpectedSubFilter=*/OString());
// This was 0, out-of-PKCS#7 signature date wasn't read. // This was 0, out-of-PKCS#7 signature date wasn't read.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2016), aInfos[1].stDateTime.Year); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2016), aInfos[1].stDateTime.Year);
} }
...@@ -354,7 +383,8 @@ void PDFSigningTest::testPDF16Adobe() ...@@ -354,7 +383,8 @@ void PDFSigningTest::testPDF16Adobe()
// stream with a predictor. And a valid signature. // stream with a predictor. And a valid signature.
// Found signatures was 0, as parsing failed due to lack of support for // Found signatures was 0, as parsing failed due to lack of support for
// these features. // these features.
verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf16adobe.pdf", 1, /*rExpectedSubFilter=*/OString()); verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf16adobe.pdf", 1,
/*rExpectedSubFilter=*/OString());
} }
void PDFSigningTest::testPDF16Add() void PDFSigningTest::testPDF16Add()
...@@ -363,7 +393,8 @@ void PDFSigningTest::testPDF16Add() ...@@ -363,7 +393,8 @@ void PDFSigningTest::testPDF16Add()
// markup correctly. // markup correctly.
OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY); OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY);
OUString aInURL = aSourceDir + "pdf16adobe.pdf"; OUString aInURL = aSourceDir + "pdf16adobe.pdf";
OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/"); OUString aTargetDir
= m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
OUString aOutURL = aTargetDir + "add.pdf"; OUString aOutURL = aTargetDir + "add.pdf";
// This failed: verification broke as incorrect xref stream was written as // This failed: verification broke as incorrect xref stream was written as
// part of the new signature. // part of the new signature.
...@@ -383,17 +414,21 @@ void PDFSigningTest::testPDF14LOWin() ...@@ -383,17 +414,21 @@ void PDFSigningTest::testPDF14LOWin()
// algorithm when it meant SEC_OID_SHA1, make sure we tolerate that on all // algorithm when it meant SEC_OID_SHA1, make sure we tolerate that on all
// platforms. // platforms.
// This failed, as NSS HASH_Create() didn't handle the sign algorithm. // This failed, as NSS HASH_Create() didn't handle the sign algorithm.
verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf14lowin.pdf", 1, /*rExpectedSubFilter=*/OString()); verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "pdf14lowin.pdf", 1,
/*rExpectedSubFilter=*/OString());
} }
void PDFSigningTest::testPDFPAdESGood() void PDFSigningTest::testPDFPAdESGood()
{ {
verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "good-pades.pdf", 1, "ETSI.CAdES.detached"); verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "good-pades.pdf", 1,
"ETSI.CAdES.detached");
} }
void PDFSigningTest::testPartial() void PDFSigningTest::testPartial()
{ {
std::vector<SignatureInformation> aInfos = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "partial.pdf", 1, /*rExpectedSubFilter=*/OString()); std::vector<SignatureInformation> aInfos
= verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "partial.pdf", 1,
/*rExpectedSubFilter=*/OString());
CPPUNIT_ASSERT(!aInfos.empty()); CPPUNIT_ASSERT(!aInfos.empty());
SignatureInformation& rInformation = aInfos[0]; SignatureInformation& rInformation = aInfos[0];
CPPUNIT_ASSERT(rInformation.bPartialDocumentSignature); CPPUNIT_ASSERT(rInformation.bPartialDocumentSignature);
...@@ -404,7 +439,8 @@ void PDFSigningTest::testSigningCertificateAttribute() ...@@ -404,7 +439,8 @@ void PDFSigningTest::testSigningCertificateAttribute()
// Create a new signature. // Create a new signature.
OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY); OUString aSourceDir = m_directories.getURLFromSrc(DATA_DIRECTORY);
OUString aInURL = aSourceDir + "no.pdf"; OUString aInURL = aSourceDir + "no.pdf";
OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/"); OUString aTargetDir
= m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
OUString aOutURL = aTargetDir + "signing-certificate-attribute.pdf"; OUString aOutURL = aTargetDir + "signing-certificate-attribute.pdf";
bool bHadCertificates = sign(aInURL, aOutURL, 0); bool bHadCertificates = sign(aInURL, aOutURL, 0);
if (!bHadCertificates) if (!bHadCertificates)
...@@ -420,8 +456,7 @@ void PDFSigningTest::testSigningCertificateAttribute() ...@@ -420,8 +456,7 @@ void PDFSigningTest::testSigningCertificateAttribute()
void PDFSigningTest::testGood() void PDFSigningTest::testGood()
{ {
const std::initializer_list<OUStringLiteral> aNames = const std::initializer_list<OUStringLiteral> aNames = {
{
// We failed to determine if this is good or bad. // We failed to determine if this is good or bad.
"good-non-detached.pdf", "good-non-detached.pdf",
// Boolean value for dictionary key caused read error. // Boolean value for dictionary key caused read error.
...@@ -430,17 +465,19 @@ void PDFSigningTest::testGood() ...@@ -430,17 +465,19 @@ void PDFSigningTest::testGood()
for (const auto& rName : aNames) for (const auto& rName : aNames)
{ {
std::vector<SignatureInformation> aInfos = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + rName, 1, /*rExpectedSubFilter=*/OString()); std::vector<SignatureInformation> aInfos
= verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + rName, 1,
/*rExpectedSubFilter=*/OString());
CPPUNIT_ASSERT(!aInfos.empty()); CPPUNIT_ASSERT(!aInfos.empty());
SignatureInformation& rInformation = aInfos[0]; SignatureInformation& rInformation = aInfos[0];
CPPUNIT_ASSERT_EQUAL(int(xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED), static_cast<int>(rInformation.nStatus)); CPPUNIT_ASSERT_EQUAL(int(xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED),
static_cast<int>(rInformation.nStatus));
} }
} }
void PDFSigningTest::testTokenize() void PDFSigningTest::testTokenize()
{ {
const std::initializer_list<OUStringLiteral> aNames = const std::initializer_list<OUStringLiteral> aNames = {
{
// We looped on this broken input. // We looped on this broken input.
"no-eof.pdf", "no-eof.pdf",
// ']' in a name token was mishandled. // ']' in a name token was mishandled.
...@@ -472,9 +509,13 @@ void PDFSigningTest::testTokenize() ...@@ -472,9 +509,13 @@ void PDFSigningTest::testTokenize()
void PDFSigningTest::testUnknownSubFilter() void PDFSigningTest::testUnknownSubFilter()
{ {
// Tokenize the bugdoc. // Tokenize the bugdoc.
uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); = xml::crypto::SEInitializer::create(mxComponentContext);
SvStream* pStream = utl::UcbStreamHelper::CreateStream(m_directories.getURLFromSrc(DATA_DIRECTORY) + "cr-comment.pdf", StreamMode::READ | StreamMode::WRITE); uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
SvStream* pStream = utl::UcbStreamHelper::CreateStream(
m_directories.getURLFromSrc(DATA_DIRECTORY) + "cr-comment.pdf",
StreamMode::READ | StreamMode::WRITE);
uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream)); uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream));
DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content); DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content);
aManager.mxSignatureStream = xStream; aManager.mxSignatureStream = xStream;
......
...@@ -27,8 +27,8 @@ namespace xmlsecurity ...@@ -27,8 +27,8 @@ namespace xmlsecurity
{ {
namespace pdfio namespace pdfio
{ {
bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature,
bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, SignatureInformation& rInformation, bool bLast) SignatureInformation& rInformation, bool bLast)
{ {
vcl::filter::PDFObjectElement* pValue = pSignature->LookupObject("V"); vcl::filter::PDFObjectElement* pValue = pSignature->LookupObject("V");
if (!pValue) if (!pValue)
...@@ -53,12 +53,15 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat ...@@ -53,12 +53,15 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
auto pSubFilter = dynamic_cast<vcl::filter::PDFNameElement*>(pValue->Lookup("SubFilter")); auto pSubFilter = dynamic_cast<vcl::filter::PDFNameElement*>(pValue->Lookup("SubFilter"));
const bool bNonDetached = pSubFilter && pSubFilter->GetValue() == "adbe.pkcs7.sha1"; const bool bNonDetached = pSubFilter && pSubFilter->GetValue() == "adbe.pkcs7.sha1";
if (!pSubFilter || (pSubFilter->GetValue() != "adbe.pkcs7.detached" && !bNonDetached && pSubFilter->GetValue() != "ETSI.CAdES.detached")) if (!pSubFilter
|| (pSubFilter->GetValue() != "adbe.pkcs7.detached" && !bNonDetached
&& pSubFilter->GetValue() != "ETSI.CAdES.detached"))
{ {
if (!pSubFilter) if (!pSubFilter)
SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: missing sub-filter"); SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: missing sub-filter");
else else
SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: unsupported sub-filter: '"<<pSubFilter->GetValue()<<"'"); SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: unsupported sub-filter: '"
<< pSubFilter->GetValue() << "'");
return false; return false;
} }
...@@ -114,7 +117,8 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat ...@@ -114,7 +117,8 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
auto pNumber = dynamic_cast<vcl::filter::PDFNumberElement*>(rByteRangeElements[i]); auto pNumber = dynamic_cast<vcl::filter::PDFNumberElement*>(rByteRangeElements[i]);
if (!pNumber) if (!pNumber)
{ {
SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: signature offset and length has to be a number"); SAL_WARN("xmlsecurity.pdfio",
"ValidateSignature: signature offset and length has to be a number");
return false; return false;
} }
...@@ -142,7 +146,8 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat ...@@ -142,7 +146,8 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
size_t nSignatureLength = static_cast<size_t>(pContents->GetValue().getLength()) + 2; size_t nSignatureLength = static_cast<size_t>(pContents->GetValue().getLength()) + 2;
if (aByteRanges[1].first != (aByteRanges[0].second + nSignatureLength)) if (aByteRanges[1].first != (aByteRanges[0].second + nSignatureLength))
{ {
SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: second range start is not the end of the signature"); SAL_WARN("xmlsecurity.pdfio",
"ValidateSignature: second range start is not the end of the signature");
return false; return false;
} }
rStream.Seek(STREAM_SEEK_TO_END); rStream.Seek(STREAM_SEEK_TO_END);
...@@ -160,7 +165,8 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat ...@@ -160,7 +165,8 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
return false; return false;
} }
return svl::crypto::Signing::Verify(rStream, aByteRanges, bNonDetached, aSignature, rInformation); return svl::crypto::Signing::Verify(rStream, aByteRanges, bNonDetached, aSignature,
rInformation);
} }
} // namespace pdfio } // namespace pdfio
......
...@@ -39,7 +39,9 @@ void generatePreview(const OString& rPdfPath, const OString& rPngPath) ...@@ -39,7 +39,9 @@ void generatePreview(const OString& rPdfPath, const OString& rPngPath)
osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPdfPath), aInURL); osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPdfPath), aInURL);
SvFileStream aInStream(aInURL, StreamMode::READ); SvFileStream aInStream(aInURL, StreamMode::READ);
WmfExternal* pExtHeader = nullptr; WmfExternal* pExtHeader = nullptr;
if (rFilter.ImportGraphic(aGraphic, OUString(), aInStream, GRFILTER_FORMAT_DONTKNOW, nullptr, GraphicFilterImportFlags::NONE, pExtHeader) != ERRCODE_NONE) if (rFilter.ImportGraphic(aGraphic, OUString(), aInStream, GRFILTER_FORMAT_DONTKNOW, nullptr,
GraphicFilterImportFlags::NONE, pExtHeader)
!= ERRCODE_NONE)
return; return;
BitmapEx aBitmapEx = aGraphic.GetBitmapEx(); BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
...@@ -66,11 +68,14 @@ int pdfVerify(int nArgc, char** pArgv) ...@@ -66,11 +68,14 @@ int pdfVerify(int nArgc, char** pArgv)
} }
catch (const uno::RuntimeException& rException) catch (const uno::RuntimeException& rException)
{ {
SAL_WARN("xmlsecurity.pdfio", "cppu::defaultBootstrap_InitialComponentContext() failed: " << rException); SAL_WARN("xmlsecurity.pdfio",
"cppu::defaultBootstrap_InitialComponentContext() failed: " << rException);
return 1; return 1;
} }
uno::Reference<lang::XMultiComponentFactory> xMultiComponentFactory = xComponentContext->getServiceManager(); uno::Reference<lang::XMultiComponentFactory> xMultiComponentFactory
uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xMultiComponentFactory, uno::UNO_QUERY); = xComponentContext->getServiceManager();
uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xMultiComponentFactory,
uno::UNO_QUERY);
comphelper::setProcessServiceFactory(xMultiServiceFactory); comphelper::setProcessServiceFactory(xMultiServiceFactory);
if (nArgc > 3 && OString(pArgv[3]) == "-p") if (nArgc > 3 && OString(pArgv[3]) == "-p")
...@@ -88,10 +93,12 @@ int pdfVerify(int nArgc, char** pArgv) ...@@ -88,10 +93,12 @@ int pdfVerify(int nArgc, char** pArgv)
} }
catch (const uno::DeploymentException& rException) catch (const uno::DeploymentException& rException)
{ {
SAL_WARN("xmlsecurity.pdfio", "DeploymentException while creating SEInitializer: " << rException); SAL_WARN("xmlsecurity.pdfio",
"DeploymentException while creating SEInitializer: " << rException);
return 1; return 1;
} }
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString()); uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xSEInitializer->createSecurityContext(OUString());
OUString aInURL; OUString aInURL;
osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[1]), aInURL); osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[1]), aInURL);
...@@ -157,7 +164,8 @@ int pdfVerify(int nArgc, char** pArgv) ...@@ -157,7 +164,8 @@ int pdfVerify(int nArgc, char** pArgv)
return 1; return 1;
} }
bool bSuccess = aInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; bool bSuccess
= aInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl; std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl;
} }
} }
...@@ -166,8 +174,10 @@ int pdfVerify(int nArgc, char** pArgv) ...@@ -166,8 +174,10 @@ int pdfVerify(int nArgc, char** pArgv)
} }
std::cerr << "adding a new signature" << std::endl; std::cerr << "adding a new signature" << std::endl;
uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = xSecurityContext->getSecurityEnvironment(); uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment
uno::Sequence<uno::Reference<security::XCertificate>> aCertificates = xSecurityEnvironment->getPersonalCertificates(); = xSecurityContext->getSecurityEnvironment();
uno::Sequence<uno::Reference<security::XCertificate>> aCertificates
= xSecurityEnvironment->getPersonalCertificates();
if (!aCertificates.hasElements()) if (!aCertificates.hasElements())
{ {
SAL_WARN("xmlsecurity.pdfio", "no signing certificates found"); SAL_WARN("xmlsecurity.pdfio", "no signing certificates found");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment