diff options
Diffstat (limited to 'fpdfsdk')
-rw-r--r-- | fpdfsdk/src/javascript/Field.cpp | 22 | ||||
-rw-r--r-- | fpdfsdk/src/javascript/PublicMethods.cpp | 153 | ||||
-rw-r--r-- | fpdfsdk/src/javascript/PublicMethods.h | 9 |
3 files changed, 156 insertions, 28 deletions
diff --git a/fpdfsdk/src/javascript/Field.cpp b/fpdfsdk/src/javascript/Field.cpp index ebd3d331f5..959e8dcadd 100644 --- a/fpdfsdk/src/javascript/Field.cpp +++ b/fpdfsdk/src/javascript/Field.cpp @@ -2741,8 +2741,13 @@ FX_BOOL Field::value(IJS_Context* cc, CFX_WideString swValue = pFormField->GetValue(); double dRet; - if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet)) { - vp << dRet; + FX_BOOL bDot; + if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet, + bDot)) { + if (bDot) + vp << dRet; + else + vp << dRet; } else { vp << swValue; } @@ -2764,8 +2769,13 @@ FX_BOOL Field::value(IJS_Context* cc, CFX_WideString swValue = pFormField->GetValue(); double dRet; - if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet)) { - vp << dRet; + FX_BOOL bDot; + if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet, + bDot)) { + if (bDot) + vp << dRet; + else + vp << dRet; } else { vp << swValue; } @@ -2780,7 +2790,9 @@ FX_BOOL Field::value(IJS_Context* cc, CFX_WideString swValue = pFormField->GetControl(i)->GetExportValue(); double dRet; - if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet)) { + FX_BOOL bDotDummy; + if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet, + bDotDummy)) { vp << dRet; } else { vp << swValue; diff --git a/fpdfsdk/src/javascript/PublicMethods.cpp b/fpdfsdk/src/javascript/PublicMethods.cpp index 9e5ad5d182..d2f7fb09ac 100644 --- a/fpdfsdk/src/javascript/PublicMethods.cpp +++ b/fpdfsdk/src/javascript/PublicMethods.cpp @@ -194,38 +194,147 @@ CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) { return StrRTrim(StrLTrim(pStr)); } -FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource, - double& dRet) { - CFX_ByteString sDigits = CFX_WideString(swSource).UTF8Encode(); +double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource, + FX_BOOL& bAllDigits, + FX_BOOL& bDot, + FX_BOOL& bSign, + FX_BOOL& bKXJS) { + bDot = FALSE; + bSign = FALSE; + bKXJS = FALSE; + + FX_BOOL bDigitExist = FALSE; + + const FX_WCHAR* p = swSource; + wchar_t c; - // Always interpret "," as "." independent of the locale. - for (FX_STRSIZE k = 0; k < sDigits.GetLength(); k++) { - if (sDigits[k] == ',') - sDigits.SetAt(k, '.'); + const FX_WCHAR* pStart = NULL; + const FX_WCHAR* pEnd = NULL; + + while ((c = *p)) { + if (!pStart && c != L' ') { + pStart = p; + } + + pEnd = p; + p++; } - // Parse a number, ignoring leading and trailing whitespace. - // Fail if there is trailing garbage. - const char* pStart = sDigits.c_str(); - const char* pEnd = NULL; - dRet = strtod(pStart, const_cast<char**>(&pEnd)); - if (pEnd == pStart) { - return FALSE; + if (!pStart) { + bAllDigits = FALSE; + return 0; } - for (; *pEnd; pEnd++) { - if (!isspace(*pEnd)) { - dRet = 0; - return FALSE; + + while (pEnd != pStart) { + if (*pEnd == L' ') + pEnd--; + else + break; + } + + double dRet = 0; + p = pStart; + bAllDigits = TRUE; + CFX_WideString swDigits; + + while (p <= pEnd) { + c = *p; + + if (FXSYS_iswdigit(c)) { + swDigits += c; + bDigitExist = TRUE; + } else { + switch (c) { + case L' ': + bAllDigits = FALSE; + break; + case L'.': + case L',': + if (!bDot) { + if (bDigitExist) { + swDigits += L'.'; + } else { + swDigits += L'0'; + swDigits += L'.'; + bDigitExist = TRUE; + } + + bDot = TRUE; + break; + } + case 'e': + case 'E': + if (!bKXJS) { + p++; + c = *p; + if (c == '+' || c == '-') { + bKXJS = TRUE; + swDigits += 'e'; + swDigits += c; + } + break; + } + case L'-': + if (!bDigitExist && !bSign) { + swDigits += c; + bSign = TRUE; + break; + } + default: + bAllDigits = FALSE; + + if (p != pStart && !bDot && bDigitExist) { + swDigits += L'.'; + bDot = TRUE; + } else { + bDot = FALSE; + bDigitExist = FALSE; + swDigits = L""; + } + break; + } } + + p++; } - return TRUE; + if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) { + CFX_ByteString sDigits = swDigits.UTF8Encode(); + + if (bKXJS) { + dRet = atof(sDigits); + } else { + if (bDot) { + char* pStopString; + dRet = ::strtod(sDigits, &pStopString); + } else { + dRet = atol(sDigits); + } + } + } + + return dRet; } double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) { - double dRet; - ConvertStringToNumber(swSource, dRet); - return dRet; + FX_BOOL bAllDigits = FALSE; + FX_BOOL bDot = FALSE; + FX_BOOL bSign = FALSE; + FX_BOOL bKXJS = FALSE; + + return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS); +} + +FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource, + double& dRet, + FX_BOOL& bDot) { + FX_BOOL bAllDigits = FALSE; + FX_BOOL bSign = FALSE; + FX_BOOL bKXJS = FALSE; + + dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS); + + return bAllDigits; } CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime, diff --git a/fpdfsdk/src/javascript/PublicMethods.h b/fpdfsdk/src/javascript/PublicMethods.h index 0172cbafb8..013c4ce1a4 100644 --- a/fpdfsdk/src/javascript/PublicMethods.h +++ b/fpdfsdk/src/javascript/PublicMethods.h @@ -144,11 +144,18 @@ class CJS_PublicMethods : public CJS_Object { bool* bWrongFormat); static CFX_WideString MakeFormatDate(double dDate, const CFX_WideString& format); - static FX_BOOL ConvertStringToNumber(const FX_WCHAR* swSource, double& dRet); + static FX_BOOL ConvertStringToNumber(const FX_WCHAR* swSource, + double& dRet, + FX_BOOL& bDot); static double ParseStringToNumber(const FX_WCHAR* swSource); static double ParseNormalDate(const CFX_WideString& value, bool* bWrongFormat); static double MakeInterDate(CFX_WideString strValue); + static double ParseNumber(const FX_WCHAR* swSource, + FX_BOOL& bAllDigits, + FX_BOOL& bDot, + FX_BOOL& bSign, + FX_BOOL& bKXJS); public: static CFX_WideString StrLTrim(const FX_WCHAR* pStr); |