Coverage Report

Created: 2026-06-07 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/glib/poppler-form-field.cc
Line
Count
Source
1
/* poppler-form-field.cc: glib interface to poppler
2
 *
3
 * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
4
 * Copyright (C) 2006 Julien Rebetez
5
 * Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de>
6
 * Copyright (C) 2021 André Guerreiro <aguerreiro1985@gmail.com>
7
 * Copyright (C) 2021, 2023 Marek Kasik <mkasik@redhat.com>
8
 * Copyright (C) 2023-2026 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
9
 * Copyright (C) 2025 Jan-Michael Brummer <jan-michael.brummer1@volkswagen.de>
10
 * Copyright (C) 2025 lbaudin <lbaudin@gnome.org>
11
 * Copyright (C) 2025, 2026 Albert Astals Cid <aacid@kde.org>
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2, or (at your option)
16
 * any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
26
 */
27
28
#include <memory>
29
30
#include "poppler.h"
31
#include "poppler-private.h"
32
33
#include <CertificateInfo.h>
34
#if ENABLE_NSS3
35
#    include <NSSCryptoSignBackend.h>
36
#endif
37
#include <CryptoSignBackend.h>
38
39
/**
40
 * SECTION:poppler-form-field
41
 * @short_description: Form Field
42
 * @title: PopplerFormField
43
 */
44
45
struct _PopplerFormFieldClass
46
{
47
    GObjectClass parent_class;
48
};
49
using PopplerFormFieldClass = _PopplerFormFieldClass;
50
51
0
G_DEFINE_TYPE(PopplerFormField, poppler_form_field, G_TYPE_OBJECT)
52
0
53
0
static void poppler_form_field_finalize(GObject *object)
54
0
{
55
0
    PopplerFormField *field = POPPLER_FORM_FIELD(object);
56
57
0
    if (field->document) {
58
0
        g_object_unref(field->document);
59
0
        field->document = nullptr;
60
0
    }
61
0
    if (field->action) {
62
0
        poppler_action_free(field->action);
63
0
        field->action = nullptr;
64
0
    }
65
0
    field->widget = nullptr;
66
67
0
    G_OBJECT_CLASS(poppler_form_field_parent_class)->finalize(object);
68
0
}
69
70
0
static void poppler_form_field_init(PopplerFormField * /*field*/) { }
71
72
static void poppler_form_field_class_init(PopplerFormFieldClass *klass)
73
0
{
74
0
    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
75
76
0
    gobject_class->finalize = poppler_form_field_finalize;
77
0
}
78
79
PopplerFormField *_poppler_form_field_new(PopplerDocument *document, FormWidget *field)
80
0
{
81
0
    PopplerFormField *poppler_field;
82
83
0
    g_return_val_if_fail(POPPLER_IS_DOCUMENT(document), NULL);
84
0
    g_return_val_if_fail(field != nullptr, NULL);
85
86
0
    poppler_field = POPPLER_FORM_FIELD(g_object_new(POPPLER_TYPE_FORM_FIELD, nullptr));
87
88
0
    poppler_field->document = static_cast<PopplerDocument *> g_object_ref(document);
89
0
    poppler_field->widget = field;
90
91
0
    return poppler_field;
92
0
}
93
94
/* Public methods */
95
/**
96
 * poppler_form_field_get_field_type:
97
 * @field: a #PopplerFormField
98
 *
99
 * Gets the type of @field
100
 *
101
 * Return value: #PopplerFormFieldType of @field
102
 **/
103
PopplerFormFieldType poppler_form_field_get_field_type(PopplerFormField *field)
104
0
{
105
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), POPPLER_FORM_FIELD_UNKNOWN);
106
107
0
    switch (field->widget->getType()) {
108
0
    case formButton:
109
0
        return POPPLER_FORM_FIELD_BUTTON;
110
0
    case formText:
111
0
        return POPPLER_FORM_FIELD_TEXT;
112
0
    case formChoice:
113
0
        return POPPLER_FORM_FIELD_CHOICE;
114
0
    case formSignature:
115
0
        return POPPLER_FORM_FIELD_SIGNATURE;
116
0
    default:
117
0
        g_warning("Unsupported Form Field Type");
118
0
    }
119
120
0
    return POPPLER_FORM_FIELD_UNKNOWN;
121
0
}
122
123
/**
124
 * poppler_form_field_get_id:
125
 * @field: a #PopplerFormField
126
 *
127
 * Gets the id of @field
128
 *
129
 * Return value: the id of @field
130
 **/
131
gint poppler_form_field_get_id(PopplerFormField *field)
132
0
{
133
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), -1);
134
135
0
    return field->widget->getID();
136
0
}
137
138
/**
139
 * poppler_form_field_get_font_size:
140
 * @field: a #PopplerFormField
141
 *
142
 * Gets the font size of @field
143
 *
144
 * WARNING: This function always returns 0. Contact the poppler
145
 * mailing list if you're interested in implementing it properly
146
 *
147
 * Return value: the font size of @field
148
 **/
149
gdouble poppler_form_field_get_font_size(PopplerFormField *field)
150
0
{
151
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), 0);
152
153
0
    return 0;
154
0
}
155
156
/**
157
 * poppler_form_field_is_read_only:
158
 * @field: a #PopplerFormField
159
 *
160
 * Checks whether @field is read only
161
 *
162
 * Return value: %TRUE if @field is read only
163
 **/
164
gboolean poppler_form_field_is_read_only(PopplerFormField *field)
165
0
{
166
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), FALSE);
167
168
0
    return field->widget->isReadOnly();
169
0
}
170
171
/**
172
 * poppler_form_field_get_action:
173
 * @field: a #PopplerFormField
174
 *
175
 * Retrieves the action (#PopplerAction) that shall be
176
 * performed when @field is activated, or %NULL
177
 *
178
 * Return value: (transfer none): the action to perform. The returned
179
 *               object is owned by @field and should not be freed
180
 *
181
 * Since: 0.18
182
 */
183
PopplerAction *poppler_form_field_get_action(PopplerFormField *field)
184
0
{
185
0
    const LinkAction *action;
186
187
0
    if (field->action) {
188
0
        return field->action;
189
0
    }
190
191
0
    action = field->widget->getActivationAction();
192
0
    if (!action) {
193
0
        return nullptr;
194
0
    }
195
196
0
    field->action = _poppler_action_new(field->document, action, nullptr);
197
198
0
    return field->action;
199
0
}
200
201
/**
202
 * poppler_form_field_get_additional_action:
203
 * @field: a #PopplerFormField
204
 * @type: the type of additional action
205
 *
206
 * Retrieves the action (#PopplerAction) that shall be performed when
207
 * an additional action is triggered on @field, or %NULL.
208
 *
209
 * Return value: (transfer none): the action to perform. The returned
210
 *               object is owned by @field and should not be freed.
211
 *
212
 *
213
 * Since: 0.72
214
 */
215
PopplerAction *poppler_form_field_get_additional_action(PopplerFormField *field, PopplerAdditionalActionType type)
216
0
{
217
0
    Annot::FormAdditionalActionsType form_action;
218
0
    PopplerAction **action;
219
220
0
    switch (type) {
221
0
    case POPPLER_ADDITIONAL_ACTION_FIELD_MODIFIED:
222
0
        form_action = Annot::actionFieldModified;
223
0
        action = &field->field_modified_action;
224
0
        break;
225
0
    case POPPLER_ADDITIONAL_ACTION_FORMAT_FIELD:
226
0
        form_action = Annot::actionFormatField;
227
0
        action = &field->format_field_action;
228
0
        break;
229
0
    case POPPLER_ADDITIONAL_ACTION_VALIDATE_FIELD:
230
0
        form_action = Annot::actionValidateField;
231
0
        action = &field->validate_field_action;
232
0
        break;
233
0
    case POPPLER_ADDITIONAL_ACTION_CALCULATE_FIELD:
234
0
        form_action = Annot::actionCalculateField;
235
0
        action = &field->calculate_field_action;
236
0
        break;
237
0
    default:
238
0
        g_return_val_if_reached(nullptr);
239
0
        return nullptr;
240
0
    }
241
242
0
    if (*action) {
243
0
        return *action;
244
0
    }
245
246
0
    std::unique_ptr<LinkAction> link_action = field->widget->getAdditionalAction(form_action);
247
0
    if (!link_action) {
248
0
        return nullptr;
249
0
    }
250
251
0
    *action = _poppler_action_new(nullptr, link_action.get(), nullptr);
252
253
0
    return *action;
254
0
}
255
256
/* Button Field */
257
/**
258
 * poppler_form_field_button_get_button_type:
259
 * @field: a #PopplerFormField
260
 *
261
 * Gets the button type of @field
262
 *
263
 * Return value: #PopplerFormButtonType of @field
264
 **/
265
PopplerFormButtonType poppler_form_field_button_get_button_type(PopplerFormField *field)
266
0
{
267
0
    g_return_val_if_fail(field->widget->getType() == formButton, POPPLER_FORM_BUTTON_PUSH);
268
269
0
    switch (static_cast<FormWidgetButton *>(field->widget)->getButtonType()) {
270
0
    case formButtonPush:
271
0
        return POPPLER_FORM_BUTTON_PUSH;
272
0
    case formButtonCheck:
273
0
        return POPPLER_FORM_BUTTON_CHECK;
274
0
    case formButtonRadio:
275
0
        return POPPLER_FORM_BUTTON_RADIO;
276
0
    default:
277
0
        g_assert_not_reached();
278
0
    }
279
0
}
280
281
/**
282
 * poppler_form_field_button_get_state:
283
 * @field: a #PopplerFormField
284
 *
285
 * Queries a #PopplerFormField and returns its current state. Returns %TRUE if
286
 * @field is pressed in and %FALSE if it is raised.
287
 *
288
 * Return value: current state of @field
289
 **/
290
gboolean poppler_form_field_button_get_state(PopplerFormField *field)
291
0
{
292
0
    g_return_val_if_fail(field->widget->getType() == formButton, FALSE);
293
294
0
    return static_cast<FormWidgetButton *>(field->widget)->getState();
295
0
}
296
297
/**
298
 * poppler_form_field_button_set_state:
299
 * @field: a #PopplerFormField
300
 * @state: %TRUE or %FALSE
301
 *
302
 * Sets the status of @field. Set to %TRUE if you want the #PopplerFormField
303
 * to be 'pressed in', and %FALSE to raise it.
304
 **/
305
void poppler_form_field_button_set_state(PopplerFormField *field, gboolean state)
306
0
{
307
0
    g_return_if_fail(field->widget->getType() == formButton);
308
309
0
    static_cast<FormWidgetButton *>(field->widget)->setState(static_cast<bool>(state));
310
0
}
311
312
/**
313
 * poppler_form_field_get_partial_name:
314
 * @field: a #PopplerFormField
315
 *
316
 * Gets the partial name of @field.
317
 *
318
 * Return value: a new allocated string. It must be freed with g_free() when done.
319
 *
320
 * Since: 0.16
321
 **/
