/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 | } |