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