Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_signature.cpp
Go to the documentation of this file.
1// Copyright 2020 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "public/fpdf_signature.h"
6
7#include <utility>
8#include <vector>
9
10#include "constants/form_fields.h"
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_dictionary.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
14#include "core/fxcrt/stl_util.h"
15#include "fpdfsdk/cpdfsdk_helpers.h"
16#include "third_party/base/numerics/safe_conversions.h"
17
18namespace {
19
20std::vector<RetainPtr<const CPDF_Dictionary>> CollectSignatures(
21 CPDF_Document* doc) {
22 std::vector<RetainPtr<const CPDF_Dictionary>> signatures;
23 const CPDF_Dictionary* root = doc->GetRoot();
24 if (!root)
25 return signatures;
26
27 RetainPtr<const CPDF_Dictionary> acro_form = root->GetDictFor("AcroForm");
28 if (!acro_form)
29 return signatures;
30
31 RetainPtr<const CPDF_Array> fields = acro_form->GetArrayFor("Fields");
32 if (!fields)
33 return signatures;
34
35 CPDF_ArrayLocker locker(std::move(fields));
36 for (auto& field : locker) {
37 RetainPtr<const CPDF_Dictionary> field_dict = field->GetDict();
38 if (field_dict && field_dict->GetNameFor(pdfium::form_fields::kFT) ==
39 pdfium::form_fields::kSig) {
40 signatures.push_back(std::move(field_dict));
41 }
42 }
43 return signatures;
44}
45
46} // namespace
47
49 auto* doc = CPDFDocumentFromFPDFDocument(document);
50 if (!doc)
51 return -1;
52
53 return fxcrt::CollectionSize<int>(CollectSignatures(doc));
54}
55
56FPDF_EXPORT FPDF_SIGNATURE FPDF_CALLCONV
57FPDF_GetSignatureObject(FPDF_DOCUMENT document, int index) {
58 auto* doc = CPDFDocumentFromFPDFDocument(document);
59 if (!doc)
60 return nullptr;
61
62 std::vector<RetainPtr<const CPDF_Dictionary>> signatures =
63 CollectSignatures(doc);
64 if (!fxcrt::IndexInBounds(signatures, index))
65 return nullptr;
66
67 return FPDFSignatureFromCPDFDictionary(signatures[index].Get());
68}
69
70FPDF_EXPORT unsigned long FPDF_CALLCONV
71FPDFSignatureObj_GetContents(FPDF_SIGNATURE signature,
72 void* buffer,
73 unsigned long length) {
74 const CPDF_Dictionary* signature_dict =
76 if (!signature_dict)
77 return 0;
78
79 RetainPtr<const CPDF_Dictionary> value_dict =
80 signature_dict->GetDictFor(pdfium::form_fields::kV);
81 if (!value_dict)
82 return 0;
83
84 ByteString contents = value_dict->GetByteStringFor("Contents");
85 const unsigned long contents_len =
86 pdfium::base::checked_cast<unsigned long>(contents.GetLength());
87 if (buffer && length >= contents_len)
88 memcpy(buffer, contents.c_str(), contents_len);
89
90 return contents_len;
91}
92
93FPDF_EXPORT unsigned long FPDF_CALLCONV
94FPDFSignatureObj_GetByteRange(FPDF_SIGNATURE signature,
95 int* buffer,
96 unsigned long length) {
97 const CPDF_Dictionary* signature_dict =
99 if (!signature_dict)
100 return 0;
101
102 RetainPtr<const CPDF_Dictionary> value_dict =
103 signature_dict->GetDictFor(pdfium::form_fields::kV);
104 if (!value_dict)
105 return 0;
106
107 RetainPtr<const CPDF_Array> byte_range = value_dict->GetArrayFor("ByteRange");
108 if (!byte_range)
109 return 0;
110
111 const unsigned long byte_range_len =
112 fxcrt::CollectionSize<unsigned long>(*byte_range);
113 if (buffer && length >= byte_range_len) {
114 for (size_t i = 0; i < byte_range_len; ++i)
115 buffer[i] = byte_range->GetIntegerAt(i);
116 }
117 return byte_range_len;
118}
119
120FPDF_EXPORT unsigned long FPDF_CALLCONV
121FPDFSignatureObj_GetSubFilter(FPDF_SIGNATURE signature,
122 char* buffer,
123 unsigned long length) {
124 const CPDF_Dictionary* signature_dict =
126 if (!signature_dict)
127 return 0;
128
129 RetainPtr<const CPDF_Dictionary> value_dict =
130 signature_dict->GetDictFor(pdfium::form_fields::kV);
131 if (!value_dict || !value_dict->KeyExist("SubFilter"))
132 return 0;
133
134 ByteString sub_filter = value_dict->GetNameFor("SubFilter");
135 return NulTerminateMaybeCopyAndReturnLength(sub_filter, buffer, length);
136}
137
138FPDF_EXPORT unsigned long FPDF_CALLCONV
139FPDFSignatureObj_GetReason(FPDF_SIGNATURE signature,
140 void* buffer,
141 unsigned long length) {
142 const CPDF_Dictionary* signature_dict =
144 if (!signature_dict)
145 return 0;
146
147 RetainPtr<const CPDF_Dictionary> value_dict =
148 signature_dict->GetDictFor(pdfium::form_fields::kV);
149 if (!value_dict)
150 return 0;
151
152 RetainPtr<const CPDF_Object> obj = value_dict->GetObjectFor("Reason");
153 if (!obj || !obj->IsString())
154 return 0;
155
156 return Utf16EncodeMaybeCopyAndReturnLength(obj->GetUnicodeText(), buffer,
157 length);
158}
159
160FPDF_EXPORT unsigned long FPDF_CALLCONV
161FPDFSignatureObj_GetTime(FPDF_SIGNATURE signature,
162 char* buffer,
163 unsigned long length) {
164 const CPDF_Dictionary* signature_dict =
166 if (!signature_dict)
167 return 0;
168
169 RetainPtr<const CPDF_Dictionary> value_dict =
170 signature_dict->GetDictFor(pdfium::form_fields::kV);
171 if (!value_dict)
172 return 0;
173
174 RetainPtr<const CPDF_Object> obj = value_dict->GetObjectFor("M");
175 if (!obj || !obj->IsString())
176 return 0;
177
178 return NulTerminateMaybeCopyAndReturnLength(obj->GetString(), buffer, length);
179}
180
181FPDF_EXPORT unsigned int FPDF_CALLCONV
182FPDFSignatureObj_GetDocMDPPermission(FPDF_SIGNATURE signature) {
183 int permission = 0;
184 const CPDF_Dictionary* signature_dict =
186 if (!signature_dict)
187 return permission;
188
189 RetainPtr<const CPDF_Dictionary> value_dict =
190 signature_dict->GetDictFor(pdfium::form_fields::kV);
191 if (!value_dict)
192 return permission;
193
194 RetainPtr<const CPDF_Array> references = value_dict->GetArrayFor("Reference");
195 if (!references)
196 return permission;
197
198 CPDF_ArrayLocker locker(std::move(references));
199 for (auto& reference : locker) {
200 RetainPtr<const CPDF_Dictionary> reference_dict = reference->GetDict();
201 if (!reference_dict)
202 continue;
203
204 ByteString transform_method = reference_dict->GetNameFor("TransformMethod");
205 if (transform_method != "DocMDP")
206 continue;
207
208 RetainPtr<const CPDF_Dictionary> transform_params =
209 reference_dict->GetDictFor("TransformParams");
210 if (!transform_params)
211 continue;
212
213 // Valid values are 1, 2 and 3; 2 is the default.
214 permission = transform_params->GetIntegerFor("P", 2);
215 if (permission < 1 || permission > 3)
216 permission = 0;
217
218 return permission;
219 }
220
221 return permission;
222}
const CPDF_Dictionary * GetRoot() const
const char * c_str() const
Definition bytestring.h:76
unsigned long NulTerminateMaybeCopyAndReturnLength(const ByteString &text, void *buffer, unsigned long buflen)
const CPDF_Dictionary * CPDFDictionaryFromFPDFSignature(FPDF_SIGNATURE signature)
CPDF_Document * CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc)
FPDF_EXPORT unsigned int FPDF_CALLCONV FPDFSignatureObj_GetDocMDPPermission(FPDF_SIGNATURE signature)
FPDF_EXPORT FPDF_SIGNATURE FPDF_CALLCONV FPDF_GetSignatureObject(FPDF_DOCUMENT document, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDF_GetSignatureCount(FPDF_DOCUMENT document)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFSignatureObj_GetTime(FPDF_SIGNATURE signature, char *buffer, unsigned long length)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFSignatureObj_GetReason(FPDF_SIGNATURE signature, void *buffer, unsigned long length)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFSignatureObj_GetByteRange(FPDF_SIGNATURE signature, int *buffer, unsigned long length)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFSignatureObj_GetContents(FPDF_SIGNATURE signature, void *buffer, unsigned long length)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFSignatureObj_GetSubFilter(FPDF_SIGNATURE signature, char *buffer, unsigned long length)
#define FPDF_CALLCONV
Definition fpdfview.h:227
#define FPDF_EXPORT
Definition fpdfview.h:221