• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fxcrt/fx_basic.h"
8 #include "core/fxcrt/fx_ext.h"
9 
10 #include <algorithm>
11 #include <cctype>
12 #include <limits>
13 #include <memory>
14 
FX_atonum(const CFX_ByteStringC & strc,void * pData)15 bool FX_atonum(const CFX_ByteStringC& strc, void* pData) {
16   if (strc.Find('.') != -1) {
17     FX_FLOAT* pFloat = static_cast<FX_FLOAT*>(pData);
18     *pFloat = FX_atof(strc);
19     return false;
20   }
21 
22   // Note, numbers in PDF are typically of the form 123, -123, etc. But,
23   // for things like the Permissions on the encryption hash the number is
24   // actually an unsigned value. We use a uint32_t so we can deal with the
25   // unsigned and then check for overflow if the user actually signed the value.
26   // The Permissions flag is listed in Table 3.20 PDF 1.7 spec.
27   pdfium::base::CheckedNumeric<uint32_t> integer = 0;
28   bool bNegative = false;
29   bool bSigned = false;
30   int cc = 0;
31   if (strc[0] == '+') {
32     cc++;
33     bSigned = true;
34   } else if (strc[0] == '-') {
35     bNegative = true;
36     bSigned = true;
37     cc++;
38   }
39 
40   while (cc < strc.GetLength() && std::isdigit(strc[cc])) {
41     integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
42     if (!integer.IsValid())
43       break;
44     cc++;
45   }
46 
47   // We have a sign, and the value was greater then a regular integer
48   // we've overflowed, reset to the default value.
49   if (bSigned) {
50     if (bNegative) {
51       if (integer.ValueOrDefault(0) >
52           static_cast<uint32_t>(std::numeric_limits<int>::max()) + 1) {
53         integer = 0;
54       }
55     } else if (integer.ValueOrDefault(0) >
56                static_cast<uint32_t>(std::numeric_limits<int>::max())) {
57       integer = 0;
58     }
59   }
60 
61   // Switch back to the int space so we can flip to a negative if we need.
62   uint32_t uValue = integer.ValueOrDefault(0);
63   int32_t value = static_cast<int>(uValue);
64   if (bNegative)
65     value = -value;
66 
67   int* pInt = static_cast<int*>(pData);
68   *pInt = value;
69   return true;
70 }
71 
72 static const FX_FLOAT fraction_scales[] = {
73     0.1f,         0.01f,         0.001f,        0.0001f,
74     0.00001f,     0.000001f,     0.0000001f,    0.00000001f,
75     0.000000001f, 0.0000000001f, 0.00000000001f};
76 
FXSYS_FractionalScaleCount()77 int FXSYS_FractionalScaleCount() {
78   return FX_ArraySize(fraction_scales);
79 }
80 
FXSYS_FractionalScale(size_t scale_factor,int value)81 FX_FLOAT FXSYS_FractionalScale(size_t scale_factor, int value) {
82   return fraction_scales[scale_factor] * value;
83 }
84 
FX_atof(const CFX_ByteStringC & strc)85 FX_FLOAT FX_atof(const CFX_ByteStringC& strc) {
86   if (strc.IsEmpty())
87     return 0.0;
88 
89   int cc = 0;
90   bool bNegative = false;
91   int len = strc.GetLength();
92   if (strc[0] == '+') {
93     cc++;
94   } else if (strc[0] == '-') {
95     bNegative = true;
96     cc++;
97   }
98   while (cc < len) {
99     if (strc[cc] != '+' && strc[cc] != '-')
100       break;
101     cc++;
102   }
103   FX_FLOAT value = 0;
104   while (cc < len) {
105     if (strc[cc] == '.')
106       break;
107     value = value * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
108     cc++;
109   }
110   int scale = 0;
111   if (cc < len && strc[cc] == '.') {
112     cc++;
113     while (cc < len) {
114       value +=
115           FXSYS_FractionalScale(scale, FXSYS_toDecimalDigit(strc.CharAt(cc)));
116       scale++;
117       if (scale == FXSYS_FractionalScaleCount())
118         break;
119       cc++;
120     }
121   }
122   return bNegative ? -value : value;
123 }
124 
125 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900
FXSYS_snprintf(char * str,size_t size,_Printf_format_string_ const char * fmt,...)126 void FXSYS_snprintf(char* str,
127                     size_t size,
128                     _Printf_format_string_ const char* fmt,
129                     ...) {
130   va_list ap;
131   va_start(ap, fmt);
132   FXSYS_vsnprintf(str, size, fmt, ap);
133   va_end(ap);
134 }
135 
FXSYS_vsnprintf(char * str,size_t size,const char * fmt,va_list ap)136 void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap) {
137   (void)_vsnprintf(str, size, fmt, ap);
138   if (size)
139     str[size - 1] = 0;
140 }
141 #endif  // _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900
142 
FX_OpenFolder(const FX_CHAR * path)143 FX_FileHandle* FX_OpenFolder(const FX_CHAR* path) {
144 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
145   std::unique_ptr<CFindFileDataA> pData(new CFindFileDataA);
146   pData->m_Handle = FindFirstFileExA((CFX_ByteString(path) + "/*.*").c_str(),
147                                      FindExInfoStandard, &pData->m_FindData,
148                                      FindExSearchNameMatch, nullptr, 0);
149   if (pData->m_Handle == INVALID_HANDLE_VALUE)
150     return nullptr;
151 
152   pData->m_bEnd = false;
153   return pData.release();
154 #else
155   return opendir(path);
156 #endif
157 }
158 
FX_GetNextFile(FX_FileHandle * handle,CFX_ByteString * filename,bool * bFolder)159 bool FX_GetNextFile(FX_FileHandle* handle,
160                     CFX_ByteString* filename,
161                     bool* bFolder) {
162   if (!handle)
163     return false;
164 
165 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
166   if (handle->m_bEnd)
167     return false;
168 
169   *filename = handle->m_FindData.cFileName;
170   *bFolder =
171       (handle->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
172   if (!FindNextFileA(handle->m_Handle, &handle->m_FindData))
173     handle->m_bEnd = true;
174   return true;
175 #elif defined(__native_client__)
176   abort();
177   return false;
178 #else
179   struct dirent* de = readdir(handle);
180   if (!de)
181     return false;
182   *filename = de->d_name;
183   *bFolder = de->d_type == DT_DIR;
184   return true;
185 #endif
186 }
187 
FX_CloseFolder(FX_FileHandle * handle)188 void FX_CloseFolder(FX_FileHandle* handle) {
189   if (!handle)
190     return;
191 
192 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
193   FindClose(handle->m_Handle);
194   delete handle;
195 #else
196   closedir(handle);
197 #endif
198 }
199 
FX_GetFolderSeparator()200 FX_WCHAR FX_GetFolderSeparator() {
201 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
202   return '\\';
203 #else
204   return '/';
205 #endif
206 }
207 
Inverse()208 CFX_Matrix_3by3 CFX_Matrix_3by3::Inverse() {
209   FX_FLOAT det =
210       a * (e * i - f * h) - b * (i * d - f * g) + c * (d * h - e * g);
211   if (FXSYS_fabs(det) < 0.0000001)
212     return CFX_Matrix_3by3();
213 
214   return CFX_Matrix_3by3(
215       (e * i - f * h) / det, -(b * i - c * h) / det, (b * f - c * e) / det,
216       -(d * i - f * g) / det, (a * i - c * g) / det, -(a * f - c * d) / det,
217       (d * h - e * g) / det, -(a * h - b * g) / det, (a * e - b * d) / det);
218 }
219 
Multiply(const CFX_Matrix_3by3 & m)220 CFX_Matrix_3by3 CFX_Matrix_3by3::Multiply(const CFX_Matrix_3by3& m) {
221   return CFX_Matrix_3by3(
222       a * m.a + b * m.d + c * m.g, a * m.b + b * m.e + c * m.h,
223       a * m.c + b * m.f + c * m.i, d * m.a + e * m.d + f * m.g,
224       d * m.b + e * m.e + f * m.h, d * m.c + e * m.f + f * m.i,
225       g * m.a + h * m.d + i * m.g, g * m.b + h * m.e + i * m.h,
226       g * m.c + h * m.f + i * m.i);
227 }
228 
TransformVector(const CFX_Vector_3by1 & v)229 CFX_Vector_3by1 CFX_Matrix_3by3::TransformVector(const CFX_Vector_3by1& v) {
230   return CFX_Vector_3by1(a * v.a + b * v.b + c * v.c,
231                          d * v.a + e * v.b + f * v.c,
232                          g * v.a + h * v.b + i * v.c);
233 }
234 
GetBits32(const uint8_t * pData,int bitpos,int nbits)235 uint32_t GetBits32(const uint8_t* pData, int bitpos, int nbits) {
236   ASSERT(0 < nbits && nbits <= 32);
237   const uint8_t* dataPtr = &pData[bitpos / 8];
238   int bitShift;
239   int bitMask;
240   int dstShift;
241   int bitCount = bitpos & 0x07;
242   if (nbits < 8 && nbits + bitCount <= 8) {
243     bitShift = 8 - nbits - bitCount;
244     bitMask = (1 << nbits) - 1;
245     dstShift = 0;
246   } else {
247     bitShift = 0;
248     int bitOffset = 8 - bitCount;
249     bitMask = (1 << std::min(bitOffset, nbits)) - 1;
250     dstShift = nbits - bitOffset;
251   }
252   uint32_t result =
253       static_cast<uint32_t>((*dataPtr++ >> bitShift & bitMask) << dstShift);
254   while (dstShift >= 8) {
255     dstShift -= 8;
256     result |= *dataPtr++ << dstShift;
257   }
258   if (dstShift > 0) {
259     bitShift = 8 - dstShift;
260     bitMask = (1 << dstShift) - 1;
261     result |= *dataPtr++ >> bitShift & bitMask;
262   }
263   return result;
264 }
265