Coverage Report

Created: 2026-07-30 07:17

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
111
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
111
FoFiBase::~FoFiBase() = default;
46
47
std::optional<std::vector<unsigned char>> FoFiBase::readFile(const char *fileName)
48
0
{
49
0
    FILE *f;
50
51
0
    if (!(f = openFile(fileName, "rb"))) {
52
0
        error(errIO, -1, "Cannot open '{0:s}'", fileName);
53
0
        return std::nullopt;
54
0
    }
55
0
    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
0
    const int n = static_cast<int>(ftell(f));
61
0
    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
0
    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
0
    const size_t nToRead = n;
72
0
    std::vector<unsigned char> buf;
73
0
    buf.resize(nToRead);
74
0
    if (fread(buf.data(), 1, nToRead, f) != nToRead) {
75
0
        fclose(f);
76
0
        return std::nullopt;
77
0
    }
78
0
    fclose(f);
79
0
    return buf;
80
0
}
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
298
{
99
298
    if (pos < 0 || static_cast<size_t>(pos) >= file.size()) {
100
3
        *ok = false;
101
3
        return 0;
102
3
    }
103
295
    return file[pos];
104
298
}
105
106
int FoFiBase::getS16BE(int pos, bool *ok) const
107
0
{
108
0
    int x;
109
110
0
    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
0
    x = file[pos];
115
0
    x = (x << 8) + file[pos + 1];
116
0
    if (x & 0x8000) {
117
0
        x |= ~0xffff;
118
0
    }
119
0
    return x;
120
0
}
121
122
int FoFiBase::getU16BE(int pos, bool *ok) const
123
444
{
124
444
    int x;
125
126
444
    if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= static_cast<int>(file.size())) {
127
126
        *ok = false;
128
126
        return 0;
129
126
    }
130
318
    x = file[pos];
131
318
    x = (x << 8) + file[pos + 1];
132
318
    return x;
133
444
}
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
0
{
155
0
    unsigned int x;
156
157
0
    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
0
    x = file[pos];
162
0
    x = (x << 8) + file[pos + 1];
163
0
    x = (x << 8) + file[pos + 2];
164
0
    x = (x << 8) + file[pos + 3];
165
0
    return x;
166
0
}
167
168
unsigned int FoFiBase::getU32LE(int pos, bool *ok) const
169
0
{
170
0
    unsigned int x;
171
172
0
    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
0
    x = file[pos + 3];
177
0
    x = (x << 8) + file[pos + 2];
178
0
    x = (x << 8) + file[pos + 1];
179
0
    x = (x << 8) + file[pos];
180
0
    return x;
181
0
}
182
183
unsigned int FoFiBase::getUVarBE(int pos, int size, bool *ok) const
184
187
{
185
187
    unsigned int x;
186
187
    int i;
187
188
187
    if (pos < 0 || pos > INT_MAX - size || pos + size > static_cast<int>(file.size())) {
189
66
        *ok = false;
190
66
        return 0;
191
66
    }
192
121
    x = 0;
193
1.21k
    for (i = 0; i < size; ++i) {
194
1.09k
        x = (x << 8) + file[pos + i];
195
1.09k
    }
196
121
    return x;
197
187
}
198
199
bool FoFiBase::checkRegion(int pos, int size) const
200
0
{
201
0
    return pos >= 0 && size >= 0 && pos < INT_MAX - size && size < INT_MAX - pos && pos + size >= pos && pos + size <= static_cast<int>(file.size());
202
0
}