Coverage Report

Created: 2023-06-07 06:20

/src/mupdf/source/pdf/pdf-store.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2004-2021 Artifex Software, Inc.
2
//
3
// This file is part of MuPDF.
4
//
5
// MuPDF is free software: you can redistribute it and/or modify it under the
6
// terms of the GNU Affero General Public License as published by the Free
7
// Software Foundation, either version 3 of the License, or (at your option)
8
// any later version.
9
//
10
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
// details.
14
//
15
// You should have received a copy of the GNU Affero General Public License
16
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17
//
18
// Alternative licensing terms are available from the licensor.
19
// For commercial licensing, see <https://www.artifex.com/> or contact
20
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21
// CA 94129, USA, for further information.
22
23
#include "mupdf/fitz.h"
24
#include "mupdf/pdf.h"
25
26
#include <assert.h>
27
28
static int
29
pdf_make_hash_key(fz_context *ctx, fz_store_hash *hash, void *key_)
30
322k
{
31
322k
  pdf_obj *key = (pdf_obj *)key_;
32
33
322k
  if (!pdf_is_indirect(ctx, key))
34
4.37k
    return 0;
35
318k
  hash->u.pi.i = pdf_to_num(ctx, key);
36
318k
  hash->u.pi.ptr = pdf_get_indirect_document(ctx, key);
37
318k
  return 1;
38
322k
}
39
40
static void *
41
pdf_keep_key(fz_context *ctx, void *key)
42
30.4k
{
43
30.4k
  return (void *)pdf_keep_obj(ctx, (pdf_obj *)key);
44
30.4k
}
45
46
static void
47
pdf_drop_key(fz_context *ctx, void *key)
48
30.4k
{
49
30.4k
  pdf_drop_obj(ctx, (pdf_obj *)key);
50
30.4k
}
51
52
static int
53
pdf_cmp_key(fz_context *ctx, void *k0, void *k1)
54
5.37k
{
55
5.37k
  return pdf_objcmp(ctx, (pdf_obj *)k0, (pdf_obj *)k1);
56
5.37k
}
57
58
static void
59
pdf_format_key(fz_context *ctx, char *s, size_t n, void *key_)
60
0
{
61
0
  pdf_obj *key = (pdf_obj *)key_;
62
0
  if (pdf_is_indirect(ctx, key))
63
0
    fz_snprintf(s, n, "(%d 0 R)", pdf_to_num(ctx, key));
64
0
  else
65
0
  {
66
0
    size_t t;
67
0
    char *p = pdf_sprint_obj(ctx, s, n, &t, key, 1, 0);
68
0
    if (p != s) {
69
0
      fz_strlcpy(s, p, n);
70
0
      fz_free(ctx, p);
71
0
    }
72
0
  }
73
0
}
74
75
static const fz_store_type pdf_obj_store_type =
76
{
77
  "pdf_obj",
78
  pdf_make_hash_key,
79
  pdf_keep_key,
80
  pdf_drop_key,
81
  pdf_cmp_key,
82
  pdf_format_key,
83
  NULL
84
};
85
86
void
87
pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, size_t itemsize)
88
30.4k
{
89
30.4k
  void *existing;
90
91
30.4k
  assert(pdf_is_name(ctx, key) || pdf_is_array(ctx, key) || pdf_is_dict(ctx, key) || pdf_is_indirect(ctx, key));
92
30.4k
  existing = fz_store_item(ctx, key, val, itemsize, &pdf_obj_store_type);
93
30.4k
  if (existing)
94
0
    fz_warn(ctx, "unexpectedly replacing entry in PDF store");
95
30.4k
}
96
97
void *
98
pdf_find_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key)
99
261k
{
100
261k
  return fz_find_item(ctx, drop, key, &pdf_obj_store_type);
101
261k
}
102
103
void
104
pdf_remove_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key)
105
0
{
106
0
  fz_remove_item(ctx, drop, key, &pdf_obj_store_type);
107
0
}
108
109
static int
110
pdf_filter_store(fz_context *ctx, void *doc_, void *key)
111
30.4k
{
112
30.4k
  pdf_document *doc = (pdf_document *)doc_;
113
30.4k
  pdf_obj *obj = (pdf_obj *)key;
114
30.4k
  pdf_document *key_doc = pdf_get_bound_document(ctx, obj);
115
116
30.4k
  return (doc == key_doc);
117
30.4k
}
118
119
void
120
pdf_empty_store(fz_context *ctx, pdf_document *doc)
121
14.7k
{
122
14.7k
  fz_filter_store(ctx, pdf_filter_store, doc, &pdf_obj_store_type);
123
14.7k
}
124
125
static int
126
pdf_filter_locals(fz_context *ctx, void *doc_, void *key)
127
188
{
128
188
  pdf_document *doc = (pdf_document *)doc_;
129
188
  pdf_obj *obj = (pdf_obj *)key;
130
188
  pdf_document *key_doc = pdf_get_bound_document(ctx, obj);
131
132
188
  return (doc == key_doc && pdf_is_local_object(ctx, doc, obj));
133
188
}
134
135
void pdf_purge_locals_from_store(fz_context *ctx, pdf_document *doc)
136
14.0k
{
137
14.0k
  fz_filter_store(ctx, pdf_filter_locals, doc, &pdf_obj_store_type);
138
14.0k
}