Coverage Report

Created: 2025-07-12 07:23

/src/poppler/fofi/FoFiBase.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// FoFiBase.cc
4
//
5
// Copyright 1999-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 Ed Avis <eda@waniasset.com>
17
// Copyright (C) 2011 Jim Meyering <jim@meyering.net>
18
// Copyright (C) 2016, 2018, 2020 Albert Astals Cid <aacid@kde.org>
19
// Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
20
// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
21
// Copyright (C) 2022 Oliver Sander <oliver.sander@tu-dresden.de>
22
// Copyright (C) 2025 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
23
//
24
// To see a description of the changes please see the Changelog file that
25
// came with your tarball or type make ChangeLog if you are building from git
26
//
27
//========================================================================
28
29
#include <config.h>
30
31
#include <cstdio>
32
#include <climits>
33
#include "goo/gfile.h"
34
#include "poppler/Error.h"
35
#include "FoFiBase.h"
36
37
//------------------------------------------------------------------------
38
// FoFiBase
39
//------------------------------------------------------------------------
40
41
326k
FoFiBase::FoFiBase(std::vector<unsigned char> &&fileA) : fileOwner(std::move(fileA)), file(fileOwner) { }
42
43
66.4k
FoFiBase::FoFiBase(std::span<unsigned char> fileA) : file(fileA) { }
44
45
393k
FoFiBase::~FoFiBase() = default;
46
47
std::optional<std::vector<unsigned char>> FoFiBase::readFile(const char *fileName)
48
123k
{
49
123k
    FILE *f;
50
51
123k
    if (!(f = openFile(fileName, "rb"))) {
52
0
        error(errIO, -1, "Cannot open '{0:s}'", fileName);
53
0
        return std::nullopt;
54
0
    }
55
123k
    if (fseek(f, 0, SEEK_END) != 0) {
56
0
        error(errIO, -1, "Cannot seek to end of '{0:s}'", fileName);
57
0
        fclose(f);
58
0
        return std::nullopt;
59
0
    }
60
123k
    int n = (int)ftell(f);
61
123k
    if (n < 0) {
62
0
        error(errIO, -1, "Cannot determine length of '{0:s}'", fileName);
63
0
        fclose(f);
64
0
        return std::nullopt;
65
0
    }
66
123k
    if (fseek(f, 0, SEEK_SET) != 0) {
67
0
        error(errIO, -1, "Cannot seek to start of '{0:s}'", fileName);
68
0
        fclose(f);
69
0
        return std::nullopt;
70
0
    }
71
123k
    std::vector<unsigned char> buf;
72
123k
    buf.resize(n);
73
123k
    if ((int)fread(buf.data(), 1, n, f) != n) {
74
0
        fclose(f);
75
0
        return std::nullopt;
76
0
    }
77
123k
    fclose(f);
78
123k
    return buf;
79
123k
}
80
81
int FoFiBase::getS8(int pos, bool *ok) const
82
0
{
83
0
    int x;
84
85
0
    if (pos < 0 || pos >= int(file.size())) {
86
0
        *ok = false;
87
0
        return 0;
88
0
    }
89
0
    x = file[pos];
90
0
    if (x & 0x80) {
91
0
        x |= ~0xff;
92
0
    }
93
0
    return x;
94
0
}
95
96
int FoFiBase::getU8(int pos, bool *ok) const
97
11.5G
{
98
11.5G
    if (pos < 0 || pos >= int(file.size())) {
99
10.4G
        *ok = false;
100
10.4G
        return 0;
101
10.4G
    }
102
1.16G
    return file[pos];
103
11.5G
}
104
105
int FoFiBase::getS16BE(int pos, bool *ok) const
106
797k
{
107
797k
    int x;
108
109
797k
    if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= int(file.size())) {
110
13.9k
        *ok = false;
111
13.9k
        return 0;
112
13.9k
    }
113
783k
    x = file[pos];
114
783k
    x = (x << 8) + file[pos + 1];
115
783k
    if (x & 0x8000) {
116
296k
        x |= ~0xffff;
117
296k
    }
118
783k
    return x;
119
797k
}
120
121
int FoFiBase::getU16BE(int pos, bool *ok) const
122
8.92G
{
123
8.92G
    int x;
124
125
8.92G
    if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= int(file.size())) {
126
219M
        *ok = false;
127
219M
        return 0;
128
219M
    }
129
8.70G
    x = file[pos];
130
8.70G
    x = (x << 8) + file[pos + 1];
131
8.70G
    return x;
132
8.92G
}
133
134
int FoFiBase::getS32BE(int pos, bool *ok) const
135
4.75k
{
136
4.75k
    int x;
137
138
4.75k
    if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= int(file.size())) {
139
0
        *ok = false;
140
0
        return 0;
141
0
    }
142
4.75k
    x = file[pos];
143
4.75k
    x = (x << 8) + file[pos + 1];
144
4.75k
    x = (x << 8) + file[pos + 2];
145
4.75k
    x = (x << 8) + file[pos + 3];
146
4.75k
    if (x & 0x80000000) {
147
0
        x |= ~0xffffffff;
148
0
    }
149
4.75k
    return x;
150
4.75k
}
151
152
unsigned int FoFiBase::getU32BE(int pos, bool *ok) const
153
1.81G
{
154
1.81G
    unsigned int x;
155
156
1.81G
    if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= int(file.size())) {
157
483M
        *ok = false;
158
483M
        return 0;
159
483M
    }
160
1.33G
    x = file[pos];
161
1.33G
    x = (x << 8) + file[pos + 1];
162
1.33G
    x = (x << 8) + file[pos + 2];
163
1.33G
    x = (x << 8) + file[pos + 3];
164
1.33G
    return x;
165
1.81G
}
166
167
unsigned int FoFiBase::getU32LE(int pos, bool *ok) const
168
398
{
169
398
    unsigned int x;
170
171
398
    if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= int(file.size())) {
172
0
        *ok = false;
173
0
        return 0;
174
0
    }
175
398
    x = file[pos + 3];
176
398
    x = (x << 8) + file[pos + 2];
177
398
    x = (x << 8) + file[pos + 1];
178
398
    x = (x << 8) + file[pos];
179
398
    return x;
180
398
}
181
182
unsigned int FoFiBase::getUVarBE(int pos, int size, bool *ok) const
183
12.0M
{
184
12.0M
    unsigned int x;
185
12.0M
    int i;
186
187
12.0M
    if (pos < 0 || pos > INT_MAX - size || pos + size > int(file.size())) {
188
198k
        *ok = false;
189
198k
        return 0;
190
198k
    }
191
11.8M
    x = 0;
192
36.8M
    for (i = 0; i < size; ++i) {
193
25.0M
        x = (x << 8) + file[pos + i];
194
25.0M
    }
195
11.8M
    return x;
196
12.0M
}
197
198
bool FoFiBase::checkRegion(int pos, int size) const
199
636M
{
200
636M
    return pos >= 0 && size >= 0 && pos < INT_MAX - size && size < INT_MAX - pos && pos + size >= pos && pos + size <= int(file.size());
201
636M
}