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 |