322
gchar *poppler_form_field_get_partial_name(PopplerFormField *field)
323
0
{
324
0
    const GooString *tmp;
325
326
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
327
328
0
    tmp = field->widget->getPartialName();
329
330
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
331
0
}
332
333
/**
334
 * poppler_form_field_get_mapping_name:
335
 * @field: a #PopplerFormField
336
 *
337
 * Gets the mapping name of @field that is used when
338
 * exporting interactive form field data from the document
339
 *
340
 * Return value: a new allocated string. It must be freed with g_free() when done.
341
 *
342
 * Since: 0.16
343
 **/
344
gchar *poppler_form_field_get_mapping_name(PopplerFormField *field)
345
0
{
346
0
    const GooString *tmp;
347
348
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
349
350
0
    tmp = field->widget->getMappingName();
351
352
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
353
0
}
354
355
/**
356
 * poppler_form_field_get_name:
357
 * @field: a #PopplerFormField
358
 *
359
 * Gets the fully qualified name of @field. It's constructed by concatenating
360
 * the partial field names of the field and all of its ancestors.
361
 *
362
 * Return value: a new allocated string. It must be freed with g_free() when done.
363
 *
364
 * Since: 0.16
365
 **/
366
gchar *poppler_form_field_get_name(PopplerFormField *field)
367
0
{
368
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
369
370
0
    const GooString *tmp = field->widget->getFullyQualifiedName();
371
372
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
373
0
}
374
375
/**
376
 * poppler_form_field_get_alternate_ui_name:
377
 * @field: a #PopplerFormField
378
 *
379
 * Gets the alternate ui name of @field. This name is also commonly
380
 * used by pdf producers/readers to show it as a tooltip when @field area
381
 * is hovered by a pointing device (eg. mouse).
382
 *
383
 * Return value: a new allocated string. It must be freed with g_free() when done.
384
 *
385
 * Since: 0.88
386
 **/
387
gchar *poppler_form_field_get_alternate_ui_name(PopplerFormField *field)
388
0
{
389
0
    const GooString *tmp;
390
391
0
    g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
392
393
0
    tmp = field->widget->getAlternateUiName();
394
395
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
396
0
}
397
398
/**
399
 * PopplerCertificateInfo:
400
 *
401
 * PopplerCertificateInfo contains detailed info about a signing certificate.
402
 *
403
 * Since 24.10 this type supports g_autoptr
404
 *
405
 * Since: 23.07.0
406
 */
407
struct _PopplerCertificateInfo
408
{
409
    char *id;
410
    char *subject_common_name;
411
    char *subject_organization;
412
    char *subject_email;
413
    char *issuer_common_name;
414
    char *issuer_organization;
415
    char *issuer_email;
416
    GDateTime *issued;
417
    GDateTime *expires;
418
};
419
420
G_DEFINE_BOXED_TYPE(PopplerCertificateInfo, poppler_certificate_info, poppler_certificate_info_copy, poppler_certificate_info_free)
421
422
/**
423
 * PopplerSignatureInfo:
424
 *
425
 * PopplerSignatureInfo contains detailed info about a signature
426
 * contained in a form field.
427
 *
428
 * Since 24.10 this type supports g_autoptr
429
 *
430
 * Since: 21.12.0
431
 **/
432
struct _PopplerSignatureInfo
433
{
434
    PopplerSignatureStatus sig_status;
435
    PopplerCertificateStatus cert_status;
436
    char *signer_name;
437
    GDateTime *local_signing_time;
438
    PopplerCertificateInfo *certificate_info;
439
};
440
441
static PopplerSignatureInfo *_poppler_form_field_signature_validate(PopplerFormField *field, PopplerSignatureValidationFlags flags, gboolean force_revalidation, GError **error)
442
0
{
443
0
    FormFieldSignature *sig_field;
444
0
    SignatureInfo *sig_info;
445
0
    PopplerSignatureInfo *poppler_sig_info;
446
0
    const X509CertificateInfo *certificate_info;
447
448
0
    if (poppler_form_field_get_field_type(field) != POPPLER_FORM_FIELD_SIGNATURE) {
449
0
        g_set_error(error, POPPLER_ERROR, POPPLER_ERROR_INVALID, "Wrong FormField type");
450
0
        return nullptr;
451
0
    }
452
453
0
    sig_field = static_cast<FormFieldSignature *>(field->widget->getField());
454
455
0
    sig_info = sig_field->validateSignatureAsync(flags & POPPLER_SIGNATURE_VALIDATION_FLAG_VALIDATE_CERTIFICATE, force_revalidation, -1, !(flags & POPPLER_SIGNATURE_VALIDATION_FLAG_WITHOUT_OCSP_REVOCATION_CHECK),
456
0
                                                 flags & POPPLER_SIGNATURE_VALIDATION_FLAG_USE_AIA_CERTIFICATE_FETCH, {});
457
0
    CertificateValidationStatus certificateStatus = sig_field->validateSignatureResult();
458
459
0
    poppler_sig_info = g_new0(PopplerSignatureInfo, 1);
460
0
    switch (sig_info->getSignatureValStatus()) {
461
0
    case SIGNATURE_VALID:
462
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_VALID;
463
0
        break;
464
0
    case SIGNATURE_INVALID:
465
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_INVALID;
466
0
        break;
467
0
    case SIGNATURE_DIGEST_MISMATCH:
468
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_DIGEST_MISMATCH;
469
0
        break;
470
0
    case SIGNATURE_DECODING_ERROR:
471
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_DECODING_ERROR;
472
0
        break;
473
0
    case SIGNATURE_GENERIC_ERROR:
474
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_GENERIC_ERROR;
475
0
        break;
476
0
    case SIGNATURE_NOT_FOUND:
477
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_FOUND;
478
0
        break;
479
0
    case SIGNATURE_NOT_VERIFIED:
480
0
        poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_VERIFIED;
481
0
        break;
482
0
    }
483
484
0
    switch (certificateStatus) {
485
0
    case CERTIFICATE_TRUSTED:
486
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_TRUSTED;
487
0
        break;
488
0
    case CERTIFICATE_UNTRUSTED_ISSUER:
489
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNTRUSTED_ISSUER;
490
0
        break;
491
0
    case CERTIFICATE_UNKNOWN_ISSUER:
492
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNKNOWN_ISSUER;
493
0
        break;
494
0
    case CERTIFICATE_REVOKED:
495
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_REVOKED;
496
0
        break;
497
0
    case CERTIFICATE_EXPIRED:
498
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_EXPIRED;
499
0
        break;
500
0
    case CERTIFICATE_GENERIC_ERROR:
501
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_GENERIC_ERROR;
502
0
        break;
503
0
    case CERTIFICATE_NOT_VERIFIED:
504
0
        poppler_sig_info->cert_status = POPPLER_CERTIFICATE_NOT_VERIFIED;
505
0
        break;
506
0
    }
507
508
0
    std::string signerName = sig_info->getSignerName();
509
0
    poppler_sig_info->signer_name = g_strdup(signerName.c_str());
510
0
    poppler_sig_info->local_signing_time = g_date_time_new_from_unix_local(sig_info->getSigningTime());
511
512
0
    certificate_info = sig_info->getCertificateInfo();
513
0
    if (certificate_info != nullptr) {
514
0
        const X509CertificateInfo::EntityInfo &subject_info = certificate_info->getSubjectInfo();
515
0
        const X509CertificateInfo::EntityInfo &issuer_info = certificate_info->getIssuerInfo();
516
0
        const X509CertificateInfo::Validity &validity = certificate_info->getValidity();
517
518
0
        poppler_sig_info->certificate_info = poppler_certificate_info_new();
519
0
        poppler_sig_info->certificate_info->subject_common_name = g_strdup(subject_info.commonName.c_str());
520
0
        poppler_sig_info->certificate_info->subject_organization = g_strdup(subject_info.organization.c_str());
521
0
        poppler_sig_info->certificate_info->subject_email = g_strdup(subject_info.email.c_str());
522
0
        poppler_sig_info->certificate_info->issuer_common_name = g_strdup(issuer_info.commonName.c_str());
523
0
        poppler_sig_info->certificate_info->issuer_email = g_strdup(issuer_info.email.c_str());
524
0
        poppler_sig_info->certificate_info->issuer_organization = g_strdup(issuer_info.organization.c_str());
525
0
        poppler_sig_info->certificate_info->issued = g_date_time_new_from_unix_utc(std::chrono::duration_cast<std::chrono::seconds>(validity.notBefore.time_since_epoch()).count());
526
0
        poppler_sig_info->certificate_info->expires = g_date_time_new_from_unix_utc(std::chrono::duration_cast<std::chrono::seconds>(validity.notAfter.time_since_epoch()).count());
527
0
    }
528
529
0
    return poppler_sig_info;
530
0
}
531
532
static void signature_validate_thread(GTask *task, gpointer source_object, gpointer task_data, GCancellable * /*cancellable*/)
533
0
{
534
0
    auto flags = static_cast<PopplerSignatureValidationFlags> GPOINTER_TO_INT(task_data);
535
0
    PopplerSignatureInfo *signature_info;
536
0
    auto *field = static_cast<PopplerFormField *>(source_object);
537
0
    GError *error = nullptr;
538
539
0
    signature_info = _poppler_form_field_signature_validate(field, flags, FALSE, &error);
540
0
    if (signature_info == nullptr && error != nullptr) {
541
0
        g_task_return_error(task, error);
542
0
        return;
543
0
    }
544
545
0
    if (g_task_set_return_on_cancel(task, FALSE)) {
546
0
        g_task_return_pointer(task, signature_info, reinterpret_cast<GDestroyNotify>(poppler_signature_info_free));
547
0
    }
548
0
}
549
550
/**
551
 * poppler_form_field_signature_validate_sync:
552
 * @field: a #PopplerFormField that represents a signature annotation
553
 * @flags: #PopplerSignatureValidationFlags flags influencing process of validation of the field signature
554
 * @cancellable: (nullable): optional #GCancellable object
555
 * @error: a #GError
556
 *
557
 * Synchronously validates the cryptographic signature contained in @signature_field.
558
 *
559
 * Return value: (transfer full): a #PopplerSignatureInfo structure containing signature metadata and validation status
560
 *                                Free the returned structure with poppler_signature_info_free().
561
 *
562
 * Since: 21.12.0
563
 **/
