Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "fpdfsdk/javascript/util.h" | 7 #include "fpdfsdk/javascript/util.h" |
| 8 | 8 |
| 9 #include <time.h> | 9 #include <time.h> |
| 10 | 10 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 const std::vector<CJS_Value>& params, | 309 const std::vector<CJS_Value>& params, |
| 310 CJS_Value& vRet, | 310 CJS_Value& vRet, |
| 311 CFX_WideString& sError) { | 311 CFX_WideString& sError) { |
| 312 int iSize = params.size(); | 312 int iSize = params.size(); |
| 313 if (iSize < 2) | 313 if (iSize < 2) |
| 314 return FALSE; | 314 return FALSE; |
| 315 CFX_WideString sFormat = params[0].ToCFXWideString(); | 315 CFX_WideString sFormat = params[0].ToCFXWideString(); |
| 316 CFX_WideString sSource = params[1].ToCFXWideString(); | 316 CFX_WideString sSource = params[1].ToCFXWideString(); |
| 317 std::string cFormat = CFX_ByteString::FromUnicode(sFormat).c_str(); | 317 std::string cFormat = CFX_ByteString::FromUnicode(sFormat).c_str(); |
| 318 std::string cSource = CFX_ByteString::FromUnicode(sSource).c_str(); | 318 std::string cSource = CFX_ByteString::FromUnicode(sSource).c_str(); |
| 319 std::string cDest; | 319 vRet = printx(cFormat, cSource).c_str(); |
| 320 printx(cFormat, cSource, cDest); | |
| 321 vRet = cDest.c_str(); | |
| 322 return TRUE; | 320 return TRUE; |
| 323 } | 321 } |
| 324 | 322 |
| 325 void util::printx(const std::string& cFormat, | 323 enum CaseMode { kPreserveCase, kUpperCase, kLowerCase }; |
| 326 const std::string& cSource2, | 324 |
| 327 std::string& cPurpose) { | 325 static char TranslateCase(char input, CaseMode eMode) { |
| 328 std::string cSource(cSource2); | 326 if (eMode == kLowerCase && input >= 'A' && input <= 'Z') |
| 329 if (!cPurpose.empty()) | 327 return input | 0x20; |
|
dsinclair
2016/03/28 18:39:01
Why not toupper and tolower for these?
Tom Sepez
2016/03/28 19:03:41
ToUpper() isn't safe if |input| isn't an unsigned
| |
| 330 // cPurpose.clear(); | 328 if (eMode == kUpperCase && input >= 'a' && input <= 'z') |
| 331 cPurpose.erase(); | 329 return input & ~0x20; |
| 332 int itSource = 0; | 330 return input; |
| 333 int iSize = cSource.size(); | 331 } |
| 334 for (int iIndex = 0; iIndex < (int)cFormat.size() && itSource < iSize; | 332 |
| 335 iIndex++) { | 333 std::string util::printx(const std::string& cFormat, |
| 336 char letter = cFormat[iIndex]; | 334 const std::string& cSource) { |
| 337 switch (letter) { | 335 std::string cResult; |
| 338 case '?': | 336 size_t iSourceIndex = 0; |
| 339 cPurpose += cSource[itSource]; | 337 size_t iFormatIndex = 0; |
| 340 itSource++; | 338 CaseMode eCaseMode = kPreserveCase; |
| 341 break; | 339 bool bEscaped = false; |
| 340 while (iFormatIndex < cFormat.size()) { | |
| 341 if (bEscaped) { | |
| 342 bEscaped = false; | |
| 343 cResult += cFormat[iFormatIndex]; | |
| 344 ++iFormatIndex; | |
| 345 continue; | |
| 346 } | |
| 347 switch (cFormat[iFormatIndex]) { | |
| 348 case '\\': { | |
| 349 bEscaped = true; | |
| 350 ++iFormatIndex; | |
| 351 } break; | |
| 352 case '<': { | |
| 353 eCaseMode = kUpperCase; | |
|
dsinclair
2016/03/28 18:39:01
The original code did tolower for < and toupper fo
Tom Sepez
2016/03/28 19:03:41
No, I botched it. Good catch.
| |
| 354 ++iFormatIndex; | |
| 355 } break; | |
| 356 case '>': { | |
| 357 eCaseMode = kLowerCase; | |
| 358 ++iFormatIndex; | |
| 359 } break; | |
| 360 case '=': { | |
| 361 eCaseMode = kPreserveCase; | |
| 362 ++iFormatIndex; | |
| 363 } break; | |
| 364 case '?': { | |
| 365 if (iSourceIndex < cSource.size()) { | |
| 366 cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); | |
| 367 ++iSourceIndex; | |
| 368 } | |
| 369 ++iFormatIndex; | |
| 370 } break; | |
| 342 case 'X': { | 371 case 'X': { |
| 343 while (itSource < iSize) { | 372 if (iSourceIndex < cSource.size()) { |
| 344 if (std::isdigit(cSource[itSource]) || | 373 if (std::isdigit(cSource[iSourceIndex]) || |
|
Tom Sepez
2016/03/28 19:03:41
This should also be avoided due to same issue.
| |
| 345 (cSource[itSource] >= 'a' && cSource[itSource] <= 'z') || | 374 (cSource[iSourceIndex] >= 'a' && cSource[iSourceIndex] <= 'z') || |
|
dsinclair
2016/03/28 18:39:01
std::islower() and std::isupper() ?
Tom Sepez
2016/03/28 19:03:41
Same issue.
| |
| 346 (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) { | 375 (cSource[iSourceIndex] >= 'A' && cSource[iSourceIndex] <= 'Z')) { |
| 347 cPurpose += cSource[itSource]; | 376 cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| 348 itSource++; | 377 ++iFormatIndex; |
| 349 break; | |
| 350 } | 378 } |
| 351 itSource++; | 379 ++iSourceIndex; |
| 380 } else { | |
| 381 ++iFormatIndex; | |
| 352 } | 382 } |
| 353 break; | |
| 354 } break; | 383 } break; |
| 355 case 'A': { | 384 case 'A': { |
| 356 while (itSource < iSize) { | 385 if (iSourceIndex < cSource.size()) { |
| 357 if ((cSource[itSource] >= 'a' && cSource[itSource] <= 'z') || | 386 if ((cSource[iSourceIndex] >= 'a' && cSource[iSourceIndex] <= 'z') || |
|
dsinclair
2016/03/28 18:39:01
ditto
Tom Sepez
2016/03/28 19:03:41
ditto.
| |
| 358 (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) { | 387 (cSource[iSourceIndex] >= 'A' && cSource[iSourceIndex] <= 'Z')) { |
| 359 cPurpose += cSource[itSource]; | 388 cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| 360 itSource++; | 389 ++iFormatIndex; |
| 361 break; | |
| 362 } | 390 } |
| 363 itSource++; | 391 ++iSourceIndex; |
| 392 } else { | |
| 393 ++iFormatIndex; | |
| 364 } | 394 } |
| 365 break; | |
| 366 } break; | 395 } break; |
| 367 case '9': { | 396 case '9': { |
| 368 while (itSource < iSize) { | 397 if (iSourceIndex < cSource.size()) { |
| 369 if (std::isdigit(cSource[itSource])) { | 398 if (std::isdigit(cSource[iSourceIndex])) { |
| 370 cPurpose += cSource[itSource]; | 399 cResult += cSource[iSourceIndex]; |
| 371 itSource++; | 400 ++iFormatIndex; |
| 372 break; | |
| 373 } | 401 } |
| 374 itSource++; | 402 ++iSourceIndex; |
| 403 } else { | |
| 404 ++iFormatIndex; | |
| 375 } | 405 } |
| 376 break; | 406 } break; |
| 377 } | |
| 378 case '*': { | 407 case '*': { |
| 379 cPurpose.append(cSource, itSource, iSize - itSource); | 408 if (iSourceIndex < cSource.size()) { |
| 380 itSource = iSize - 1; | 409 cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| 381 break; | 410 ++iSourceIndex; |
| 382 } | 411 } else { |
| 383 case '\\': | 412 ++iFormatIndex; |
| 384 break; | 413 } |
| 385 case '>': { | 414 } break; |
| 386 for (char& c : cSource) | 415 default: { |
| 387 c = toupper(c); | 416 cResult += cFormat[iFormatIndex]; |
| 388 break; | 417 ++iFormatIndex; |
| 389 } | 418 } break; |
| 390 case '<': { | |
| 391 for (char& c : cSource) | |
| 392 c = tolower(c); | |
| 393 break; | |
| 394 } | |
| 395 case '=': | |
| 396 break; | |
| 397 default: | |
| 398 cPurpose += letter; | |
| 399 break; | |
| 400 } | 419 } |
| 401 } | 420 } |
| 421 return cResult; | |
| 402 } | 422 } |
| 403 | 423 |
| 404 FX_BOOL util::scand(IJS_Context* cc, | 424 FX_BOOL util::scand(IJS_Context* cc, |
| 405 const std::vector<CJS_Value>& params, | 425 const std::vector<CJS_Value>& params, |
| 406 CJS_Value& vRet, | 426 CJS_Value& vRet, |
| 407 CFX_WideString& sError) { | 427 CFX_WideString& sError) { |
| 408 int iSize = params.size(); | 428 int iSize = params.size(); |
| 409 if (iSize < 2) | 429 if (iSize < 2) |
| 410 return FALSE; | 430 return FALSE; |
| 411 | 431 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 432 int iSize = params.size(); | 452 int iSize = params.size(); |
| 433 if (iSize == 0) | 453 if (iSize == 0) |
| 434 return FALSE; | 454 return FALSE; |
| 435 int nByte = params[0].ToInt(); | 455 int nByte = params[0].ToInt(); |
| 436 unsigned char cByte = (unsigned char)nByte; | 456 unsigned char cByte = (unsigned char)nByte; |
| 437 CFX_WideString csValue; | 457 CFX_WideString csValue; |
| 438 csValue.Format(L"%c", cByte); | 458 csValue.Format(L"%c", cByte); |
| 439 vRet = csValue.c_str(); | 459 vRet = csValue.c_str(); |
| 440 return TRUE; | 460 return TRUE; |
| 441 } | 461 } |
| OLD | NEW |