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