564
PopplerSignatureInfo *poppler_form_field_signature_validate_sync(PopplerFormField *field, PopplerSignatureValidationFlags flags, GCancellable *cancellable, GError **error)
565
0
{
566
0
    PopplerSignatureInfo *signature_info;
567
0
    GTask *task;
568
569
0
    g_return_val_if_fail(error == nullptr || *error == nullptr, NULL);
570
571
0
    task = g_task_new(field, cancellable, nullptr, nullptr);
572
0
    g_task_set_task_data(task, GINT_TO_POINTER(flags), nullptr);
573
0
    g_task_set_return_on_cancel(task, TRUE);
574
575
0
    g_task_run_in_thread_sync(task, signature_validate_thread);
576
577
0
    signature_info = static_cast<PopplerSignatureInfo *>(g_task_propagate_pointer(task, error));
578
0
    g_object_unref(task);
579
580
0
    return signature_info;
581
0
}
582
583
/**
584
 * poppler_form_field_signature_validate_async:
585
 * @field: a #PopplerFormField that represents a signature annotation
586
 * @flags: #PopplerSignatureValidationFlags flags influencing process of validation of the field signature
587
 * @cancellable: (nullable): optional #GCancellable object
588
 * @callback: (scope async) (closure user_data): a #GAsyncReadyCallback to call when the signature is validated
589
 * @user_data: the data to pass to callback function
590
 *
591
 * Asynchronously validates the cryptographic signature contained in @signature_field.
592
 *
593
 * Since: 21.12.0
594
 **/
595
void poppler_form_field_signature_validate_async(PopplerFormField *field, PopplerSignatureValidationFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
596
0
{
597
0
    GTask *task;
598
599
0
    task = g_task_new(field, cancellable, callback, user_data);
600
0
    g_task_set_task_data(task, GINT_TO_POINTER(flags), nullptr);
601
0
    g_task_set_return_on_cancel(task, TRUE);
602
603
0
    g_task_run_in_thread(task, signature_validate_thread);
604
605
0
    g_object_unref(task);
606
0
}
607
608
/**
609
 * poppler_form_field_signature_validate_finish:
610
 * @field: a #PopplerFormField that represents a signature annotation
611
 * @result: a #GAsyncResult
612
 * @error: a #GError
613
 *
614
 * Finishes validation of the cryptographic signature contained in @signature_field.
615
 * See poppler_form_field_signature_validate_async().
616
 *
617
 * Return value: (transfer full): a #PopplerSignatureInfo structure containing signature metadata and validation status
618
 *                                Free the returned structure with poppler_signature_info_free().
619
 *
620
 * Since: 21.12.0
621
 **/
622
PopplerSignatureInfo *poppler_form_field_signature_validate_finish(PopplerFormField *field, GAsyncResult *result, GError **error)
623
0
{
624
0
    g_return_val_if_fail(g_task_is_valid(result, field), NULL);
625
626
0
    return static_cast<PopplerSignatureInfo *>(g_task_propagate_pointer(G_TASK(result), error));
627
0
}
628
629
G_DEFINE_BOXED_TYPE(PopplerSignatureInfo, poppler_signature_info, poppler_signature_info_copy, poppler_signature_info_free)
630
631
/**
632
 * poppler_signature_info_copy:
633
 * @siginfo: a #PopplerSignatureInfo structure containing signature metadata and validation status
634
 *
635
 * Copies @siginfo, creating an identical #PopplerSignatureInfo.
636
 *
637
 * Return value: (transfer full): a new #PopplerSignatureInfo structure identical to @siginfo
638
 *
639
 * Since: 21.12.0
640
 **/
641
PopplerSignatureInfo *poppler_signature_info_copy(const PopplerSignatureInfo *siginfo)
642
0
{
643
0
    PopplerSignatureInfo *new_info;
644
645
0
    g_return_val_if_fail(siginfo != nullptr, NULL);
646
647
0
    new_info = g_new(PopplerSignatureInfo, 1);
648
0
    new_info->sig_status = siginfo->sig_status;
649
0
    new_info->cert_status = siginfo->cert_status;
650
0
    new_info->signer_name = g_strdup(siginfo->signer_name);
651
0
    new_info->local_signing_time = g_date_time_ref(siginfo->local_signing_time);
652
0
    new_info->certificate_info = poppler_certificate_info_copy(siginfo->certificate_info);
653
654
0
    return new_info;
655
0
}
656
657
/**
658
 * poppler_signature_info_free:
659
 * @siginfo: a #PopplerSignatureInfo structure containing signature metadata and validation status
660
 *
661
 * Frees @siginfo
662
 *
663
 * Since: 21.12.0
664
 **/
665
void poppler_signature_info_free(PopplerSignatureInfo *siginfo)
666
0
{
667
0
    if (siginfo == nullptr) {
668
0
        return;
669
0
    }
670
671
0
    g_date_time_unref(siginfo->local_signing_time);
672
0
    g_free(siginfo->signer_name);
673
0
    poppler_certificate_info_free(siginfo->certificate_info);
674
0
    g_free(siginfo);
675
0
}
676
677
/**
678
 * poppler_signature_info_get_signature_status:
679
 * @siginfo: a #PopplerSignatureInfo
680
 *
681
 * Returns status of the signature for given PopplerSignatureInfo.
682
 *
683
 * Return value: signature status of the signature
684
 *
685
 * Since: 21.12.0
686
 **/
687
PopplerSignatureStatus poppler_signature_info_get_signature_status(const PopplerSignatureInfo *siginfo)
688
0
{
689
0
    g_return_val_if_fail(siginfo != nullptr, POPPLER_SIGNATURE_GENERIC_ERROR);
690
691
0
    return siginfo->sig_status;
692
0
}
693
694
/**
695
 * poppler_signature_info_get_certificate_info:
696
 * @siginfo: a #PopplerSignatureInfo
697
 *
698
 * Returns PopplerCertificateInfo for given PopplerSignatureInfo.
699
 *
700
 * Return value: (transfer none): certificate info of the signature
701
 *
702
 * Since: 23.08.0
703
 **/
704
PopplerCertificateInfo *poppler_signature_info_get_certificate_info(const PopplerSignatureInfo *siginfo)
705
0
{
706
0
    g_return_val_if_fail(siginfo != nullptr, NULL);
707
708
0
    return siginfo->certificate_info;
709
0
}
710
711
/**
712
 * poppler_signature_info_get_certificate_status:
713
 * @siginfo: a #PopplerSignatureInfo
714
 *
715
 * Returns status of the certificate for given PopplerSignatureInfo.
716
 *
717
 * Return value: certificate status of the signature
718
 *
719
 * Since: 21.12.0
720
 **/
721
PopplerCertificateStatus poppler_signature_info_get_certificate_status(const PopplerSignatureInfo *siginfo)
722
0
{
723
0
    g_return_val_if_fail(siginfo != nullptr, POPPLER_CERTIFICATE_GENERIC_ERROR);
724
725
0
    return siginfo->cert_status;
726
0
}
727
728
/**
729
 * poppler_signature_info_get_signer_name:
730
 * @siginfo: a #PopplerSignatureInfo
731
 *
732
 * Returns name of signer for given PopplerSignatureInfo.
733
 *
734
 * Return value: (transfer none): A string.
735
 *
736
 * Since: 21.12.0
737
 **/
738
const gchar *poppler_signature_info_get_signer_name(const PopplerSignatureInfo *siginfo)
739
0
{
740
0
    g_return_val_if_fail(siginfo != nullptr, NULL);
741
742
0
    return siginfo->signer_name;
743
0
}
744
745
/**
746
 * poppler_signature_info_get_local_signing_time:
747
 * @siginfo: a #PopplerSignatureInfo
748
 *
749
 * Returns local time of signing as GDateTime. This does not
750
 * contain information about time zone since it has not been
751
 * preserved during conversion.
752
 * Do not modify returned value since it is internal to
753
 * PopplerSignatureInfo.
754
 *
755
 * Return value: (transfer none): GDateTime
756
 *
757
 * Since: 21.12.0
758
 **/
759
GDateTime *poppler_signature_info_get_local_signing_time(const PopplerSignatureInfo *siginfo)
760
0
{
761
0
    g_return_val_if_fail(siginfo != nullptr, NULL);
762
763
0
    return siginfo->local_signing_time;
764
0
}
765
766
/* Text Field */
767
/**
768
 * poppler_form_field_text_get_text_type:
769
 * @field: a #PopplerFormField
770
 *
771
 * Gets the text type of @field.
772
 *
773
 * Return value: #PopplerFormTextType of @field
774
 **/
775
PopplerFormTextType poppler_form_field_text_get_text_type(PopplerFormField *field)
776
0
{
777
0
    FormWidgetText *text_field;
778
779
0
    g_return_val_if_fail(field->widget->getType() == formText, POPPLER_FORM_TEXT_NORMAL);
780
781
0
    text_field = static_cast<FormWidgetText *>(field->widget);
782
783
0
    if (text_field->isMultiline()) {
784
0
        return POPPLER_FORM_TEXT_MULTILINE;
785
0
    }
786
0
    if (text_field->isFileSelect()) {
787
0
        return POPPLER_FORM_TEXT_FILE_SELECT;
788
0
    }
789
790
0
    return POPPLER_FORM_TEXT_NORMAL;
791
0
}
792
793
/**
794
 * poppler_form_field_text_get_text:
795
 * @field: a #PopplerFormField
796
 *
797
 * Retrieves the contents of @field.
798
 *
799
 * Return value: a new allocated string. It must be freed with g_free() when done.
800
 **/
801
gchar *poppler_form_field_text_get_text(PopplerFormField *field)
802
0
{
803
0
    FormWidgetText *text_field;
804
0
    const GooString *tmp;
805
806
0
    g_return_val_if_fail(field->widget->getType() == formText, NULL);
807
808
0
    text_field = static_cast<FormWidgetText *>(field->widget);
809
0
    tmp = text_field->getContent();
810
811
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
812
0
}
813
814
/**
815
 * poppler_form_field_text_set_text:
816
 * @field: a #PopplerFormField
817
 * @text: the new text
818
 *
819
 * Sets the text in @field to the given value, replacing the current contents.
820
 **/
821
void poppler_form_field_text_set_text(PopplerFormField *field, const gchar *text)
822
0
{
823
0
    gchar *tmp;
824
0
    gsize length = 0;
825
826
0
    g_return_if_fail(field->widget->getType() == formText);
827
828
0
    tmp = text ? g_convert(text, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr;
829
0
    std::unique_ptr<GooString> goo_tmp = std::make_unique<GooString>(tmp, length);
830
0
    g_free(tmp);
831
0
    static_cast<FormWidgetText *>(field->widget)->setContent(std::move(goo_tmp));
832
0
}
833
834
/**
835
 * poppler_form_field_text_get_max_len:
836
 * @field: a #PopplerFormField
837
 *
838
 * Retrieves the maximum allowed length of the text in @field
839
 *
840
 * Return value: the maximum allowed number of characters in @field, or -1 if there is no maximum.
841
 **/
842
gint poppler_form_field_text_get_max_len(PopplerFormField *field)
843
0
{
844
0
    g_return_val_if_fail(field->widget->getType() == formText, 0);
845
846
0
    return static_cast<FormWidgetText *>(field->widget)->getMaxLen();
847
0
}
848
849
/**
850
 * poppler_form_field_text_do_spell_check:
851
 * @field: a #PopplerFormField
852
 *
853
 * Checks whether spell checking should be done for the contents of @field
854
 *
855
 * Return value: %TRUE if spell checking should be done for @field
856
 **/
857
gboolean poppler_form_field_text_do_spell_check(PopplerFormField *field)
858
0
{
859
0
    g_return_val_if_fail(field->widget->getType() == formText, FALSE);
860
861
0
    return !static_cast<FormWidgetText *>(field->widget)->noSpellCheck();
862
0
}
863
864
gboolean poppler_form_field_text_do_scroll(PopplerFormField *field)
865
0
{
866
0
    g_return_val_if_fail(field->widget->getType() == formText, FALSE);
867
868
0
    return !static_cast<FormWidgetText *>(field->widget)->noScroll();
869
0
}
870
871
/**
872
 * poppler_form_field_text_is_rich_text:
873
 * @field: a #PopplerFormField
874
 *
875
 * Checks whether the contents of @field are rich text
876
 *
877
 * Return value: %TRUE if the contents of @field are rich text
878
 **/
879
gboolean poppler_form_field_text_is_rich_text(PopplerFormField *field)
880
0
{
881
0
    g_return_val_if_fail(field->widget->getType() == formText, FALSE);
882
883
0
    return static_cast<FormWidgetText *>(field->widget)->isRichText();
884
0
}
885
886
/**
887
 * poppler_form_field_text_is_password:
888
 * @field: a #PopplerFormField
889
 *
890
 * Checks whether content of @field is a password and it must be hidden
891
 *
892
 * Return value: %TRUE if the content of @field is a password
893
 **/
894
gboolean poppler_form_field_text_is_password(PopplerFormField *field)
895
0
{
896
0
    g_return_val_if_fail(field->widget->getType() == formText, FALSE);
897
898
0
    return static_cast<FormWidgetText *>(field->widget)->isPassword();
899
0
}
900
901
/* Choice Field */
902
/**
903
 * poppler_form_field_choice_get_choice_type:
904
 * @field: a #PopplerFormField
905
 *
906
 * Gets the choice type of @field
907
 *
908
 * Return value: #PopplerFormChoiceType of @field
909
 **/
910
PopplerFormChoiceType poppler_form_field_choice_get_choice_type(PopplerFormField *field)
911
0
{
912
0
    g_return_val_if_fail(field->widget->getType() == formChoice, POPPLER_FORM_CHOICE_COMBO);
913
914
0
    if (static_cast<FormWidgetChoice *>(field->widget)->isCombo()) {
915
0
        return POPPLER_FORM_CHOICE_COMBO;
916
0
    }
917
0
    return POPPLER_FORM_CHOICE_LIST;
918
0
}
919
920
/**
921
 * poppler_form_field_choice_is_editable:
922
 * @field: a #PopplerFormField
923
 *
924
 * Checks whether @field is editable
925
 *
926
 * Return value: %TRUE if @field is editable
927
 **/
928
gboolean poppler_form_field_choice_is_editable(PopplerFormField *field)
929
0
{
930
0
    g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
931
932
0
    return static_cast<FormWidgetChoice *>(field->widget)->hasEdit();
933
0
}
934
935
/**
936
 * poppler_form_field_choice_can_select_multiple:
937
 * @field: a #PopplerFormField
938
 *
939
 * Checks whether @field allows multiple choices to be selected
940
 *
941
 * Return value: %TRUE if @field allows multiple choices to be selected
942
 **/
943
gboolean poppler_form_field_choice_can_select_multiple(PopplerFormField *field)
944
0
{
945
0
    g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
946
947
0
    return static_cast<FormWidgetChoice *>(field->widget)->isMultiSelect();
948
0
}
949
950
/**
951
 * poppler_form_field_choice_do_spell_check:
952
 * @field: a #PopplerFormField
953
 *
954
 * Checks whether spell checking should be done for the contents of @field
955
 *
956
 * Return value: %TRUE if spell checking should be done for @field
957
 **/
958
gboolean poppler_form_field_choice_do_spell_check(PopplerFormField *field)
959
0
{
960
0
    g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
961
962
0
    return !static_cast<FormWidgetChoice *>(field->widget)->noSpellCheck();
963
0
}
964
965
gboolean poppler_form_field_choice_commit_on_change(PopplerFormField *field)
966
0
{
967
0
    g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
968
969
0
    return static_cast<FormWidgetChoice *>(field->widget)->commitOnSelChange();
970
0
}
971
972
/**
973
 * poppler_form_field_choice_get_n_items:
974
 * @field: a #PopplerFormField
975
 *
976
 * Returns the number of items on @field
977
 *
978
 * Return value: the number of items on @field
979
 **/
980
gint poppler_form_field_choice_get_n_items(PopplerFormField *field)
981
0
{
982
0
    g_return_val_if_fail(field->widget->getType() == formChoice, -1);
983
984
0
    return static_cast<FormWidgetChoice *>(field->widget)->getChoices().size();
985
0
}
986
987
/**
988
 * poppler_form_field_choice_get_item:
989
 * @field: a #PopplerFormField
990
 * @index: the index of the item
991
 *
992
 * Returns the contents of the item on @field at the given index
993
 *
994
 * Return value: a new allocated string. It must be freed with g_free() when done.
995
 **/
996
gchar *poppler_form_field_choice_get_item(PopplerFormField *field, gint index)
997
0
{
998
0
    const GooString *tmp;
999
1000
0
    g_return_val_if_fail(field->widget->getType() == formChoice, NULL);
1001
0
    g_return_val_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field), NULL);
1002
1003
0
    tmp = static_cast<FormWidgetChoice *>(field->widget)->getChoice(index);
1004
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
1005
0
}
1006
1007
/**
1008
 * poppler_form_field_choice_is_item_selected:
1009
 * @field: a #PopplerFormField
1010
 * @index: the index of the item
1011
 *
1012
 * Checks whether the item at the given index on @field is currently selected
1013
 *
1014
 * Return value: %TRUE if item at @index is currently selected
1015
 **/
