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