Chromium Code Reviews| Index: fpdfsdk/javascript/util.cpp |
| diff --git a/fpdfsdk/javascript/util.cpp b/fpdfsdk/javascript/util.cpp |
| index 30656cd76659c3f8176abd077fcbb1c182a55efc..671a862964452fbb497535f945b06bdb5023c43b 100644 |
| --- a/fpdfsdk/javascript/util.cpp |
| +++ b/fpdfsdk/javascript/util.cpp |
| @@ -316,89 +316,109 @@ FX_BOOL util::printx(IJS_Context* cc, |
| CFX_WideString sSource = params[1].ToCFXWideString(); |
| std::string cFormat = CFX_ByteString::FromUnicode(sFormat).c_str(); |
| std::string cSource = CFX_ByteString::FromUnicode(sSource).c_str(); |
| - std::string cDest; |
| - printx(cFormat, cSource, cDest); |
| - vRet = cDest.c_str(); |
| + vRet = printx(cFormat, cSource).c_str(); |
| return TRUE; |
| } |
| -void util::printx(const std::string& cFormat, |
| - const std::string& cSource2, |
| - std::string& cPurpose) { |
| - std::string cSource(cSource2); |
| - if (!cPurpose.empty()) |
| - // cPurpose.clear(); |
| - cPurpose.erase(); |
| - int itSource = 0; |
| - int iSize = cSource.size(); |
| - for (int iIndex = 0; iIndex < (int)cFormat.size() && itSource < iSize; |
| - iIndex++) { |
| - char letter = cFormat[iIndex]; |
| - switch (letter) { |
| - case '?': |
| - cPurpose += cSource[itSource]; |
| - itSource++; |
| - break; |
| +enum CaseMode { kPreserveCase, kUpperCase, kLowerCase }; |
| + |
| +static char TranslateCase(char input, CaseMode eMode) { |
| + if (eMode == kLowerCase && input >= 'A' && input <= 'Z') |
| + 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
|
| + if (eMode == kUpperCase && input >= 'a' && input <= 'z') |
| + return input & ~0x20; |
| + return input; |
| +} |
| + |
| +std::string util::printx(const std::string& cFormat, |
| + const std::string& cSource) { |
| + std::string cResult; |
| + size_t iSourceIndex = 0; |
| + size_t iFormatIndex = 0; |
| + CaseMode eCaseMode = kPreserveCase; |
| + bool bEscaped = false; |
| + while (iFormatIndex < cFormat.size()) { |
| + if (bEscaped) { |
| + bEscaped = false; |
| + cResult += cFormat[iFormatIndex]; |
| + ++iFormatIndex; |
| + continue; |
| + } |
| + switch (cFormat[iFormatIndex]) { |
| + case '\\': { |
| + bEscaped = true; |
| + ++iFormatIndex; |
| + } break; |
| + case '<': { |
| + 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.
|
| + ++iFormatIndex; |
| + } break; |
| + case '>': { |
| + eCaseMode = kLowerCase; |
| + ++iFormatIndex; |
| + } break; |
| + case '=': { |
| + eCaseMode = kPreserveCase; |
| + ++iFormatIndex; |
| + } break; |
| + case '?': { |
| + if (iSourceIndex < cSource.size()) { |
| + cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| + ++iSourceIndex; |
| + } |
| + ++iFormatIndex; |
| + } break; |
| case 'X': { |
| - while (itSource < iSize) { |
| - if (std::isdigit(cSource[itSource]) || |
| - (cSource[itSource] >= 'a' && cSource[itSource] <= 'z') || |
| - (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) { |
| - cPurpose += cSource[itSource]; |
| - itSource++; |
| - break; |
| + if (iSourceIndex < cSource.size()) { |
| + if (std::isdigit(cSource[iSourceIndex]) || |
|
Tom Sepez
2016/03/28 19:03:41
This should also be avoided due to same issue.
|
| + (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.
|
| + (cSource[iSourceIndex] >= 'A' && cSource[iSourceIndex] <= 'Z')) { |
| + cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| + ++iFormatIndex; |
| } |
| - itSource++; |
| + ++iSourceIndex; |
| + } else { |
| + ++iFormatIndex; |
| } |
| - break; |
| } break; |
| case 'A': { |
| - while (itSource < iSize) { |
| - if ((cSource[itSource] >= 'a' && cSource[itSource] <= 'z') || |
| - (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) { |
| - cPurpose += cSource[itSource]; |
| - itSource++; |
| - break; |
| + if (iSourceIndex < cSource.size()) { |
| + if ((cSource[iSourceIndex] >= 'a' && cSource[iSourceIndex] <= 'z') || |
|
dsinclair
2016/03/28 18:39:01
ditto
Tom Sepez
2016/03/28 19:03:41
ditto.
|
| + (cSource[iSourceIndex] >= 'A' && cSource[iSourceIndex] <= 'Z')) { |
| + cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| + ++iFormatIndex; |
| } |
| - itSource++; |
| + ++iSourceIndex; |
| + } else { |
| + ++iFormatIndex; |
| } |
| - break; |
| } break; |
| case '9': { |
| - while (itSource < iSize) { |
| - if (std::isdigit(cSource[itSource])) { |
| - cPurpose += cSource[itSource]; |
| - itSource++; |
| - break; |
| + if (iSourceIndex < cSource.size()) { |
| + if (std::isdigit(cSource[iSourceIndex])) { |
| + cResult += cSource[iSourceIndex]; |
| + ++iFormatIndex; |
| } |
| - itSource++; |
| + ++iSourceIndex; |
| + } else { |
| + ++iFormatIndex; |
| } |
| - break; |
| - } |
| + } break; |
| case '*': { |
| - cPurpose.append(cSource, itSource, iSize - itSource); |
| - itSource = iSize - 1; |
| - break; |
| - } |
| - case '\\': |
| - break; |
| - case '>': { |
| - for (char& c : cSource) |
| - c = toupper(c); |
| - break; |
| - } |
| - case '<': { |
| - for (char& c : cSource) |
| - c = tolower(c); |
| - break; |
| - } |
| - case '=': |
| - break; |
| - default: |
| - cPurpose += letter; |
| - break; |
| + if (iSourceIndex < cSource.size()) { |
| + cResult += TranslateCase(cSource[iSourceIndex], eCaseMode); |
| + ++iSourceIndex; |
| + } else { |
| + ++iFormatIndex; |
| + } |
| + } break; |
| + default: { |
| + cResult += cFormat[iFormatIndex]; |
| + ++iFormatIndex; |
| + } break; |
| } |
| } |
| + return cResult; |
| } |
| FX_BOOL util::scand(IJS_Context* cc, |