1016
gboolean poppler_form_field_choice_is_item_selected(PopplerFormField *field, gint index)
1017
0
{
1018
0
    g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
1019
0
    g_return_val_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field), FALSE);
1020
1021
0
    return static_cast<FormWidgetChoice *>(field->widget)->isSelected(index);
1022
0
}
1023
1024
/**
1025
 * poppler_form_field_choice_select_item:
1026
 * @field: a #PopplerFormField
1027
 * @index: the index of the item
1028
 *
1029
 * Selects the item at the given index on @field
1030
 **/
1031
void poppler_form_field_choice_select_item(PopplerFormField *field, gint index)
1032
0
{
1033
0
    g_return_if_fail(field->widget->getType() == formChoice);
1034
0
    g_return_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field));
1035
1036
0
    static_cast<FormWidgetChoice *>(field->widget)->select(index);
1037
0
}
1038
1039
/**
1040
 * poppler_form_field_choice_unselect_all:
1041
 * @field: a #PopplerFormField
1042
 *
1043
 * Unselects all the items on @field
1044
 **/
1045
void poppler_form_field_choice_unselect_all(PopplerFormField *field)
1046
0
{
1047
0
    g_return_if_fail(field->widget->getType() == formChoice);
1048
1049
0
    static_cast<FormWidgetChoice *>(field->widget)->deselectAll();
1050
0
}
1051
1052
/**
1053
 * poppler_form_field_choice_toggle_item:
1054
 * @field: a #PopplerFormField
1055
 * @index: the index of the item
1056
 *
1057
 * Changes the state of the item at the given index
1058
 **/
1059
void poppler_form_field_choice_toggle_item(PopplerFormField *field, gint index)
1060
0
{
1061
0
    g_return_if_fail(field->widget->getType() == formChoice);
1062
0
    g_return_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field));
1063
1064
0
    static_cast<FormWidgetChoice *>(field->widget)->toggle(index);
1065
0
}
1066
1067
/**
1068
 * poppler_form_field_choice_set_text:
1069
 * @field: a #PopplerFormField
1070
 * @text: the new text
1071
 *
1072
 * Sets the text in @field to the given value, replacing the current contents
1073
 **/
