summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2016-01-14 17:35:04 -0800
committerTom Sepez <tsepez@chromium.org>2016-01-14 17:35:04 -0800
commit283ef3c9292889ef7d53e9e451f9272d4efb0221 (patch)
tree98a868a584f13538e24a12e070c55d659086c48b
parent4cd5b80e70e5fc50d8bd805cfa3c7b54878a0a35 (diff)
downloadpdfium-283ef3c9292889ef7d53e9e451f9272d4efb0221.tar.xz
Revert "Cleanup CJS_PublicMethods::ParseNumber"
This reverts commit 4cd5b80e70e5fc50d8bd805cfa3c7b54878a0a35. Reason for revert: broke tests on windows TBR=tombergan@chromium.org TBR=thestig@chromium.org Review URL: https://codereview.chromium.org/1573243016 .
-rw-r--r--fpdfsdk/src/javascript/Field.cpp22
-rw-r--r--fpdfsdk/src/javascript/PublicMethods.cpp153
-rw-r--r--fpdfsdk/src/javascript/PublicMethods.h9
-rw-r--r--testing/resources/javascript/bug_361_expected.txt32
4 files changed, 172 insertions, 44 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);
diff --git a/testing/resources/javascript/bug_361_expected.txt b/testing/resources/javascript/bug_361_expected.txt
index da9256277f..f7f7a562bb 100644
--- a/testing/resources/javascript/bug_361_expected.txt
+++ b/testing/resources/javascript/bug_361_expected.txt
@@ -12,31 +12,31 @@ Alert: Answer for " 4
Alert: Answer for "4 3 2 1" is: string 4 3 2 1
Alert: Answer for "-4" is: number -4
Alert: Answer for "23.00000001" is: number 23.00000001
-Alert: Answer for "23.00000000000000001" is: number 23
+Alert: Answer for "23.00000000000000001" is: number 0
Alert: Answer for "4e+25" is: number 4e+25
-Alert: Answer for "40000000000000000000000000" is: number 4e+25
+Alert: Answer for "40000000000000000000000000" is: number 0
Alert: Answer for "25,5" is: number 25.5
Alert: Answer for "1e+5" is: number 100000
-Alert: Answer for "1e5" is: number 100000
+Alert: Answer for "1e5" is: number 1
Alert: Answer for "1e-5" is: number 0.00001
Alert: Answer for "-1e-5" is: number -0.00001
-Alert: Answer for "1.2e5" is: number 120000
-Alert: Answer for "Infinity" is: number Infinity
-Alert: Answer for "Infinity" is: number Infinity
-Alert: Answer for "INFINITY" is: number Infinity
-Alert: Answer for "INF" is: number Infinity
-Alert: Answer for "NaN" is: number NaN
-Alert: Answer for "NaN" is: number NaN
-Alert: Answer for "NAN" is: number NaN
-Alert: Answer for "0x100" is: number 256
-Alert: Answer for "0x100.1" is: number 256.0625
-Alert: Answer for "0x100,1" is: number 256.0625
+Alert: Answer for "1.2e5" is: number 1.2
+Alert: Answer for "Infinity" is: string Infinity
+Alert: Answer for "Infinity" is: string Infinity
+Alert: Answer for "INFINITY" is: string INFINITY
+Alert: Answer for "INF" is: string INF
+Alert: Answer for "NaN" is: string NaN
+Alert: Answer for "NaN" is: string NaN
+Alert: Answer for "NAN" is: string NAN
+Alert: Answer for "0x100" is: string 0x100
+Alert: Answer for "0x100.1" is: string 0x100.1
+Alert: Answer for "0x100,1" is: string 0x100,1
Alert: Answer for "0x100x1" is: string 0x100x1
Alert: Answer for "123x6" is: string 123x6
Alert: Answer for "123xy6" is: string 123xy6
Alert: Answer for "123.y6" is: string 123.y6
-Alert: Answer for "1,000,000" is: string 1,000,000
-Alert: Answer for "1.2.3" is: string 1.2.3
+Alert: Answer for "1,000,000" is: number 1
+Alert: Answer for "1.2.3" is: number 1.2
Alert: Answer for "1-3" is: string 1-3
Alert: Answer for "1+3" is: string 1+3
Alert: Answer for "1.-3" is: string 1.-3