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/include/fxcrt/fx_basic.h" 8 #include "core/include/fxcrt/fx_ext.h" 9 #include "extension.h" 10 11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 12 #include <wincrypt.h> 13 #else 14 #include <ctime> 15 #endif 16 17 CFX_CRTFileStream::CFX_CRTFileStream(IFXCRT_FileAccess* pFA) 18 : m_pFile(pFA), m_dwCount(1) {} 19 20 CFX_CRTFileStream::~CFX_CRTFileStream() { 21 if (m_pFile) { 22 m_pFile->Release(); 23 } 24 } 25 26 IFX_FileStream* CFX_CRTFileStream::Retain() { 27 m_dwCount++; 28 return this; 29 } 30 31 void CFX_CRTFileStream::Release() { 32 FX_DWORD nCount = --m_dwCount; 33 if (!nCount) { 34 delete this; 35 } 36 } 37 38 FX_FILESIZE CFX_CRTFileStream::GetSize() { 39 return m_pFile->GetSize(); 40 } 41 42 FX_BOOL CFX_CRTFileStream::IsEOF() { 43 return GetPosition() >= GetSize(); 44 } 45 46 FX_FILESIZE CFX_CRTFileStream::GetPosition() { 47 return m_pFile->GetPosition(); 48 } 49 50 FX_BOOL CFX_CRTFileStream::ReadBlock(void* buffer, 51 FX_FILESIZE offset, 52 size_t size) { 53 return (FX_BOOL)m_pFile->ReadPos(buffer, size, offset); 54 } 55 56 size_t CFX_CRTFileStream::ReadBlock(void* buffer, size_t size) { 57 return m_pFile->Read(buffer, size); 58 } 59 60 FX_BOOL CFX_CRTFileStream::WriteBlock(const void* buffer, 61 FX_FILESIZE offset, 62 size_t size) { 63 return (FX_BOOL)m_pFile->WritePos(buffer, size, offset); 64 } 65 66 FX_BOOL CFX_CRTFileStream::Flush() { 67 return m_pFile->Flush(); 68 } 69 70 #ifdef PDF_ENABLE_XFA 71 IFX_FileAccess* FX_CreateDefaultFileAccess(const CFX_WideStringC& wsPath) { 72 if (wsPath.GetLength() == 0) 73 return NULL; 74 75 CFX_CRTFileAccess* pFA = NULL; 76 pFA = new CFX_CRTFileAccess; 77 if (NULL == pFA) 78 return NULL; 79 80 pFA->Init(wsPath); 81 return pFA; 82 } 83 #endif // PDF_ENABLE_XFA 84 85 IFX_FileStream* FX_CreateFileStream(const FX_CHAR* filename, FX_DWORD dwModes) { 86 IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create(); 87 if (!pFA) { 88 return NULL; 89 } 90 if (!pFA->Open(filename, dwModes)) { 91 pFA->Release(); 92 return NULL; 93 } 94 return new CFX_CRTFileStream(pFA); 95 } 96 IFX_FileStream* FX_CreateFileStream(const FX_WCHAR* filename, 97 FX_DWORD dwModes) { 98 IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create(); 99 if (!pFA) { 100 return NULL; 101 } 102 if (!pFA->Open(filename, dwModes)) { 103 pFA->Release(); 104 return NULL; 105 } 106 return new CFX_CRTFileStream(pFA); 107 } 108 IFX_FileRead* FX_CreateFileRead(const FX_CHAR* filename) { 109 return FX_CreateFileStream(filename, FX_FILEMODE_ReadOnly); 110 } 111 IFX_FileRead* FX_CreateFileRead(const FX_WCHAR* filename) { 112 return FX_CreateFileStream(filename, FX_FILEMODE_ReadOnly); 113 } 114 IFX_MemoryStream* FX_CreateMemoryStream(uint8_t* pBuffer, 115 size_t dwSize, 116 FX_BOOL bTakeOver) { 117 return new CFX_MemoryStream(pBuffer, dwSize, bTakeOver); 118 } 119 IFX_MemoryStream* FX_CreateMemoryStream(FX_BOOL bConsecutive) { 120 return new CFX_MemoryStream(bConsecutive); 121 } 122 123 FX_FLOAT FXSYS_tan(FX_FLOAT a) { 124 return (FX_FLOAT)tan(a); 125 } 126 FX_FLOAT FXSYS_logb(FX_FLOAT b, FX_FLOAT x) { 127 return FXSYS_log(x) / FXSYS_log(b); 128 } 129 FX_FLOAT FXSYS_strtof(const FX_CHAR* pcsStr, 130 int32_t iLength, 131 int32_t* pUsedLen) { 132 FXSYS_assert(pcsStr); 133 if (iLength < 0) { 134 iLength = (int32_t)FXSYS_strlen(pcsStr); 135 } 136 CFX_WideString ws = CFX_WideString::FromLocal(pcsStr, iLength); 137 return FXSYS_wcstof(ws.c_str(), iLength, pUsedLen); 138 } 139 FX_FLOAT FXSYS_wcstof(const FX_WCHAR* pwsStr, 140 int32_t iLength, 141 int32_t* pUsedLen) { 142 FXSYS_assert(pwsStr); 143 if (iLength < 0) { 144 iLength = (int32_t)FXSYS_wcslen(pwsStr); 145 } 146 if (iLength == 0) { 147 return 0.0f; 148 } 149 int32_t iUsedLen = 0; 150 FX_BOOL bNegtive = FALSE; 151 switch (pwsStr[iUsedLen]) { 152 case '-': 153 bNegtive = TRUE; 154 case '+': 155 iUsedLen++; 156 break; 157 } 158 FX_FLOAT fValue = 0.0f; 159 while (iUsedLen < iLength) { 160 FX_WCHAR wch = pwsStr[iUsedLen]; 161 if (wch >= L'0' && wch <= L'9') { 162 fValue = fValue * 10.0f + (wch - L'0'); 163 } else { 164 break; 165 } 166 iUsedLen++; 167 } 168 if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') { 169 FX_FLOAT fPrecise = 0.1f; 170 while (++iUsedLen < iLength) { 171 FX_WCHAR wch = pwsStr[iUsedLen]; 172 if (wch >= L'0' && wch <= L'9') { 173 fValue += (wch - L'0') * fPrecise; 174 fPrecise *= 0.1f; 175 } else { 176 break; 177 } 178 } 179 } 180 if (pUsedLen) { 181 *pUsedLen = iUsedLen; 182 } 183 return bNegtive ? -fValue : fValue; 184 } 185 FX_WCHAR* FXSYS_wcsncpy(FX_WCHAR* dstStr, 186 const FX_WCHAR* srcStr, 187 size_t count) { 188 FXSYS_assert(dstStr && srcStr && count > 0); 189 for (size_t i = 0; i < count; ++i) 190 if ((dstStr[i] = srcStr[i]) == L'\0') { 191 break; 192 } 193 return dstStr; 194 } 195 int32_t FXSYS_wcsnicmp(const FX_WCHAR* s1, const FX_WCHAR* s2, size_t count) { 196 FXSYS_assert(s1 && s2 && count > 0); 197 FX_WCHAR wch1 = 0, wch2 = 0; 198 while (count-- > 0) { 199 wch1 = (FX_WCHAR)FXSYS_tolower(*s1++); 200 wch2 = (FX_WCHAR)FXSYS_tolower(*s2++); 201 if (wch1 != wch2) { 202 break; 203 } 204 } 205 return wch1 - wch2; 206 } 207 int32_t FXSYS_strnicmp(const FX_CHAR* s1, const FX_CHAR* s2, size_t count) { 208 FXSYS_assert(s1 && s2 && count > 0); 209 FX_CHAR ch1 = 0, ch2 = 0; 210 while (count-- > 0) { 211 ch1 = (FX_CHAR)FXSYS_tolower(*s1++); 212 ch2 = (FX_CHAR)FXSYS_tolower(*s2++); 213 if (ch1 != ch2) { 214 break; 215 } 216 } 217 return ch1 - ch2; 218 } 219 FX_DWORD FX_HashCode_String_GetA(const FX_CHAR* pStr, 220 int32_t iLength, 221 FX_BOOL bIgnoreCase) { 222 FXSYS_assert(pStr); 223 if (iLength < 0) { 224 iLength = (int32_t)FXSYS_strlen(pStr); 225 } 226 const FX_CHAR* pStrEnd = pStr + iLength; 227 FX_DWORD dwHashCode = 0; 228 if (bIgnoreCase) { 229 while (pStr < pStrEnd) { 230 dwHashCode = 31 * dwHashCode + FXSYS_tolower(*pStr++); 231 } 232 } else { 233 while (pStr < pStrEnd) { 234 dwHashCode = 31 * dwHashCode + *pStr++; 235 } 236 } 237 return dwHashCode; 238 } 239 FX_DWORD FX_HashCode_String_GetW(const FX_WCHAR* pStr, 240 int32_t iLength, 241 FX_BOOL bIgnoreCase) { 242 FXSYS_assert(pStr); 243 if (iLength < 0) { 244 iLength = (int32_t)FXSYS_wcslen(pStr); 245 } 246 const FX_WCHAR* pStrEnd = pStr + iLength; 247 FX_DWORD dwHashCode = 0; 248 if (bIgnoreCase) { 249 while (pStr < pStrEnd) { 250 dwHashCode = 1313 * dwHashCode + FXSYS_tolower(*pStr++); 251 } 252 } else { 253 while (pStr < pStrEnd) { 254 dwHashCode = 1313 * dwHashCode + *pStr++; 255 } 256 } 257 return dwHashCode; 258 } 259 260 void* FX_Random_MT_Start(FX_DWORD dwSeed) { 261 FX_LPMTRANDOMCONTEXT pContext = FX_Alloc(FX_MTRANDOMCONTEXT, 1); 262 pContext->mt[0] = dwSeed; 263 FX_DWORD& i = pContext->mti; 264 FX_DWORD* pBuf = pContext->mt; 265 for (i = 1; i < MT_N; i++) { 266 pBuf[i] = (1812433253UL * (pBuf[i - 1] ^ (pBuf[i - 1] >> 30)) + i); 267 } 268 pContext->bHaveSeed = TRUE; 269 return pContext; 270 } 271 FX_DWORD FX_Random_MT_Generate(void* pContext) { 272 FXSYS_assert(pContext); 273 FX_LPMTRANDOMCONTEXT pMTC = (FX_LPMTRANDOMCONTEXT)pContext; 274 FX_DWORD v; 275 static FX_DWORD mag[2] = {0, MT_Matrix_A}; 276 FX_DWORD& mti = pMTC->mti; 277 FX_DWORD* pBuf = pMTC->mt; 278 if ((int)mti < 0 || mti >= MT_N) { 279 if (mti > MT_N && !pMTC->bHaveSeed) { 280 return 0; 281 } 282 FX_DWORD kk; 283 for (kk = 0; kk < MT_N - MT_M; kk++) { 284 v = (pBuf[kk] & MT_Upper_Mask) | (pBuf[kk + 1] & MT_Lower_Mask); 285 pBuf[kk] = pBuf[kk + MT_M] ^ (v >> 1) ^ mag[v & 1]; 286 } 287 for (; kk < MT_N - 1; kk++) { 288 v = (pBuf[kk] & MT_Upper_Mask) | (pBuf[kk + 1] & MT_Lower_Mask); 289 pBuf[kk] = pBuf[kk + (MT_M - MT_N)] ^ (v >> 1) ^ mag[v & 1]; 290 } 291 v = (pBuf[MT_N - 1] & MT_Upper_Mask) | (pBuf[0] & MT_Lower_Mask); 292 pBuf[MT_N - 1] = pBuf[MT_M - 1] ^ (v >> 1) ^ mag[v & 1]; 293 mti = 0; 294 } 295 v = pBuf[mti++]; 296 v ^= (v >> 11); 297 v ^= (v << 7) & 0x9d2c5680UL; 298 v ^= (v << 15) & 0xefc60000UL; 299 v ^= (v >> 18); 300 return v; 301 } 302 void FX_Random_MT_Close(void* pContext) { 303 FXSYS_assert(pContext); 304 FX_Free(pContext); 305 } 306 void FX_Random_GenerateMT(FX_DWORD* pBuffer, int32_t iCount) { 307 FX_DWORD dwSeed; 308 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 309 if (!FX_GenerateCryptoRandom(&dwSeed, 1)) { 310 FX_Random_GenerateBase(&dwSeed, 1); 311 } 312 #else 313 FX_Random_GenerateBase(&dwSeed, 1); 314 #endif 315 void* pContext = FX_Random_MT_Start(dwSeed); 316 while (iCount-- > 0) { 317 *pBuffer++ = FX_Random_MT_Generate(pContext); 318 } 319 FX_Random_MT_Close(pContext); 320 } 321 void FX_Random_GenerateBase(FX_DWORD* pBuffer, int32_t iCount) { 322 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 323 SYSTEMTIME st1, st2; 324 ::GetSystemTime(&st1); 325 do { 326 ::GetSystemTime(&st2); 327 } while (FXSYS_memcmp(&st1, &st2, sizeof(SYSTEMTIME)) == 0); 328 FX_DWORD dwHash1 = 329 FX_HashCode_String_GetA((const FX_CHAR*)&st1, sizeof(st1), TRUE); 330 FX_DWORD dwHash2 = 331 FX_HashCode_String_GetA((const FX_CHAR*)&st2, sizeof(st2), TRUE); 332 ::srand((dwHash1 << 16) | (FX_DWORD)dwHash2); 333 #else 334 time_t tmLast = time(NULL), tmCur; 335 while ((tmCur = time(NULL)) == tmLast) 336 ; 337 ::srand((tmCur << 16) | (tmLast & 0xFFFF)); 338 #endif 339 while (iCount-- > 0) { 340 *pBuffer++ = (FX_DWORD)((::rand() << 16) | (::rand() & 0xFFFF)); 341 } 342 } 343 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 344 FX_BOOL FX_GenerateCryptoRandom(FX_DWORD* pBuffer, int32_t iCount) { 345 HCRYPTPROV hCP = NULL; 346 if (!::CryptAcquireContext(&hCP, NULL, NULL, PROV_RSA_FULL, 0) || !hCP) { 347 return FALSE; 348 } 349 ::CryptGenRandom(hCP, iCount * sizeof(FX_DWORD), (uint8_t*)pBuffer); 350 ::CryptReleaseContext(hCP, 0); 351 return TRUE; 352 } 353 #endif 354 void FX_Random_GenerateCrypto(FX_DWORD* pBuffer, int32_t iCount) { 355 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 356 FX_GenerateCryptoRandom(pBuffer, iCount); 357 #else 358 FX_Random_GenerateBase(pBuffer, iCount); 359 #endif 360 } 361 362 #ifdef PDF_ENABLE_XFA 363 void FX_GUID_CreateV4(FX_LPGUID pGUID) { 364 #if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \ 365 _FX_OS_ == _FX_WIN64_) 366 #ifdef _FX_WINAPI_PARTITION_DESKTOP_ 367 if (!FX_GenerateCryptoRandom((FX_DWORD*)pGUID, 4)) { 368 FX_Random_GenerateMT((FX_DWORD*)pGUID, 4); 369 } 370 #else 371 FX_Random_GenerateMT((FX_DWORD*)pGUID, 4); 372 #endif 373 #else 374 FX_Random_GenerateMT((FX_DWORD*)pGUID, 4); 375 #endif 376 uint8_t& b = ((uint8_t*)pGUID)[6]; 377 b = (b & 0x0F) | 0x40; 378 } 379 const FX_CHAR* gs_FX_pHexChars = "0123456789ABCDEF"; 380 void FX_GUID_ToString(FX_LPCGUID pGUID, 381 CFX_ByteString& bsStr, 382 FX_BOOL bSeparator) { 383 FX_CHAR* pBuf = bsStr.GetBuffer(40); 384 uint8_t b; 385 for (int32_t i = 0; i < 16; i++) { 386 b = ((const uint8_t*)pGUID)[i]; 387 *pBuf++ = gs_FX_pHexChars[b >> 4]; 388 *pBuf++ = gs_FX_pHexChars[b & 0x0F]; 389 if (bSeparator && (i == 3 || i == 5 || i == 7 || i == 9)) { 390 *pBuf++ = L'-'; 391 } 392 } 393 bsStr.ReleaseBuffer(bSeparator ? 36 : 32); 394 } 395 #endif // PDF_ENABLE_XFA 396