1074
void poppler_form_field_choice_set_text(PopplerFormField *field, const gchar *text)
1075
0
{
1076
0
    gchar *tmp;
1077
0
    gsize length = 0;
1078
1079
0
    g_return_if_fail(field->widget->getType() == formChoice);
1080
1081
0
    tmp = text ? g_convert(text, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr;
1082
0
    std::unique_ptr<GooString> goo_tmp = std::make_unique<GooString>(tmp, length);
1083
0
    g_free(tmp);
1084
0
    static_cast<FormWidgetChoice *>(field->widget)->setEditChoice(std::move(goo_tmp));
1085
0
}
1086
1087
/**
1088
 * poppler_form_field_choice_get_text:
1089
 * @field: a #PopplerFormField
1090
 *
1091
 * Retrieves the contents of @field.
1092
 *
1093
 * Return value: a new allocated string. It must be freed with g_free() when done.
1094
 **/
1095
gchar *poppler_form_field_choice_get_text(PopplerFormField *field)
1096
0
{
1097
0
    const GooString *tmp;
1098
1099
0
    g_return_val_if_fail(field->widget->getType() == formChoice, NULL);
1100
1101
0
    tmp = static_cast<FormWidgetChoice *>(field->widget)->getEditChoice();
1102
0
    return tmp ? _poppler_goo_string_to_utf8(tmp->toStr()) : nullptr;
1103
0
}
1104
1105
/**
1106
 * PopplerSigningData:
1107
 *
1108
 * Since 24.10 this type supports g_autoptr
1109
 */
1110
struct _PopplerSigningData
1111
{
1112
    char *destination_filename;
1113
    PopplerCertificateInfo *certificate_info;
1114
    int page;
1115
1116
    char *signature_text;
1117
    char *signature_text_left;
1118
    PopplerRectangle signature_rect;
1119
1120
    PopplerColor font_color;
1121
    gdouble font_size;
1122
    gdouble left_font_size;
1123
1124
    PopplerColor border_color;
1125
    gdouble border_width;
1126
1127
    PopplerColor background_color;
1128
1129
    char *field_partial_name;
1130
    char *reason;
1131
    char *location;
1132
    char *image_path;
1133
    char *password;
1134
    char *document_owner_password;
1135
    char *document_user_password;
1136
};
1137
1138
G_DEFINE_BOXED_TYPE(PopplerSigningData, poppler_signing_data, poppler_signing_data_copy, poppler_signing_data_free)
1139
1140
/**
1141
 * poppler_signing_data_new:
1142
 *
1143
 * Creates a new #PopplerSigningData with default content.
1144
 *
1145
 * Return value: a new #PopplerSigningData. It must be freed with poppler_signing_data_free() when done.
1146
 *
1147
 * Since: 23.07.0
1148
 **/
1149
PopplerSigningData *poppler_signing_data_new(void)
1150
0
{
1151
0
    auto *data = static_cast<PopplerSigningData *>(g_malloc0(sizeof(PopplerSigningData)));
1152
1153
0
    data->password = g_strdup("");
1154
0
    data->page = 0;
1155
1156
0
    data->font_size = 10.0;
1157
0
    data->left_font_size = 20.0;
1158
0
    data->border_width = 1.5;
1159
1160
    /* Grey background */
1161
0
    auto background_color = PopplerColor();
1162
0
    background_color.red = 0xEF00;
1163
0
    background_color.green = 0xEF00;
1164
0
    background_color.blue = 0xEF00;
1165
0
    poppler_signing_data_set_background_color(data, &background_color);
1166
1167
    /* Red border color */
1168
0
    auto border_color = PopplerColor();
1169
0
    border_color.red = 0xFFFF;
1170
0
    border_color.green = 0x00;
1171
0
    border_color.blue = 0x00;
1172
0
    poppler_signing_data_set_border_color(data, &border_color);
1173
1174
    /* Red font color */
1175
0
    auto font_color = PopplerColor();
1176
0
    font_color.red = 0xFFFF;
1177
0
    font_color.green = 0x00;
1178
0
    border_color.blue = 0x00;
1179
0
    poppler_signing_data_set_font_color(data, &font_color);
1180
1181
0
    return data;
1182
0
}
1183
1184
/**
1185
 * poppler_signing_data_copy:
1186
 * @signing_data: a #PopplerSigningData structure containing signing data
1187
 *
1188
 * Copies @signing_data, creating an identical #PopplerSigningData.
1189
 *
1190
 * Return value: (transfer full): a new #PopplerSigningData structure identical to @signing_data
1191
 *
1192
 * Since: 23.07.0
1193
 **/
1194
PopplerSigningData *poppler_signing_data_copy(const PopplerSigningData *signing_data)
1195
0
{
1196
0
    PopplerSigningData *data;
1197
1198
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1199
1200
0
    data = static_cast<PopplerSigningData *>(g_malloc0(sizeof(PopplerSigningData)));
1201
0
    data->destination_filename = g_strdup(signing_data->destination_filename);
1202
0
    data->certificate_info = poppler_certificate_info_copy(signing_data->certificate_info);
1203
0
    data->page = signing_data->page;
1204
1205
0
    data->signature_text = g_strdup(signing_data->signature_text);
1206
0
    data->signature_text_left = g_strdup(signing_data->signature_text_left);
1207
0
    memcpy(&data->signature_rect, &signing_data->signature_rect, sizeof(PopplerRectangle));
1208
1209
0
    memcpy(&data->font_color, &signing_data->font_color, sizeof(PopplerColor));
1210
0
    data->font_size = signing_data->font_size;
1211
0
    data->left_font_size = signing_data->left_font_size;
1212
1213
0
    memcpy(&data->border_color, &signing_data->border_color, sizeof(PopplerColor));
1214
0
    data->border_width = signing_data->border_width;
1215
1216
0
    memcpy(&data->background_color, &signing_data->background_color, sizeof(PopplerColor));
1217
1218
0
    data->field_partial_name = g_strdup(signing_data->field_partial_name);
1219
0
    data->reason = g_strdup(signing_data->reason);
1220
0
    data->location = g_strdup(signing_data->location);
1221
0
    data->image_path = g_strdup(signing_data->image_path);
1222
0
    data->password = g_strdup(signing_data->password);
1223
0
    data->document_owner_password = g_strdup(signing_data->document_owner_password);
1224
0
    data->document_user_password = g_strdup(signing_data->document_user_password);
1225
1226
0
    return data;
1227
0
}
1228
1229
/**
1230
 * poppler_signing_data_free:
1231
 * @signing_data: (nullable): a #PopplerSigningData structure containing signing data
1232
 *
1233
 * Frees @signing_data
1234
 *
1235
 * Since: 23.07.0
1236
 **/
1237
void poppler_signing_data_free(PopplerSigningData *signing_data)
1238
0
{
1239
0
    if (!signing_data) {
1240
0
        return;
1241
0
    }
1242
1243
0
    g_clear_pointer(&signing_data->destination_filename, g_free);
1244
0
    g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free);
1245
0
    g_clear_pointer(&signing_data->signature_text, g_free);
1246
0
    g_clear_pointer(&signing_data->signature_text_left, g_free);
1247
0
    g_clear_pointer(&signing_data->field_partial_name, g_free);
1248
0
    g_clear_pointer(&signing_data->reason, g_free);
1249
0
    g_clear_pointer(&signing_data->location, g_free);
1250
0
    g_clear_pointer(&signing_data->image_path, g_free);
1251
1252
0
    if (signing_data->password) {
1253
#ifdef HAVE_EXPLICIT_BZERO
1254
        explicit_bzero(signing_data->password, strlen(signing_data->password));
1255
#else
1256
0
        memset(signing_data->password, 0, strlen(signing_data->password));
1257
0
#endif
1258
0
        g_clear_pointer(&signing_data->password, g_free);
1259
0
    }
1260
1261
0
    if (signing_data->document_owner_password) {
1262
#ifdef HAVE_EXPLICIT_BZERO
1263
        explicit_bzero(signing_data->document_owner_password, strlen(signing_data->document_owner_password));
1264
#else
1265
0
        memset(signing_data->document_owner_password, 0, strlen(signing_data->document_owner_password));
1266
0
#endif
1267
0
        g_clear_pointer(&signing_data->document_owner_password, g_free);
1268
0
    }
1269
1270
0
    if (signing_data->document_user_password) {
1271
#ifdef HAVE_EXPLICIT_BZERO
1272
        explicit_bzero(signing_data->document_user_password, strlen(signing_data->document_user_password));
1273
#else
1274
0
        memset(signing_data->document_user_password, 0, strlen(signing_data->document_user_password));
1275
0
#endif
1276
0
        g_clear_pointer(&signing_data->document_user_password, g_free);
1277
0
    }
1278
1279
0
    g_free(signing_data);
1280
0
}
1281
1282
/**
1283
 * poppler_signing_data_set_destination_filename:
1284
 * @signing_data: a #PopplerSigningData structure containing signing data
1285
 * @filename: destination filename
1286
 *
1287
 * Set destination file name.
1288
 *
1289
 * Since: 23.07.0
1290
 **/
1291
void poppler_signing_data_set_destination_filename(PopplerSigningData *signing_data, const gchar *filename)
1292
0
{
1293
0
    g_return_if_fail(signing_data != nullptr);
1294
0
    g_return_if_fail(filename != nullptr);
1295
1296
0
    if (signing_data->destination_filename == filename) {
1297
0
        return;
1298
0
    }
1299
1300
0
    g_clear_pointer(&signing_data->destination_filename, g_free);
1301
0
    signing_data->destination_filename = g_strdup(filename);
1302
0
}
1303
1304
/**
1305
 * poppler_signing_data_get_destination_filename:
1306
 * @signing_data: a #PopplerSigningData structure containing signing data
1307
 *
1308
 * Get destination file name.
1309
 *
1310
 * Return value: destination filename
1311
 *
1312
 * Since: 23.07.0
1313
 **/
1314
const gchar *poppler_signing_data_get_destination_filename(const PopplerSigningData *signing_data)
1315
0
{
1316
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1317
1318
0
    return signing_data->destination_filename;
1319
0
}
1320
1321
/**
1322
 * poppler_signing_data_set_certificate_info:
1323
 * @signing_data: a #PopplerSigningData structure containing signing data
1324
 * @certificate_info: a #PopplerCertificateInfo
1325
 *
1326
 * Set certification information.
1327
 *
1328
 * Since: 23.07.0
1329
 **/
1330
void poppler_signing_data_set_certificate_info(PopplerSigningData *signing_data, const PopplerCertificateInfo *certificate_info)
1331
0
{
1332
0
    g_return_if_fail(signing_data != nullptr);
1333
0
    g_return_if_fail(certificate_info != nullptr);
1334
1335
0
    if (signing_data->certificate_info == certificate_info) {
1336
0
        return;
1337
0
    }
1338
1339
0
    g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free);
1340
0
    signing_data->certificate_info = poppler_certificate_info_copy(certificate_info);
1341
0
}
1342
1343
/**
1344
 * poppler_signing_data_get_certificate_info:
1345
 * @signing_data: a #PopplerSigningData structure containing signing data
1346
 *
1347
 * Get certification information.
1348
 *
1349
 * Return value: a #PopplerCertificateInfo
1350
 *
1351
 * Since: 23.07.0
1352
 **/
1353
const PopplerCertificateInfo *poppler_signing_data_get_certificate_info(const PopplerSigningData *signing_data)
1354
0
{
1355
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1356
0
    return signing_data->certificate_info;
1357
0
}
1358
1359
/**
1360
 * poppler_signing_data_set_page:
1361
 * @signing_data: a #PopplerSigningData structure containing signing data
1362
 * @page: a page number
1363
 *
1364
 * Set page (>=0).
1365
 *
1366
 * Since: 23.07.0
1367
 **/
1368
void poppler_signing_data_set_page(PopplerSigningData *signing_data, int page)
1369
0
{
1370
0
    g_return_if_fail(signing_data != nullptr);
1371
1372
0
    if (page < 0) {
1373
0
        return;
1374
0
    }
1375
1376
0
    signing_data->page = page;
1377
0
}
1378
1379
/**
1380
 * poppler_signing_data_get_page:
1381
 * @signing_data: a #PopplerSigningData structure containing signing data
1382
 *
1383
 * Get page.
1384
 *
1385
 * Return value: page number
1386
 *
1387
 * Since: 23.07.0
1388
 **/
1389
int poppler_signing_data_get_page(const PopplerSigningData *signing_data)
1390
0
{
1391
0
    g_return_val_if_fail(signing_data != nullptr, 0);
1392
0
    return signing_data->page;
1393
0
}
1394
1395
/**
1396
 * poppler_signing_data_set_signature_text:
1397
 * @signing_data: a #PopplerSigningData structure containing signing data
1398
 * @signature_text: text to show as main signature
1399
 *
1400
 * Set signature text.
1401
 *
1402
 * Since: 23.07.0
1403
 **/
1404
void poppler_signing_data_set_signature_text(PopplerSigningData *signing_data, const gchar *signature_text)
1405
0
{
1406
0
    g_return_if_fail(signing_data != nullptr);
1407
0
    g_return_if_fail(signature_text != nullptr);
1408
1409
0
    if (signing_data->signature_text == signature_text) {
1410
0
        return;
1411
0
    }
1412
1413
0
    g_clear_pointer(&signing_data->signature_text, g_free);
1414
0
    signing_data->signature_text = g_strdup(signature_text);
1415
0
}
1416
1417
/**
1418
 * poppler_signing_data_get_signature_text:
1419
 * @signing_data: a #PopplerSigningData structure containing signing data
1420
 *
1421
 * Get signature text.
1422
 *
1423
 * Return value: signature text
1424
 *
1425
 * Since: 23.07.0
1426
 **/
