Coverage Report

Created: 2026-10-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/fofi/FoFiBase.cc
Line
Count
Source
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, 2026 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, 2026 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
5.47k
FoFiBase::FoFiBase(std::vector<unsigned char> &&fileA) : fileOwner(std::move(fileA)), file(fileOwner) { }
42
43
0
FoFiBase::FoFiBase(std::span<const unsigned char> fileA) : file(fileA) { }
44
45
5.47k
FoFiBase::~FoFiBase() = default;
46
47
std::optional<std::vector<unsigned char>> FoFiBase::readFile(const char *fileName)
48
601
{
49
601
    FILE *f;
50
51
601
    if (!(f = openFile(fileName, "rb"))) {
52
0
        error(errIO, -1, "Cannot open '{0:s}'", fileName);
53
0
        return std::nullopt;
54
0
    }
55
601
    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
601
    const int n = static_cast<int>(ftell(f));
61
601
    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
601
    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
601
    const size_t nToRead = n;
72
601
    std::vector<unsigned char> buf;
73
601
    buf.resize(nToRead);
74
601
    if (fread(buf.data(), 1, nToRead, f) != nToRead) {
75
0
        fclose(f);
76
0
        return std::nullopt;
77
0
    }
78
601
    fclose(f);
79
601
    return buf;
80
601
}
81
82
int FoFiBase::getS8(int pos, bool *ok) const
83
0
{
84
0
    int x;
85
86
0
    if (pos < 0 || static_cast<size_t>(pos) >= file.size()) {
87
0
        *ok = false;
88
0
        return 0;
89
0
    }
90
0
    x = file[pos];
91
0
    if (x & 0x80) {
92
0
        x |= ~0xff;
93
0
    }
94
0
    return x;
95
0
}
96
97
int FoFiBase::getU8(int pos, bool *ok) const
98
2.62M
{
99
2.62M
    if (pos < 0 || static_cast<size_t>(pos) >= file.size()) {
100
394
        *ok = false;
101
394
        return 0;
102
394
    }
103
2.62M
    return file[pos];
104
2.62M
}
105
106
int FoFiBase::getS16BE(int pos, bool *ok) const
107
3.00k
{
108
3.00k
    int x;
109
110
3.00k
    if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= static_cast<int>(file.size())) {
111
0
        *ok = false;
112
0
        return 0;
113
0
    }
114
3.00k
    x = file[pos];
115
3.00k
    x = (x << 8) + file[pos + 1];
116
3.00k
    if (x & 0x8000) {
117
1.20k
        x |= ~0xffff;
118
1.20k
    }
119
3.00k
    return x;
120
3.00k
}
121
122
int FoFiBase::getU16BE(int pos, bool *ok) const
123
2.67M
{
124
2.67M
    int x;
125
126
2.67M
    if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= static_cast<int>(file.size())) {
127
732
        *ok = false;
128
732
        return 0;
129
732
    }
130
2.67M
    x = file[pos];
131
2.67M
    x = (x << 8) + file[pos + 1];
132
2.67M
    return x;
133
2.67M
}
134
135
int FoFiBase::getS32BE(int pos, bool *ok) const
136
0
{
137
0
    int x;
138
139
0
    if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= static_cast<int>(file.size())) {
140
0
        *ok = false;
141
0
        return 0;
142
0
    }
143
0
    x = file[pos];
144
0
    x = (x << 8) + file[pos + 1];
145
0
    x = (x << 8) + file[pos + 2];
146
0
    x = (x << 8) + file[pos + 3];
147
0
    if (x & 0x80000000) {
148
0
        x |= ~0xffffffff;
149
0
    }
150
0
    return x;
151
0
}
152
153
unsigned int FoFiBase::getU32BE(int pos, bool *ok) const
154
43.6k
{
155
43.6k
    unsigned int x;
156
157
43.6k
    if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= static_cast<int>(file.size())) {
158
0
        *ok = false;
159
0
        return 0;
160
0
    }
161
43.6k
    x = file[pos];
162
43.6k
    x = (x << 8) + file[pos + 1];
163
43.6k
    x = (x << 8) + file[pos + 2];
164
43.6k
    x = (x << 8) + file[pos + 3];
165
43.6k
    return x;
166
43.6k
}
167
168
unsigned int FoFiBase::getU32LE(int pos, bool *ok) const
169
21
{
170
21
    unsigned int x;
171
172
21
    if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= static_cast<int>(file.size())) {
173
0
        *ok = false;
174
0
        return 0;
175
0
    }
176
21
    x = file[pos + 3];
177
21
    x = (x << 8) + file[pos + 2];
178
21
    x = (x << 8) + file[pos + 1];
179
21
    x = (x << 8) + file[pos];
180
21
    return x;
181
21
}
182
183
unsigned int FoFiBase::getUVarBE(int pos, int size, bool *ok) const
184
98.1k
{
185
98.1k
    unsigned int x;
186
98.1k
    int i;
187
188
98.1k
    if (pos < 0 || pos > INT_MAX - size || pos + size > static_cast<int>(file.size())) {
189
222
        *ok = false;
190
222
        return 0;
191
222
    }
192
97.9k
    x = 0;
193
279k
    for (i = 0; i < size; ++i) {
194
181k
        x = (x << 8) + file[pos + i];
195
181k
    }
196
97.9k
    return x;
197
98.1k
}
198
199
bool FoFiBase::checkRegion(int pos, int size) const
200
2.48M
{
201
2.48M
    return pos >= 0 && size >= 0 && pos < INT_MAX - size && size < INT_MAX - pos && pos + size >= pos && pos + size <= static_cast<int>(file.size());
202
2.48M
}