summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlocale_tools.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-04 12:01:08 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-04 17:32:12 +0000
commit59dbf1786f22ec4ac88d8f9d38cac5cfb82acaea (patch)
treee0e73b31a47cb5f9eb497945727d54a7e55ff445 /src/corelib/tools/qlocale_tools.cpp
parenta926f675be220ca6020039ac3640991b63a0fae7 (diff)
QLocale: Return overflowing numbers from asciiToDouble()
The behavior from before libdouble-conversion is that in case of an overflow the OK flag is set to false, but the returned number is still infinity, rather than 0. Also, the number of processed characters is always set to the number of characters actually processed, unless garbage is found. There is an important distinction between an overflow and garbage. The client code may accept overflows and infinity may be a valid result. Garbage is most certainly not acceptable. Having an infinity/false result in addition to 0/false allows the client code to distinguish those. One application where this is useful is parsing JavaScript. Change-Id: I4b8581568144b44fca3353c4bd9685c702762af9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qlocale_tools.cpp')
-rw-r--r--src/corelib/tools/qlocale_tools.cpp36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 33b0530d05..18d1096c12 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -303,31 +303,51 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed)
d = conv.StringToDouble(num, numLen, &processed);
if (!qIsFinite(d)) {
- processed = 0;
ok = false;
- return 0.0;
+ if (qIsNaN(d)) {
+ // Garbage found. We don't accept it and return 0.
+ processed = 0;
+ return 0.0;
+ } else {
+ // Overflow. That's not OK, but we still return infinity.
+ return d;
+ }
}
-
- Q_ASSERT(processed == numLen); // Otherwise we would have gotten NaN
#else
if (qDoubleSscanf(num, QT_CLOCALE, "%lf%n", &d, &processed) < 1)
processed = 0;
- if (processed != numLen || !qIsFinite(d)) {
- // We stopped at a non-digit character after converting some digits
- // or we found an implementation-defined symbol for infinity or nan, which we don't accept.
+ if (processed != numLen || qIsNaN(d)) {
+ // Implementation defined nan symbol or garbage found. We don't accept it.
processed = 0;
ok = false;
return 0.0;
}
+
+ if (!qIsFinite(d)) {
+ // Overflow. Check for implementation-defined infinity symbols and reject them.
+ // We assume that any infinity symbol has to contain a character that cannot be part of a
+ // "normal" number (that is 0-9, ., -, +, e).
+ ok = false;
+ for (int i = 0; i < numLen; ++i) {
+ char c = num[i];
+ if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e') {
+ // Garbage found
+ processed = 0;
+ return 0.0;
+ }
+ }
+ return d;
+ }
#endif // !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
+ Q_ASSERT(processed == numLen); // Otherwise we would have gotten NaN or sorted it out above.
+
// Check if underflow has occurred.
if (isZero(d)) {
for (int i = 0; i < numLen; ++i) {
if (num[i] >= '1' && num[i] <= '9') {
// if a digit before any 'e' is not 0, then a non-zero number was intended.
- processed = 0;
ok = false;
return 0.0;
} else if (num[i] == 'e') {