1427
const gchar *poppler_signing_data_get_signature_text(const PopplerSigningData *signing_data)
1428
0
{
1429
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1430
0
    return signing_data->signature_text;
1431
0
}
1432
1433
/**
1434
 * poppler_signing_data_set_signature_text_left:
1435
 * @signing_data: a #PopplerSigningData structure containing signing data
1436
 * @signature_text_left: text to show as small left signature
1437
 *
1438
 * Set small signature text on the left hand.
1439
 *
1440
 * Since: 23.07.0
1441
 **/
1442
void poppler_signing_data_set_signature_text_left(PopplerSigningData *signing_data, const gchar *signature_text_left)
1443
0
{
1444
0
    g_return_if_fail(signing_data != nullptr);
1445
0
    g_return_if_fail(signature_text_left != nullptr);
1446
1447
0
    if (signing_data->signature_text_left == signature_text_left) {
1448
0
        return;
1449
0
    }
1450
1451
0
    g_clear_pointer(&signing_data->signature_text_left, g_free);
1452
0
    signing_data->signature_text_left = g_strdup(signature_text_left);
1453
0
}
1454
1455
/**
1456
 * poppler_signing_data_get_signature_text_left:
1457
 * @signing_data: a #PopplerSigningData structure containing signing data
1458
 *
1459
 * Get signature text left.
1460
 *
1461
 * Return value: signature text left
1462
 *
1463
 * Since: 23.07.0
1464
 **/
1465
const gchar *poppler_signing_data_get_signature_text_left(const PopplerSigningData *signing_data)
1466
0
{
1467
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1468
0
    return signing_data->signature_text_left;
1469
0
}
1470
1471
/**
1472
 * poppler_signing_data_set_signature_rectangle:
1473
 * @signing_data: a #PopplerSigningData structure containing signing data
1474
 * @signature_rect: a #PopplerRectangle where signature should be shown
1475
 *
1476
 * Set signature rectangle.
1477
 *
1478
 * Since: 23.07.0
1479
 **/
1480
void poppler_signing_data_set_signature_rectangle(PopplerSigningData *signing_data, const PopplerRectangle *signature_rect)
1481
0
{
1482
0
    g_return_if_fail(signing_data != nullptr);
1483
0
    g_return_if_fail(signature_rect != nullptr);
1484
1485
0
    memcpy(&signing_data->signature_rect, signature_rect, sizeof(PopplerRectangle));
1486
0
}
1487
1488
/**
1489
 * poppler_signing_data_get_signature_rectangle:
1490
 * @signing_data: a #PopplerSigningData structure containing signing data
1491
 *
1492
 * Get signature rectangle.
1493
 *
1494
 * Return value: a #PopplerRectangle
1495
 *
1496
 * Since: 23.07.0
1497
 **/
1498
const PopplerRectangle *poppler_signing_data_get_signature_rectangle(const PopplerSigningData *signing_data)
1499
0
{
1500
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1501
0
    return &signing_data->signature_rect;
1502
0
}
1503
1504
/**
1505
 * poppler_signing_data_set_font_color:
1506
 * @signing_data: a #PopplerSigningData structure containing signing data
1507
 * @font_color: a #PopplerColor to be used as signature font color
1508
 *
1509
 * Set signature font color.
1510
 *
1511
 * Since: 23.07.0
1512
 **/
1513
void poppler_signing_data_set_font_color(PopplerSigningData *signing_data, const PopplerColor *font_color)
1514
0
{
1515
0
    g_return_if_fail(signing_data != nullptr);
1516
0
    g_return_if_fail(font_color != nullptr);
1517
1518
0
    memcpy(&signing_data->font_color, font_color, sizeof(PopplerColor));
1519
0
}
1520
1521
/**
1522
 * poppler_signing_data_get_font_color:
1523
 * @signing_data: a #PopplerSigningData structure containing signing data
1524
 *
1525
 * Get signature font color.
1526
 *
1527
 * Return value: a #PopplerColor
1528
 *
1529
 * Since: 23.07.0
1530
 **/
1531
const PopplerColor *poppler_signing_data_get_font_color(const PopplerSigningData *signing_data)
1532
0
{
1533
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1534
0
    return &signing_data->font_color;
1535
0
}
1536
1537
/**
1538
 * poppler_signing_data_set_font_size:
1539
 * @signing_data: a #PopplerSigningData structure containing signing data
1540
 * @font_size: signature font size
1541
 *
1542
 * Set signature font size (>0).
1543
 *
1544
 * Since: 23.07.0
1545
 **/
1546
void poppler_signing_data_set_font_size(PopplerSigningData *signing_data, gdouble font_size)
1547
0
{
1548
0
    g_return_if_fail(signing_data != nullptr);
1549
1550
0
    if (font_size <= 0) {
1551
0
        return;
1552
0
    }
1553
1554
0
    signing_data->font_size = font_size;
1555
0
}
1556
1557
/**
1558
 * poppler_signing_data_get_font_size:
1559
 * @signing_data: a #PopplerSigningData structure containing signing data
1560
 *
1561
 * Get signature font size.
1562
 *
1563
 * Return value: font size
1564
 *
1565
 * Since: 23.07.0
1566
 **/
1567
gdouble poppler_signing_data_get_font_size(const PopplerSigningData *signing_data)
1568
0
{
1569
0
    g_return_val_if_fail(signing_data != nullptr, 20.0F);
1570
0
    return signing_data->font_size;
1571
0
}
1572
1573
/**
1574
 * poppler_signing_data_set_left_font_size:
1575
 * @signing_data: a #PopplerSigningData structure containing signing data
1576
 * @font_size: signature font size
1577
 *
1578
 * Set signature left font size (> 0).
1579
 *
1580
 * Since: 23.07.0
1581
 **/
1582
void poppler_signing_data_set_left_font_size(PopplerSigningData *signing_data, gdouble left_font_size)
1583
0
{
1584
0
    g_return_if_fail(signing_data != nullptr);
1585
1586
0
    if (left_font_size <= 0) {
1587
0
        return;
1588
0
    }
1589
1590
0
    signing_data->left_font_size = left_font_size;
1591
0
}
1592
1593
/**
1594
 * poppler_signing_data_get_left_font_size:
1595
 * @signing_data: a #PopplerSigningData structure containing signing data
1596
 *
1597
 * Get signature left font size.
1598
 *
1599
 * Return value: left font size
1600
 *
1601
 * Since: 23.07.0
1602
 **/
1603
gdouble poppler_signing_data_get_left_font_size(const PopplerSigningData *signing_data)
1604
0
{
1605
0
    g_return_val_if_fail(signing_data != nullptr, 12.0);
1606
0
    return signing_data->left_font_size;
1607
0
}
1608
1609
/**
1610
 * poppler_signing_data_set_border_color:
1611
 * @signing_data: a #PopplerSigningData structure containing signing data
1612
 * @border_color: a #PopplerColor to be used for signature border
1613
 *
1614
 * Set signature border color.
1615
 *
1616
 * Since: 23.07.0
1617
 **/
1618
void poppler_signing_data_set_border_color(PopplerSigningData *signing_data, const PopplerColor *border_color)
1619
0
{
1620
0
    g_return_if_fail(signing_data != nullptr);
1621
0
    g_return_if_fail(border_color != nullptr);
1622
1623
0
    memcpy(&signing_data->border_color, border_color, sizeof(PopplerColor));
1624
0
}
1625
1626
/**
1627
 * poppler_signing_data_get_border_color:
1628
 * @signing_data: a #PopplerSigningData structure containing signing data
1629
 *
1630
 * Get signature border color.
1631
 *
1632
 * Return value: a #PopplerColor
1633
 *
1634
 * Since: 23.07.0
1635
 **/
1636
const PopplerColor *poppler_signing_data_get_border_color(const PopplerSigningData *signing_data)
1637
0
{
1638
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1639
0
    return &signing_data->border_color;
1640
0
}
1641
1642
/**
1643
 * poppler_signing_data_set_border_width:
1644
 * @signing_data: a #PopplerSigningData structure containing signing data
1645
 * @border_width: border width
1646
 *
1647
 * Set signature border width.
1648
 *
1649
 * Since: 23.07.0
1650
 **/
1651
void poppler_signing_data_set_border_width(PopplerSigningData *signing_data, gdouble border_width)
1652
0
{
1653
0
    g_return_if_fail(signing_data != nullptr);
1654
1655
0
    if (border_width < 0) {
1656
0
        return;
1657
0
    }
1658
1659
0
    signing_data->border_width = border_width;
1660
0
}
1661
1662
/**
1663
 * poppler_signing_data_get_border_width:
1664
 * @signing_data: a #PopplerSigningData structure containing signing data
1665
 *
1666
 * Get signature border width.
1667
 *
1668
 * Return value: border width
1669
 *
1670
 * Since: 23.07.0
1671
 **/
1672
gdouble poppler_signing_data_get_border_width(const PopplerSigningData *signing_data)
1673
0
{
1674
0
    g_return_val_if_fail(signing_data != nullptr, 12);
1675
0
    return signing_data->border_width;
1676
0
}
1677
1678
/**
1679
 * poppler_signing_data_set_background_color:
1680
 * @signing_data: a #PopplerSigningData structure containing signing data
1681
 * @background_color: a #PopplerColor to be used for signature background
1682
 *
1683
 * Set signature background color.
1684
 *
1685
 * Since: 23.07.0
1686
 **/
1687
void poppler_signing_data_set_background_color(PopplerSigningData *signing_data, const PopplerColor *background_color)
1688
0
{
1689
0
    g_return_if_fail(signing_data != nullptr);
1690
0
    g_return_if_fail(background_color != nullptr);
1691
1692
0
    memcpy(&signing_data->background_color, background_color, sizeof(PopplerColor));
1693
0
}
1694
1695
/**
1696
 * poppler_signing_data_get_background_color:
1697
 * @signing_data: a #PopplerSigningData structure containing signing data
1698
 *
1699
 * Get signature background color.
1700
 *
1701
 * Return value: a #PopplerColor
1702
 *
1703
 * Since: 23.07.0
1704
 **/
1705
const PopplerColor *poppler_signing_data_get_background_color(const PopplerSigningData *signing_data)
1706
0
{
1707
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1708
0
    return &signing_data->background_color;
1709
0
}
1710
1711
/**
1712
 * poppler_signing_data_set_field_partial_name:
1713
 * @signing_data: a #PopplerSigningData structure containing signing data
1714
 * @field_partial_name: a field partial name
1715
 *
1716
 * Set field partial name (existing field id or a new one) where signature is placed.
1717
 *
1718
 * Since: 23.07.0
1719
 **/
