summaryrefslogtreecommitdiff
path: root/fpdfsdk
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2016-01-14 17:25:08 -0800
committerTom Sepez <tsepez@chromium.org>2016-01-14 17:25:08 -0800
commit4cd5b80e70e5fc50d8bd805cfa3c7b54878a0a35 (patch)
treecb9465e37aa1495d01adbed07d351ab36930e8e2 /fpdfsdk
parent5b2bc895384749493f2ec2ca818c485797448cae (diff)
downloadpdfium-4cd5b80e70e5fc50d8bd805cfa3c7b54878a0a35.tar.xz
Cleanup CJS_PublicMethods::ParseNumber
Original patch by tombergan. The old version of this function was basically strtod with a few quirks: 1. It always interpreted ',' as '.' independent of locale. I kept this behavior, to be conservative. 2. It interpreted the first non-number character as a decimal point, unless there was a prior decimal point, in which case all characters up to that point are ignored. This would parse "123z4" as "123.4" and "123xy6" as "6". I did not keep this behavior -- in the new code, these examples all fail to parse. The new ParseNumber was inlined into ConvertStringToNumber, which returns true on success and (false, 0) on failure. BUG=pdfium:361 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1582013002 .
Diffstat (limited to 'fpdfsdk')
-rw-r--r--fpdfsdk/src/javascript/Field.cpp22
-rw-r--r--fpdfsdk/src/javascript/PublicMethods.cpp153
-rw-r--r--fpdfsdk/src/javascript/PublicMethods.h9
3 files changed, 28 insertions, 156 deletions
diff --git a/fpdfsdk/src/javascript/Field.cpp b/fpdfsdk/src/javascript/Field.cpp
index 959e8dcadd..ebd3d331f5 100644
--- a/fpdfsdk/src/javascript/Field.cpp
+++ b/fpdfsdk/src/javascript/Field.cpp
@@ -2741,13 +2741,8 @@ FX_BOOL Field::value(IJS_Context* cc,
CFX_WideString swValue = pFormField->GetValue();
double dRet;
- FX_BOOL bDot;
- if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet,
- bDot)) {
- if (bDot)
- vp << dRet;
- else
- vp << dRet;
+ if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet)) {
+ vp << dRet;
} else {
vp << swValue;
}
@@ -2769,13 +2764,8 @@ FX_BOOL Field::value(IJS_Context* cc,
CFX_WideString swValue = pFormField->GetValue();
double dRet;
- FX_BOOL bDot;
- if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet,
- bDot)) {
- if (bDot)
- vp << dRet;
- else
- vp << dRet;
+ if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet)) {
+ vp << dRet;
} else {
vp << swValue;
}
@@ -2790,9 +2780,7 @@ FX_BOOL Field::value(IJS_Context* cc,
CFX_WideString swValue = pFormField->GetControl(i)->GetExportValue();
double dRet;
- FX_BOOL bDotDummy;
- if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet,
- bDotDummy)) {
+ if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet)) {
vp << dRet;
} else {
vp << swValue;
diff --git a/fpdfsdk/src/javascript/PublicMethods.cpp b/fpdfsdk/src/javascript/PublicMethods.cpp
index d2f7fb09ac..9e5ad5d182 100644
--- a/fpdfsdk/src/javascript/PublicMethods.cpp
+++ b/fpdfsdk/src/javascript/PublicMethods.cpp
@@ -194,147 +194,38 @@ CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
return StrRTrim(StrLTrim(pStr));
}
-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;
-
- const FX_WCHAR* pStart = NULL;
- const FX_WCHAR* pEnd = NULL;
-
- while ((c = *p)) {
- if (!pStart && c != L' ') {
- pStart = p;
- }
-
- pEnd = p;
- p++;
- }
-
- if (!pStart) {
- bAllDigits = FALSE;
- return 0;
- }
+FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
+ double& dRet) {
+ CFX_ByteString sDigits = CFX_WideString(swSource).UTF8Encode();
- while (pEnd != pStart) {
- if (*pEnd == L' ')
- pEnd--;
- else
- break;
+ // Always interpret "," as "." independent of the locale.
+ for (FX_STRSIZE k = 0; k < sDigits.GetLength(); k++) {
+ if (sDigits[k] == ',')
+ sDigits.SetAt(k, '.');
}
- 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++;
+ // 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 (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);
- }
+ for (; *pEnd; pEnd++) {
+ if (!isspace(*pEnd)) {
+ dRet = 0;
+ return FALSE;
}
}
- return dRet;
+ return TRUE;
}
double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
- 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;
+ double dRet;
+ ConvertStringToNumber(swSource, dRet);
+ return dRet;
}
CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
diff --git a/fpdfsdk/src/javascript/PublicMethods.h b/fpdfsdk/src/javascript/PublicMethods.h
index 013c4ce1a4..0172cbafb8 100644
--- a/fpdfsdk/src/javascript/PublicMethods.h
+++ b/fpdfsdk/src/javascript/PublicMethods.h
@@ -144,18 +144,11 @@ 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,
- FX_BOOL& bDot);
+ static FX_BOOL ConvertStringToNumber(const FX_WCHAR* swSource, double& dRet);
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);