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/compiler_specific.h"
15#include "core/fxcrt/fx_memcpy_wrappers.h"
16#include "core/fxcrt/numerics/safe_conversions.h"
17#include "core/fxcrt/span.h"
18#include "core/fxcrt/span_util.h"
19#include "core/fxcrt/stl_util.h"
20#include "fpdfsdk/cpdfsdk_helpers.h"
21
22namespace {
23
24std::vector<RetainPtr<const CPDF_Dictionary>> CollectSignatures(
25 CPDF_Document* doc) {
26 std::vector<RetainPtr<const CPDF_Dictionary>> signatures;
27 const CPDF_Dictionary* root = doc->GetRoot();
28 if (!root)
29 return signatures;
30
31 RetainPtr<const CPDF_Dictionary> acro_form = root->GetDictFor("AcroForm");
32 if (!acro_form)
33 return signatures;
34
35 RetainPtr<const CPDF_Array> fields = acro_form->GetArrayFor("Fields");
36 if (!fields)
37 return signatures;
38
39 CPDF_ArrayLocker locker(std::move(fields));
40 for (auto& field : locker) {
41 RetainPtr<const CPDF_Dictionary> field_dict = field->GetDict();
42 if (field_dict && field_dict->GetNameFor(pdfium::form_fields::kFT) ==
43 pdfium::form_fields::kSig) {
44 signatures.push_back(std::move(field_dict));
45 }
46 }
47 return signatures;
48}
49
50} // namespace
51
53 auto* doc = CPDFDocumentFromFPDFDocument(document);
54 if (!doc)
55 return -1;
56
57 return fxcrt::CollectionSize<int>(CollectSignatures(doc));
58}
59
60FPDF_EXPORT FPDF_SIGNATURE FPDF_CALLCONV
61FPDF_GetSignatureObject(FPDF_DOCUMENT document, int index) {
62 auto* doc = CPDFDocumentFromFPDFDocument(document);
63 if (!doc)
64 return nullptr;
65
66 std::vector<RetainPtr<const CPDF_Dictionary>> signatures =
67 CollectSignatures(doc);
68 if (!fxcrt::IndexInBounds(signatures, index))
69 return nullptr;
70
71 return FPDFSignatureFromCPDFDictionary(signatures[index].Get());
72}
73
74FPDF_EXPORT unsigned long FPDF_CALLCONV
75FPDFSignatureObj_GetContents(FPDF_SIGNATURE signature,
76 void* buffer,
77 unsigned long length) {
78 const CPDF_Dictionary* signature_dict =
80 if (!signature_dict) {
81 return 0;
82 }
83 RetainPtr<const CPDF_Dictionary> value_dict =
84 signature_dict->GetDictFor(pdfium::form_fields::kV);
85 if (!value_dict) {
86 return 0;
87 }
88 // SAFETY: required from caller.
89 auto result_span = UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length));
90 ByteString contents = value_dict->GetByteStringFor("Contents");
91 fxcrt::try_spancpy(result_span, contents.span());
92 return pdfium::checked_cast<unsigned long>(contents.span().size());
93}
94
95FPDF_EXPORT unsigned long FPDF_CALLCONV
96FPDFSignatureObj_GetByteRange(FPDF_SIGNATURE signature,
97 int* buffer,
98 unsigned long length) {
99 const CPDF_Dictionary* signature_dict =
101 if (!signature_dict)
102 return 0;
103
104 RetainPtr<const CPDF_Dictionary> value_dict =
105 signature_dict->GetDictFor(pdfium::form_fields::kV);
106 if (!value_dict)
107 return 0;
108
109 RetainPtr<const CPDF_Array> byte_range = value_dict->GetArrayFor("ByteRange");
110 if (!byte_range)
111 return 0;
112
113 const unsigned long byte_range_len =
114 fxcrt::CollectionSize<unsigned long>(*byte_range);
115 if (buffer && length >= byte_range_len) {
116 // SAFETY: required from caller.
117 auto buffer_span = UNSAFE_BUFFERS(pdfium::make_span(buffer, length));
118 for (size_t i = 0; i < byte_range_len; ++i) {
119 buffer_span[i] = byte_range->GetIntegerAt(i);
120 }
121 }
122 return byte_range_len;
123}
124
125FPDF_EXPORT unsigned long FPDF_CALLCONV
126FPDFSignatureObj_GetSubFilter(FPDF_SIGNATURE signature,
127 char* buffer,
128 unsigned long length) {
129 const CPDF_Dictionary* signature_dict =
131 if (!signature_dict)
132 return 0;
133
134 RetainPtr<const CPDF_Dictionary> value_dict =
135 signature_dict->GetDictFor(pdfium::form_fields::kV);
136 if (!value_dict || !value_dict->KeyExist("SubFilter"))
137 return 0;
138
139 ByteString sub_filter = value_dict->GetNameFor("SubFilter");
140
141 // SAFETY: required from caller.
142 return NulTerminateMaybeCopyAndReturnLength(
143 sub_filter, UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length)));
144}
145
146FPDF_EXPORT unsigned long FPDF_CALLCONV
147FPDFSignatureObj_GetReason(FPDF_SIGNATURE signature,
148 void* buffer,
149 unsigned long length) {
150 const CPDF_Dictionary* signature_dict =
152 if (!signature_dict)
153 return 0;
154
155 RetainPtr<const CPDF_Dictionary> value_dict =
156 signature_dict->GetDictFor(pdfium::form_fields::kV);
157 if (!value_dict)
158 return 0;
159
160 RetainPtr<const CPDF_Object> obj = value_dict->GetObjectFor("Reason");
161 if (!obj || !obj->IsString())
162 return 0;
163
164 // SAFETY: required from caller.
165 return Utf16EncodeMaybeCopyAndReturnLength(
166 obj->GetUnicodeText(),
167 UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length)));
168}
169
170FPDF_EXPORT unsigned long FPDF_CALLCONV
171FPDFSignatureObj_GetTime(FPDF_SIGNATURE signature,
172 char* buffer,
173 unsigned long length) {
174 const CPDF_Dictionary* signature_dict =
176 if (!signature_dict)
177 return 0;
178
179 RetainPtr<const CPDF_Dictionary> value_dict =
180 signature_dict->GetDictFor(pdfium::form_fields::kV);
181 if (!value_dict)
182 return 0;
183
184 RetainPtr<const CPDF_Object> obj = value_dict->GetObjectFor("M");
185 if (!obj || !obj->IsString())
186 return 0;
187
188 // SAFETY: required from caller.
189 return NulTerminateMaybeCopyAndReturnLength(
190 obj->GetString(), UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length)));
191}
192
193FPDF_EXPORT unsigned int FPDF_CALLCONV
194FPDFSignatureObj_GetDocMDPPermission(FPDF_SIGNATURE signature) {
195 int permission = 0;
196 const CPDF_Dictionary* signature_dict =
198 if (!signature_dict)
199 return permission;
200
201 RetainPtr<const CPDF_Dictionary> value_dict =
202 signature_dict->GetDictFor(pdfium::form_fields::kV);
203 if (!value_dict)
204 return permission;
205
206 RetainPtr<const CPDF_Array> references = value_dict->GetArrayFor("Reference");
207 if (!references)
208 return permission;
209
210 CPDF_ArrayLocker locker(std::move(references));
211 for (auto& reference : locker) {
212 RetainPtr<const CPDF_Dictionary> reference_dict = reference->GetDict();
213 if (!reference_dict)
214 continue;
215
216 ByteString transform_method = reference_dict->GetNameFor("TransformMethod");
217 if (transform_method != "DocMDP")
218 continue;
219
220 RetainPtr<const CPDF_Dictionary> transform_params =
221 reference_dict->GetDictFor("TransformParams");
222 if (!transform_params)
223 continue;
224
225 // Valid values are 1, 2 and 3; 2 is the default.
226 permission = transform_params->GetIntegerFor("P", 2);
227 if (permission < 1 || permission > 3)
228 permission = 0;
229
230 return permission;
231 }
232
233 return permission;
234}
fxcrt::ByteString ByteString
Definition bytestring.h:180
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
const CPDF_Dictionary * GetRoot() const
#define UNSAFE_BUFFERS(...)
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:229
#define FPDF_EXPORT
Definition fpdfview.h:223