1720
void poppler_signing_data_set_field_partial_name(PopplerSigningData *signing_data, const gchar *field_partial_name)
1721
0
{
1722
0
    g_return_if_fail(signing_data != nullptr);
1723
0
    g_return_if_fail(field_partial_name != nullptr);
1724
1725
0
    g_clear_pointer(&signing_data->field_partial_name, g_free);
1726
0
    signing_data->field_partial_name = g_strdup(field_partial_name);
1727
0
}
1728
1729
/**
1730
 * poppler_signing_data_get_field_partial_name:
1731
 * @signing_data: a #PopplerSigningData structure containing signing data
1732
 *
1733
 * Get field partial name.
1734
 *
1735
 * Return value: field partial name
1736
 *
1737
 * Since: 23.07.0
1738
 **/
1739
const gchar *poppler_signing_data_get_field_partial_name(const PopplerSigningData *signing_data)
1740
0
{
1741
0
    g_return_val_if_fail(signing_data != nullptr, "");
1742
0
    return signing_data->field_partial_name;
1743
0
}
1744
1745
/**
1746
 * poppler_signing_data_set_reason:
1747
 * @signing_data: a #PopplerSigningData structure containing signing data
1748
 * @reason: a reason
1749
 *
1750
 * Set reason for signature (e.g. I'm approver).
1751
 *
1752
 * Since: 23.07.0
1753
 **/
1754
void poppler_signing_data_set_reason(PopplerSigningData *signing_data, const gchar *reason)
1755
0
{
1756
0
    g_return_if_fail(signing_data != nullptr);
1757
0
    g_return_if_fail(reason != nullptr);
1758
1759
0
    if (signing_data->reason == reason) {
1760
0
        return;
1761
0
    }
1762
1763
0
    g_clear_pointer(&signing_data->reason, g_free);
1764
0
    signing_data->reason = g_strdup(reason);
1765
0
}
1766
1767
/**
1768
 * poppler_signing_data_get_reason:
1769
 * @signing_data: a #PopplerSigningData structure containing signing data
1770
 *
1771
 * Get reason.
1772
 *
1773
 * Return value: reason
1774
 *
1775
 * Since: 23.07.0
1776
 **/
1777
const gchar *poppler_signing_data_get_reason(const PopplerSigningData *signing_data)
1778
0
{
1779
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1780
0
    return signing_data->reason;
1781
0
}
1782
1783
/**
1784
 * poppler_signing_data_set_location:
1785
 * @signing_data: a #PopplerSigningData structure containing signing data
1786
 * @location: a location
1787
 *
1788
 * Set signature location (e.g. "At my desk").
1789
 *
1790
 * Since: 23.07.0
1791
 **/
1792
void poppler_signing_data_set_location(PopplerSigningData *signing_data, const gchar *location)
1793
0
{
1794
0
    g_return_if_fail(signing_data != nullptr);
1795
0
    g_return_if_fail(location != nullptr);
1796
1797
0
    if (signing_data->location == location) {
1798
0
        return;
1799
0
    }
1800
1801
0
    g_clear_pointer(&signing_data->location, g_free);
1802
0
    signing_data->location = g_strdup(location);
1803
0
}
1804
1805
/**
1806
 * poppler_signing_data_get_location:
1807
 * @signing_data: a #PopplerSigningData structure containing signing data
1808
 *
1809
 * Get location.
1810
 *
1811
 * Return value: location
1812
 *
1813
 * Since: 23.07.0
1814
 **/
1815
const gchar *poppler_signing_data_get_location(const PopplerSigningData *signing_data)
1816
0
{
1817
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1818
0
    return signing_data->location;
1819
0
}
1820
1821
/**
1822
 * poppler_signing_data_set_image_path:
1823
 * @signing_data: a #PopplerSigningData structure containing signing data
1824
 * @image_path: signature image path
1825
 *
1826
 * Set signature background (watermark) image path.
1827
 *
1828
 * Since: 23.07.0
1829
 **/
1830
void poppler_signing_data_set_image_path(PopplerSigningData *signing_data, const gchar *image_path)
1831
0
{
1832
0
    g_return_if_fail(signing_data != nullptr);
1833
0
    g_return_if_fail(image_path != nullptr);
1834
1835
0
    if (signing_data->image_path == image_path) {
1836
0
        return;
1837
0
    }
1838
1839
0
    g_clear_pointer(&signing_data->image_path, g_free);
1840
0
    signing_data->image_path = g_strdup(image_path);
1841
0
}
1842
1843
/**
1844
 * poppler_signing_data_get_image_path:
1845
 * @signing_data: a #PopplerSigningData structure containing signing data
1846
 *
1847
 * Get image path.
1848
 *
1849
 * Return value: image path
1850
 *
1851
 * Since: 23.07.0
1852
 **/
1853
const gchar *poppler_signing_data_get_image_path(const PopplerSigningData *signing_data)
1854
0
{
1855
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1856
0
    return signing_data->image_path;
1857
0
}
1858
1859
/**
1860
 * poppler_signing_data_set_password:
1861
 * @signing_data: a #PopplerSigningData structure containing signing data
1862
 * @password: a password
1863
 *
1864
 * Set password for the signing key.
1865
 *
1866
 * Since: 23.07.0
1867
 **/
1868
void poppler_signing_data_set_password(PopplerSigningData *signing_data, const gchar *password)
1869
0
{
1870
0
    g_return_if_fail(signing_data != nullptr);
1871
0
    g_return_if_fail(password != nullptr);
1872
1873
0
    if (signing_data->password == password) {
1874
0
        return;
1875
0
    }
1876
1877
0
    g_clear_pointer(&signing_data->password, g_free);
1878
0
    signing_data->password = g_strdup(password);
1879
0
}
1880
1881
/**
1882
 * poppler_signing_data_get_password:
1883
 * @signing_data: a #PopplerSigningData structure containing signing data
1884
 *
1885
 * Get signing key password.
1886
 *
1887
 * Return value: password
1888
 *
1889
 * Since: 23.07.0
1890
 **/
1891
const gchar *poppler_signing_data_get_password(const PopplerSigningData *signing_data)
1892
0
{
1893
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1894
0
    return signing_data->password;
1895
0
}
1896
1897
/**
1898
 * poppler_signing_data_set_document_owner_password:
1899
 * @signing_data: a #PopplerSigningData structure containing signing data
1900
 * @document_owner_password: document owner password
1901
 *
1902
 * Set document owner password (for encrypted files).
1903
 *
1904
 * Since: 23.07.0
1905
 **/
1906
void poppler_signing_data_set_document_owner_password(PopplerSigningData *signing_data, const gchar *document_owner_password)
1907
0
{
1908
0
    g_return_if_fail(signing_data != nullptr);
1909
0
    g_return_if_fail(document_owner_password != nullptr);
1910
1911
0
    if (signing_data->document_owner_password == document_owner_password) {
1912
0
        return;
1913
0
    }
1914
1915
0
    g_clear_pointer(&signing_data->document_owner_password, g_free);
1916
0
    signing_data->document_owner_password = g_strdup(document_owner_password);
1917
0
}
1918
1919
/**
1920
 * poppler_signing_data_get_document_owner_password:
1921
 * @signing_data: a #PopplerSigningData structure containing signing data
1922
 *
1923
 * Get document owner password.
1924
 *
1925
 * Return value: document owner password (for encrypted files)
1926
 *
1927
 * Since: 23.07.0
1928
 **/
1929
const gchar *poppler_signing_data_get_document_owner_password(const PopplerSigningData *signing_data)
1930
0
{
1931
0
    g_return_val_if_fail(signing_data != nullptr, nullptr);
1932
0
    return signing_data->document_owner_password;
1933
0
}
1934
1935
/**
1936
 * poppler_signing_data_set_document_user_password:
1937
 * @signing_data: a #PopplerSigningData structure containing signing data
1938
 * @document_user_password: document user password
1939
 *
1940
 * Set document user password (for encrypted files).
1941
 *
1942
 * Since: 23.07.0
1943
 **/
1944
void poppler_signing_data_set_document_user_password(PopplerSigningData *signing_data, const gchar *document_user_password)
1945
0
{
1946
0
    g_return_if_fail(signing_data != nullptr);
1947
0
    g_return_if_fail(document_user_password != nullptr);
1948
1949
0
    if (signing_data->document_user_password == document_user_password) {
1950
0
        return;
1951
0
    }
1952
1953
0
    g_clear_pointer(&signing_data->document_user_password, g_free);
1954
0
    signing_data->document_user_password = g_strdup(document_user_password);
1955
0
}
1956
1957
/**
1958
 * poppler_signing_data_get_document_user_password:
1959
 * @signing_data: a #PopplerSigningData structure containing signing data
1960
 *
1961
 * Get document user password.
1962
 *
1963
 * Return value: document user password (for encrypted files)
1964
 *
1965
 * Since: 23.07.0
1966
 **/
1967
const gchar *poppler_signing_data_get_document_user_password(const PopplerSigningData *signing_data)
1968
0
{
1969
0
    g_return_val_if_fail(signing_data != nullptr, "");
1970
0
    return signing_data->document_user_password;
1971
0
}
1972
1973
/* Certificate Information */
1974
1975
/**
1976
 * poppler_certificate_info_new:
1977
 *
1978
 * Creates a new #PopplerCertificateInfo
1979
 *
1980
 * Return value: a new #PopplerCertificateInfo. It must be freed with poppler_certificate_info_free() when done.
1981
 *
1982
 * Since: 23.07.0
1983
 **/
1984
PopplerCertificateInfo *poppler_certificate_info_new(void)
1985
0
{
1986
0
    return static_cast<PopplerCertificateInfo *>(g_malloc0(sizeof(PopplerCertificateInfo)));
1987
0
}
1988
1989
/**
1990
 * poppler_certificate_info_get_id:
1991
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
1992
 *
1993
 * Get certificate nick name
1994
 *
1995
 * Return value: certificate nick name
1996
 *
1997
 * Since: 23.07.0
1998
 **/
1999
const char *poppler_certificate_info_get_id(const PopplerCertificateInfo *certificate_info)
2000
0
{
2001
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2002
0
    return certificate_info->id;
2003
0
}
2004
2005
/**
2006
 * poppler_certificate_info_get_subject_common_name:
2007
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2008
 *
2009
 * Get certificate subject common name
2010
 *
2011
 * Return value: certificate subject common name
2012
 *
2013
 * Since: 23.07.0
2014
 **/
2015
const char *poppler_certificate_info_get_subject_common_name(const PopplerCertificateInfo *certificate_info)
2016
0
{
2017
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2018
0
    return certificate_info->subject_common_name;
2019
0
}
2020
2021
/**
2022
 * poppler_certificate_info_get_subject_organization:
2023
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2024
 *
2025
 * Get certificate subject organization
2026
 *
2027
 * Return value: certificate subject organization
2028
 *
2029
 * Since: 23.08.0
2030
 **/
2031
const char *poppler_certificate_info_get_subject_organization(const PopplerCertificateInfo *certificate_info)
2032
0
{
2033
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2034
0
    return certificate_info->subject_organization;
2035
0
}
2036
2037
/**
2038
 * poppler_certificate_info_get_subject_email:
2039
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2040
 *
2041
 * Get certificate subject email
2042
 *
2043
 * Return value: certificate subject email
2044
 *
2045
 * Since: 23.08.0
2046
 **/
