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//
23// To see a description of the changes please see the Changelog file that
24// came with your tarball or type make ChangeLog if you are building from git
25//
26//========================================================================
27
28#include <config.h>
29
30#include <cstdio>
31#include <climits>
32#include "goo/gfile.h"
33#include "goo/gmem.h"
34#include "poppler/Error.h"
35#include "FoFiBase.h"
36
37//------------------------------------------------------------------------
38// FoFiBase
39//------------------------------------------------------------------------
40
41FoFiBase::FoFiBase(const unsigned char *fileA, int lenA, bool freeFileDataA)
42{
43 file = fileA;
44 len = lenA;
45 freeFileData = freeFileDataA;
46}
47
48FoFiBase::~FoFiBase()
49{
50 if (freeFileData) {
51 gfree(p: (char *)file);
52 }
53}
54
55char *FoFiBase::readFile(const char *fileName, int *fileLen)
56{
57 FILE *f;
58 char *buf;
59 int n;
60
61 if (!(f = openFile(path: fileName, mode: "rb"))) {
62 error(category: errIO, pos: -1, msg: "Cannot open '{0:s}'", fileName);
63 return nullptr;
64 }
65 if (fseek(stream: f, off: 0, SEEK_END) != 0) {
66 error(category: errIO, pos: -1, msg: "Cannot seek to end of '{0:s}'", fileName);
67 fclose(stream: f);
68 return nullptr;
69 }
70 n = (int)ftell(stream: f);
71 if (n < 0) {
72 error(category: errIO, pos: -1, msg: "Cannot determine length of '{0:s}'", fileName);
73 fclose(stream: f);
74 return nullptr;
75 }
76 if (fseek(stream: f, off: 0, SEEK_SET) != 0) {
77 error(category: errIO, pos: -1, msg: "Cannot seek to start of '{0:s}'", fileName);
78 fclose(stream: f);
79 return nullptr;
80 }
81 buf = (char *)gmalloc(size: n);
82 if ((int)fread(ptr: buf, size: 1, n: n, stream: f) != n) {
83 gfree(p: buf);
84 fclose(stream: f);
85 return nullptr;
86 }
87 fclose(stream: f);
88 *fileLen = n;
89 return buf;
90}
91
92int FoFiBase::getS8(int pos, bool *ok) const
93{
94 int x;
95
96 if (pos < 0 || pos >= len) {
97 *ok = false;
98 return 0;
99 }
100 x = file[pos];
101 if (x & 0x80) {
102 x |= ~0xff;
103 }
104 return x;
105}
106
107int FoFiBase::getU8(int pos, bool *ok) const
108{
109 if (pos < 0 || pos >= len) {
110 *ok = false;
111 return 0;
112 }
113 return file[pos];
114}
115
116int FoFiBase::getS16BE(int pos, bool *ok) const
117{
118 int x;
119
120 if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= len) {
121 *ok = false;
122 return 0;
123 }
124 x = file[pos];
125 x = (x << 8) + file[pos + 1];
126 if (x & 0x8000) {
127 x |= ~0xffff;
128 }
129 return x;
130}
131
132int FoFiBase::getU16BE(int pos, bool *ok) const
133{
134 int x;
135
136 if (pos < 0 || pos > INT_MAX - 1 || pos + 1 >= len) {
137 *ok = false;
138 return 0;
139 }
140 x = file[pos];
141 x = (x << 8) + file[pos + 1];
142 return x;
143}
144
145int FoFiBase::getS32BE(int pos, bool *ok) const
146{
147 int x;
148
149 if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= len) {
150 *ok = false;
151 return 0;
152 }
153 x = file[pos];
154 x = (x << 8) + file[pos + 1];
155 x = (x << 8) + file[pos + 2];
156 x = (x << 8) + file[pos + 3];
157 if (x & 0x80000000) {
158 x |= ~0xffffffff;
159 }
160 return x;
161}
162
163unsigned int FoFiBase::getU32BE(int pos, bool *ok) const
164{
165 unsigned int x;
166
167 if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= len) {
168 *ok = false;
169 return 0;
170 }
171 x = file[pos];
172 x = (x << 8) + file[pos + 1];
173 x = (x << 8) + file[pos + 2];
174 x = (x << 8) + file[pos + 3];
175 return x;
176}
177
178unsigned int FoFiBase::getU32LE(int pos, bool *ok) const
179{
180 unsigned int x;
181
182 if (pos < 0 || pos > INT_MAX - 3 || pos + 3 >= len) {
183 *ok = false;
184 return 0;
185 }
186 x = file[pos + 3];
187 x = (x << 8) + file[pos + 2];
188 x = (x << 8) + file[pos + 1];
189 x = (x << 8) + file[pos];
190 return x;
191}
192
193unsigned int FoFiBase::getUVarBE(int pos, int size, bool *ok) const
194{
195 unsigned int x;
196 int i;
197
198 if (pos < 0 || pos > INT_MAX - size || pos + size > len) {
199 *ok = false;
200 return 0;
201 }
202 x = 0;
203 for (i = 0; i < size; ++i) {
204 x = (x << 8) + file[pos + i];
205 }
206 return x;
207}
208
209bool FoFiBase::checkRegion(int pos, int size) const
210{
211 return pos >= 0 && size >= 0 && pos < INT_MAX - size && size < INT_MAX - pos && pos + size >= pos && pos + size <= len;
212}
213

source code of poppler/fofi/FoFiBase.cc