Coverage Report

Created: 2025-07-23 08:13

/src/poppler/poppler/Object.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// Object.cc
4
//
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
//========================================================================
10
//
11
// Modified under the Poppler project - http://poppler.freedesktop.org
12
//
13
// All changes made under the Poppler project to this file are licensed
14
// under GPL version 2 or later
15
//
16
// Copyright (C) 2008, 2010, 2012, 2017, 2019, 2024 Albert Astals Cid <aacid@kde.org>
17
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
18
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
19
// Copyright (C) 2020 Jakub Alba <jakubalba@gmail.com>
20
//
21
// To see a description of the changes please see the Changelog file that
22
// came with your tarball or type make ChangeLog if you are building from git
23
//
24
//========================================================================
25
26
#include <config.h>
27
28
#include <cstddef>
29
#include "Object.h"
30
#include "Array.h"
31
#include "Dict.h"
32
#include "Error.h"
33
#include "Stream.h"
34
#include "XRef.h"
35
36
//------------------------------------------------------------------------
37
// Object
38
//------------------------------------------------------------------------
39
40
static const char *objTypeNames[numObjTypes] = { "boolean", "integer", "real", "string", "name", "null", "array", "dictionary", "stream", "ref", "cmd", "error", "eof", "none", "integer64", "hexString", "dead" };
41
42
Object Object::copy() const
43
388M
{
44
388M
    CHECK_NOT_DEAD;
45
46
388M
    Object obj;
47
388M
    std::memcpy(reinterpret_cast<void *>(&obj), this, sizeof(Object)); // NOLINT(bugprone-undefined-memory-manipulation)
48
49
388M
    switch (type) {
50
27.5M
    case objString:
51
27.5M
    case objHexString:
52
27.5M
        obj.string = new GooString(string);
53
27.5M
        break;
54
34.6M
    case objName:
55
40.5M
    case objCmd:
56
40.5M
        obj.cString = copyString(cString);
57
40.5M
        break;
58
19.3M
    case objArray:
59
19.3M
        array->incRef();
60
19.3M
        break;
61
8.66M
    case objDict:
62
8.66M
        dict->incRef();
63
8.66M
        break;
64
20.5M
    case objStream:
65
20.5M
        stream->incRef();
66
20.5M
        break;
67
271M
    default:
68
271M
        break;
69
388M
    }
70
71
388M
    return obj;
72
388M
}
73
74
Object Object::deepCopy() const
75
1.16M
{
76
1.16M
    CHECK_NOT_DEAD;
77
78
1.16M
    Object obj;
79
1.16M
    std::memcpy(reinterpret_cast<void *>(&obj), this, sizeof(Object)); // NOLINT(bugprone-undefined-memory-manipulation)
80
81
1.16M
    switch (type) {
82
18.8k
    case objString:
83
18.8k
    case objHexString:
84
18.8k
        obj.string = new GooString(string);
85
18.8k
        break;
86
87.3k
    case objName:
87
141k
    case objCmd:
88
141k
        obj.cString = copyString(cString);
89
141k
        break;
90
21.4k
    case objArray:
91
21.4k
        obj.array = array->deepCopy();
92
21.4k
        break;
93
90.5k
    case objDict:
94
90.5k
        obj.dict = dict->deepCopy();
95
90.5k
        break;
96
4.81k
    case objStream:
97
4.81k
        stream->incRef();
98
4.81k
        break;
99
883k
    default:
100
883k
        break;
101
1.16M
    }
102
103
1.16M
    return obj;
104
1.16M
}
105
106
Object Object::fetch(XRef *xref, int recursion) const
107
314M
{
108
314M
    CHECK_NOT_DEAD;
109
110
314M
    return (type == objRef && xref) ? xref->fetch(ref, recursion) : copy();
111
314M
}
112
113
void Object::free()
114
18.8G
{
115
18.8G
    switch (type) {
116
77.1M
    case objString:
117
77.1M
    case objHexString:
118
119
77.1M
        delete string;
120
77.1M
        break;
121
350M
    case objName:
122
775M
    case objCmd:
123
775M
        gfree(cString);
124
775M
        break;
125
56.8M
    case objArray:
126
56.8M
        if (!array->decRef()) {
127
37.4M
            delete array;
128
37.4M
        }
129
56.8M
        break;
130
33.5M
    case objDict:
131
33.5M
        if (!dict->decRef()) {
132
24.8M
            delete dict;
133
24.8M
        }
134
33.5M
        break;
135
43.3M
    case objStream:
136
43.3M
        if (!stream->decRef()) {
137
22.8M
            delete stream;
138
22.8M
        }
139
43.3M
        break;
140
17.9G
    default:
141
17.9G
        break;
142
18.8G
    }
143
18.8G
    type = objNone;
144
18.8G
}
145
146
const char *Object::getTypeName() const
147
1.19M
{
148
1.19M
    return objTypeNames[type];
149
1.19M
}
150
151
void Object::print(FILE *f) const
152
0
{
153
0
    int i;
154
155
0
    switch (type) {
156
0
    case objBool:
157
0
        fprintf(f, "%s", booln ? "true" : "false");
158
0
        break;
159
0
    case objInt:
160
0
        fprintf(f, "%d", intg);
161
0
        break;
162
0
    case objReal:
163
0
        fprintf(f, "%g", real);
164
0
        break;
165
0
    case objString:
166
0
        fprintf(f, "(");
167
0
        fwrite(string->c_str(), 1, string->getLength(), f);
168
0
        fprintf(f, ")");
169
0
        break;
170
0
    case objHexString:
171
0
        fprintf(f, "<");
172
0
        for (i = 0; i < string->getLength(); i++) {
173
0
            fprintf(f, "%02x", string->getChar(i) & 0xff);
174
0
        }
175
0
        fprintf(f, ">");
176
0
        break;
177
0
    case objName:
178
0
        fprintf(f, "/%s", cString);
179
0
        break;
180
0
    case objNull:
181
0
        fprintf(f, "null");
182
0
        break;
183
0
    case objArray:
184
0
        fprintf(f, "[");
185
0
        for (i = 0; i < arrayGetLength(); ++i) {
186
0
            if (i > 0) {
187
0
                fprintf(f, " ");
188
0
            }
189
0
            const Object &obj = arrayGetNF(i);
190
0
            obj.print(f);
191
0
        }
192
0
        fprintf(f, "]");
193
0
        break;
194
0
    case objDict:
195
0
        fprintf(f, "<<");
196
0
        for (i = 0; i < dictGetLength(); ++i) {
197
0
            fprintf(f, " /%s ", dictGetKey(i));
198
0
            const Object &obj = dictGetValNF(i);
199
0
            obj.print(f);
200
0
        }
201
0
        fprintf(f, " >>");
202
0
        break;
203
0
    case objStream:
204
0
        fprintf(f, "<stream>");
205
0
        break;
206
0
    case objRef:
207
0
        fprintf(f, "%d %d R", ref.num, ref.gen);
208
0
        break;
209
0
    case objCmd:
210
0
        fprintf(f, "%s", cString);
211
0
        break;
212
0
    case objError:
213
0
        fprintf(f, "<error>");
214
0
        break;
215
0
    case objEOF:
216
0
        fprintf(f, "<EOF>");
217
0
        break;
218
0
    case objNone:
219
0
        fprintf(f, "<none>");
220
0
        break;
221
0
    case objDead:
222
0
        fprintf(f, "<dead>");
223
0
        break;
224
0
    case objInt64:
225
0
        fprintf(f, "%lld", int64g);
226
0
        break;
227
0
    }
228
0
}