2047
const char *poppler_certificate_info_get_subject_email(const PopplerCertificateInfo *certificate_info)
2048
0
{
2049
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2050
0
    return certificate_info->subject_email;
2051
0
}
2052
2053
/**
2054
 * poppler_certificate_info_get_issuer_common_name:
2055
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2056
 *
2057
 * Get certificate issuer common name
2058
 *
2059
 * Return value: certificate issuer common name
2060
 *
2061
 * Since: 23.08.0
2062
 **/
2063
const char *poppler_certificate_info_get_issuer_common_name(const PopplerCertificateInfo *certificate_info)
2064
0
{
2065
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2066
0
    return certificate_info->issuer_common_name;
2067
0
}
2068
2069
/**
2070
 * poppler_certificate_info_get_issuer_organization:
2071
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2072
 *
2073
 * Get certificate issuer organization
2074
 *
2075
 * Return value: certificate issuer organization
2076
 *
2077
 * Since: 23.08.0
2078
 **/
2079
const char *poppler_certificate_info_get_issuer_organization(const PopplerCertificateInfo *certificate_info)
2080
0
{
2081
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2082
0
    return certificate_info->issuer_organization;
2083
0
}
2084
2085
/**
2086
 * poppler_certificate_info_get_issuer_email:
2087
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2088
 *
2089
 * Get certificate issuer email
2090
 *
2091
 * Return value: certificate issuer email
2092
 *
2093
 * Since: 23.08.0
2094
 **/
2095
const char *poppler_certificate_info_get_issuer_email(const PopplerCertificateInfo *certificate_info)
2096
0
{
2097
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2098
0
    return certificate_info->issuer_email;
2099
0
}
2100
2101
/**
2102
 * poppler_certificate_info_get_issuance_time:
2103
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2104
 *
2105
 * Get certificate issuance time
2106
 *
2107
 * Return value: (transfer none): certificate issuance time
2108
 *
2109
 * Since: 23.08.0
2110
 **/
2111
GDateTime *poppler_certificate_info_get_issuance_time(const PopplerCertificateInfo *certificate_info)
2112
0
{
2113
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2114
0
    return certificate_info->issued;
2115
0
}
2116
2117
/**
2118
 * poppler_certificate_info_get_expiration_time:
2119
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2120
 *
2121
 * Get certificate expiration time
2122
 *
2123
 * Return value: (transfer none): certificate expiration time
2124
 *
2125
 * Since: 23.08.0
2126
 **/
2127
GDateTime *poppler_certificate_info_get_expiration_time(const PopplerCertificateInfo *certificate_info)
2128
0
{
2129
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2130
0
    return certificate_info->expires;
2131
0
}
2132
2133
static PopplerCertificateInfo *create_certificate_info(const X509CertificateInfo *ci)
2134
0
{
2135
0
    PopplerCertificateInfo *certificate_info;
2136
2137
0
    g_return_val_if_fail(ci != nullptr, nullptr);
2138
2139
0
    const X509CertificateInfo::EntityInfo &subject_info = ci->getSubjectInfo();
2140
0
    const X509CertificateInfo::EntityInfo &issuer_info = ci->getIssuerInfo();
2141
0
    const X509CertificateInfo::Validity &validity = ci->getValidity();
2142
2143
0
    certificate_info = poppler_certificate_info_new();
2144
0
    certificate_info->id = g_strdup(ci->getNickName().c_str());
2145
0
    certificate_info->subject_common_name = g_strdup(subject_info.commonName.c_str());
2146
0
    certificate_info->subject_organization = g_strdup(subject_info.organization.c_str());
2147
0
    certificate_info->subject_email = g_strdup(subject_info.email.c_str());
2148
0
    certificate_info->issuer_common_name = g_strdup(issuer_info.commonName.c_str());
2149
0
    certificate_info->issuer_organization = g_strdup(issuer_info.organization.c_str());
2150
0
    certificate_info->issuer_email = g_strdup(issuer_info.email.c_str());
2151
0
    certificate_info->issued = g_date_time_new_from_unix_utc(std::chrono::duration_cast<std::chrono::seconds>(validity.notBefore.time_since_epoch()).count());
2152
0
    certificate_info->expires = g_date_time_new_from_unix_utc(std::chrono::duration_cast<std::chrono::seconds>(validity.notAfter.time_since_epoch()).count());
2153
2154
0
    return certificate_info;
2155
0
}
2156
2157
/**
2158
 * poppler_certificate_info_copy:
2159
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2160
 *
2161
 * Copies @certificate_info, creating an identical #PopplerCertificateInfo.
2162
 *
2163
 * Return value: (transfer full): a new #PopplerCertificateInfo structure identical to @certificate_info
2164
 *
2165
 * Since: 23.07.0
2166
 **/
2167
PopplerCertificateInfo *poppler_certificate_info_copy(const PopplerCertificateInfo *certificate_info)
2168
0
{
2169
0
    PopplerCertificateInfo *dup;
2170
2171
0
    g_return_val_if_fail(certificate_info != nullptr, nullptr);
2172
2173
0
    dup = static_cast<PopplerCertificateInfo *>(g_malloc0(sizeof(PopplerCertificateInfo)));
2174
0
    dup->id = g_strdup(certificate_info->id);
2175
0
    dup->subject_common_name = g_strdup(certificate_info->subject_common_name);
2176
0
    dup->subject_organization = g_strdup(certificate_info->subject_organization);
2177
0
    dup->subject_email = g_strdup(certificate_info->subject_email);
2178
0
    dup->issuer_common_name = g_strdup(certificate_info->issuer_common_name);
2179
0
    dup->issuer_organization = g_strdup(certificate_info->issuer_organization);
2180
0
    dup->issuer_email = g_strdup(certificate_info->issuer_email);
2181
0
    dup->issued = g_date_time_ref(certificate_info->issued);
2182
0
    dup->expires = g_date_time_ref(certificate_info->expires);
2183
2184
0
    return dup;
2185
0
}
2186
2187
/**
2188
 * poppler_certificate_info_free:
2189
 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2190
 *
2191
 * Frees @certificate_info
2192
 *
2193
 * Since: 23.07.0
2194
 **/
2195
void poppler_certificate_info_free(PopplerCertificateInfo *certificate_info)
2196
0
{
2197
0
    if (certificate_info == nullptr) {
2198
0
        return;
2199
0
    }
2200
2201
0
    g_clear_pointer(&certificate_info->id, g_free);
2202
0
    g_clear_pointer(&certificate_info->subject_common_name, g_free);
2203
0
    g_clear_pointer(&certificate_info->subject_organization, g_free);
2204
0
    g_clear_pointer(&certificate_info->subject_email, g_free);
2205
0
    g_clear_pointer(&certificate_info->issuer_common_name, g_free);
2206
0
    g_clear_pointer(&certificate_info->issuer_organization, g_free);
2207
0
    g_clear_pointer(&certificate_info->issuer_email, g_free);
2208
0
    g_clear_pointer(&certificate_info->issued, g_date_time_unref);
2209
0
    g_clear_pointer(&certificate_info->expires, g_date_time_unref);
2210
2211
0
    g_free(certificate_info);
2212
0
}
2213
2214
/**
2215
 * poppler_get_available_signing_certificates:
2216
 *
2217
 * Get all available signing certificate information
2218
 *
2219
 * Returns: (transfer full) (element-type PopplerCertificateInfo): all available signing certificate information
2220
 **/
2221
GList *poppler_get_available_signing_certificates(void)
2222
0
{
2223
0
    GList *list = nullptr;
2224
0
    auto backend = CryptoSign::Factory::createActive();
2225
2226
0
    if (!backend) {
2227
0
        return nullptr;
2228
0
    }
2229
2230
0
    std::vector<std::unique_ptr<X509CertificateInfo>> vCerts = backend->getAvailableSigningCertificates();
2231
0
    for (auto &cert : vCerts) {
2232
0
        PopplerCertificateInfo *certificate_info = create_certificate_info(cert.get());
2233
0
        list = g_list_append(list, certificate_info);
2234
0
    }
2235
0
    return list;
2236
0
}
2237
2238
/**
2239
 * poppler_get_certificate_info_by_id:
2240
 *
2241
 * Get certificate by nick name
2242
 *
2243
 * Returns: (transfer full): a #PopplerCertificateInfo or %NULL if not found
2244
 **/
2245
PopplerCertificateInfo *poppler_get_certificate_info_by_id(const char *id)
2246
0
{
2247
0
    PopplerCertificateInfo *ret = nullptr;
2248
0
    GList *certificate_info = poppler_get_available_signing_certificates();
2249
0
    GList *list;
2250
2251
0
    for (list = certificate_info; list != nullptr; list = list->next) {
2252
0
        auto *info = static_cast<PopplerCertificateInfo *>(list->data);
2253
2254
0
        if (g_strcmp0(info->id, id) == 0) {
2255
0
            ret = poppler_certificate_info_copy(info);
2256
0
            break;
2257
0
        }
2258
0
    }
2259
2260
0
    g_list_free_full(certificate_info, reinterpret_cast<GDestroyNotify>(poppler_certificate_info_free));
2261
2262
0
    return ret;
2263
0
}
2264
2265
/* NSS functions */
2266
2267
/**
2268
 * poppler_set_nss_dir:
2269
 *
2270
 * Set NSS directory
2271
 *
2272
 * Since: 23.07.0
2273
 **/
2274
void poppler_set_nss_dir(const char *path)
2275
0
{
2276
0
#if ENABLE_NSS3
2277
0
    NSSSignatureConfiguration::setNSSDir(GooString(path ? path : ""));
2278
#else
2279
    (void)path;
2280
#endif
2281
0
}
2282
2283
/**
2284
 * poppler_get_nss_dir:
2285
 *
2286
 * Get NSS directory
2287
 *
2288
 * Return value: (transfer full): nss directroy.
2289
 *
2290
 * Since: 23.07.0
2291
 **/
2292
char *poppler_get_nss_dir(void)
2293
0
{
2294
0
#if ENABLE_NSS3
2295
0
    return g_strdup(NSSSignatureConfiguration::getNSSDir().c_str());
2296
#else
2297
    return nullptr;
2298
#endif
2299
0
}
2300
2301
/**
2302
 * poppler_set_nss_password_callback:
2303
 * @func: (scope call): a #PopplerNssPasswordFunc that represents a signature annotation
2304
 *
2305
 * A callback which asks for certificate password
2306
 *
2307
 * Since: 23.07.0
2308
 **/
2309
void poppler_set_nss_password_callback(PopplerNssPasswordFunc func)
2310
0
{
2311
0
#if ENABLE_NSS3
2312
0
    NSSSignatureConfiguration::setNSSPasswordCallback(func);
2313
#else
2314
    g_warning("poppler_set_nss_password_callback called but this poppler is built without NSS support");
2315
    (void)func;
2316
#endif
2317
0
}