1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qlocale_tools_p.h"
42 #include "qdoublescanprint_p.h"
43 #include "qlocale_p.h"
44 #include "qstring.h"
45 
46 #include <private/qnumeric_p.h>
47 
48 #include <ctype.h>
49 #include <errno.h>
50 #include <float.h>
51 #include <limits.h>
52 #include <math.h>
53 #include <stdlib.h>
54 #include <time.h>
55 
56 #if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
57 #    include <fenv.h>
58 #endif
59 
60 // Sizes as defined by the ISO C99 standard - fallback
61 #ifndef LLONG_MAX
62 #   define LLONG_MAX Q_INT64_C(0x7fffffffffffffff)
63 #endif
64 #ifndef LLONG_MIN
65 #   define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1))
66 #endif
67 #ifndef ULLONG_MAX
68 #   define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff)
69 #endif
70 
71 QT_BEGIN_NAMESPACE
72 
73 QT_WARNING_PUSH
74     /* "unary minus operator applied to unsigned type, result still unsigned" */
75 QT_WARNING_DISABLE_MSVC(4146)
76 #include "../../3rdparty/freebsd/strtoull.c"
77 #include "../../3rdparty/freebsd/strtoll.c"
78 QT_WARNING_POP
79 
80 QT_CLOCALE_HOLDER
81 
qt_doubleToAscii(double d,QLocaleData::DoubleForm form,int precision,char * buf,int bufSize,bool & sign,int & length,int & decpt)82 void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
83                       bool &sign, int &length, int &decpt)
84 {
85     if (bufSize == 0) {
86         decpt = 0;
87         sign = d < 0;
88         length = 0;
89         return;
90     }
91 
92     // Detect special numbers (nan, +/-inf)
93     // We cannot use the high-level API of libdouble-conversion as we need to apply locale-specific
94     // formatting, such as decimal points, thousands-separators, etc. Because of this, we have to
95     // check for infinity and NaN before calling DoubleToAscii.
96     if (qt_is_inf(d)) {
97         sign = d < 0;
98         if (bufSize >= 3) {
99             buf[0] = 'i';
100             buf[1] = 'n';
101             buf[2] = 'f';
102             length = 3;
103         } else {
104             length = 0;
105         }
106         return;
107     } else if (qt_is_nan(d)) {
108         if (bufSize >= 3) {
109             buf[0] = 'n';
110             buf[1] = 'a';
111             buf[2] = 'n';
112             length = 3;
113         } else {
114             length = 0;
115         }
116         return;
117     }
118 
119     if (form == QLocaleData::DFSignificantDigits && precision == 0)
120         precision = 1; // 0 significant digits is silently converted to 1
121 
122 #if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
123     // one digit before the decimal dot, counts as significant digit for DoubleToStringConverter
124     if (form == QLocaleData::DFExponent && precision >= 0)
125         ++precision;
126 
127     double_conversion::DoubleToStringConverter::DtoaMode mode;
128     if (precision == QLocale::FloatingPointShortest) {
129         mode = double_conversion::DoubleToStringConverter::SHORTEST;
130     } else if (form == QLocaleData::DFSignificantDigits || form == QLocaleData::DFExponent) {
131         mode = double_conversion::DoubleToStringConverter::PRECISION;
132     } else {
133         mode = double_conversion::DoubleToStringConverter::FIXED;
134     }
135     double_conversion::DoubleToStringConverter::DoubleToAscii(d, mode, precision, buf, bufSize,
136                                                               &sign, &length, &decpt);
137 #else // QT_NO_DOUBLECONVERSION || QT_BOOTSTRAPPED
138 
139     // Cut the precision at 999, to fit it into the format string. We can't get more than 17
140     // significant digits, so anything after that is mostly noise. You do get closer to the "middle"
141     // of the range covered by the given double with more digits, so to a degree it does make sense
142     // to honor higher precisions. We define that at more than 999 digits that is not the case.
143     if (precision > 999)
144         precision = 999;
145     else if (precision == QLocale::FloatingPointShortest)
146         precision = QLocaleData::DoubleMaxSignificant; // "shortest" mode not supported by snprintf
147 
148     if (isZero(d)) {
149         // Negative zero is expected as simple "0", not "-0". We cannot do d < 0, though.
150         sign = false;
151         buf[0] = '0';
152         length = 1;
153         decpt = 1;
154         return;
155     } else if (d < 0) {
156         sign = true;
157         d = -d;
158     } else {
159         sign = false;
160     }
161 
162     const int formatLength = 7; // '%', '.', 3 digits precision, 'f', '\0'
163     char format[formatLength];
164     format[formatLength - 1] = '\0';
165     format[0] = '%';
166     format[1] = '.';
167     format[2] = char((precision / 100) % 10) + '0';
168     format[3] = char((precision / 10) % 10)  + '0';
169     format[4] = char(precision % 10)  + '0';
170     int extraChars;
171     switch (form) {
172     case QLocaleData::DFDecimal:
173         format[formatLength - 2] = 'f';
174         // <anything> '.' <precision> '\0' - optimize for numbers smaller than 512k
175         extraChars = (d > (1 << 19) ? QLocaleData::DoubleMaxDigitsBeforeDecimal : 6) + 2;
176         break;
177     case QLocaleData::DFExponent:
178         format[formatLength - 2] = 'e';
179         // '.', 'e', '-', <exponent> '\0'
180         extraChars = 7;
181         break;
182     case QLocaleData::DFSignificantDigits:
183         format[formatLength - 2] = 'g';
184 
185         // either the same as in the 'e' case, or '.' and '\0'
186         // precision covers part before '.'
187         extraChars = 7;
188         break;
189     default:
190         Q_UNREACHABLE();
191     }
192 
193     QVarLengthArray<char> target(precision + extraChars);
194 
195     length = qDoubleSnprintf(target.data(), target.size(), QT_CLOCALE, format, d);
196     int firstSignificant = 0;
197     int decptInTarget = length;
198 
199     // Find the first significant digit (not 0), and note any '.' we encounter.
200     // There is no '-' at the front of target because we made sure d > 0 above.
201     while (firstSignificant < length) {
202         if (target[firstSignificant] == '.')
203             decptInTarget = firstSignificant;
204         else if (target[firstSignificant] != '0')
205             break;
206         ++firstSignificant;
207     }
208 
209     // If no '.' found so far, search the rest of the target buffer for it.
210     if (decptInTarget == length)
211         decptInTarget = std::find(target.data() + firstSignificant, target.data() + length, '.') -
212                 target.data();
213 
214     int eSign = length;
215     if (form != QLocaleData::DFDecimal) {
216         // In 'e' or 'g' form, look for the 'e'.
217         eSign = std::find(target.data() + firstSignificant, target.data() + length, 'e') -
218                 target.data();
219 
220         if (eSign < length) {
221             // If 'e' is found, the final decimal point is determined by the number after 'e'.
222             // Mind that the final decimal point, decpt, is the offset of the decimal point from the
223             // start of the resulting string in buf. It may be negative or larger than bufSize, in
224             // which case the missing digits are zeroes. In the 'e' case decptInTarget is always 1,
225             // as variants of snprintf always generate numbers with one digit before the '.' then.
226             // This is why the final decimal point is offset by 1, relative to the number after 'e'.
227             bool ok;
228             const char *endptr;
229             decpt = qstrtoll(target.data() + eSign + 1, &endptr, 10, &ok) + 1;
230             Q_ASSERT(ok);
231             Q_ASSERT(endptr - target.data() <= length);
232         } else {
233             // No 'e' found, so it's the 'f' form. Variants of snprintf generate numbers with
234             // potentially multiple digits before the '.', but without decimal exponent then. So we
235             // get the final decimal point from the position of the '.'. The '.' itself takes up one
236             // character. We adjust by 1 below if that gets in the way.
237             decpt = decptInTarget - firstSignificant;
238         }
239     } else {
240         // In 'f' form, there can not be an 'e', so it's enough to look for the '.'
241         // (and possibly adjust by 1 below)
242         decpt = decptInTarget - firstSignificant;
243     }
244 
245     // Move the actual digits from the snprintf target to the actual buffer.
246     if (decptInTarget > firstSignificant) {
247         // First move the digits before the '.', if any
248         int lengthBeforeDecpt = decptInTarget - firstSignificant;
249         memcpy(buf, target.data() + firstSignificant, qMin(lengthBeforeDecpt, bufSize));
250         if (eSign > decptInTarget && lengthBeforeDecpt < bufSize) {
251             // Then move any remaining digits, until 'e'
252             memcpy(buf + lengthBeforeDecpt, target.data() + decptInTarget + 1,
253                    qMin(eSign - decptInTarget - 1, bufSize - lengthBeforeDecpt));
254             // The final length of the output is the distance between the first significant digit
255             // and 'e' minus 1, for the '.', except if the buffer is smaller.
256             length = qMin(eSign - firstSignificant - 1, bufSize);
257         } else {
258             // 'e' was before the decpt or things didn't fit. Don't subtract the '.' from the length.
259             length = qMin(eSign - firstSignificant, bufSize);
260         }
261     } else {
262         if (eSign > firstSignificant) {
263             // If there are any significant digits at all, they are all after the '.' now.
264             // Just copy them straight away.
265             memcpy(buf, target.data() + firstSignificant, qMin(eSign - firstSignificant, bufSize));
266 
267             // The decimal point was before the first significant digit, so we were one off above.
268             // Consider 0.1 - buf will be just '1', and decpt should be 0. But
269             // "decptInTarget - firstSignificant" will yield -1.
270             ++decpt;
271             length = qMin(eSign - firstSignificant, bufSize);
272         } else {
273             // No significant digits means the number is just 0.
274             buf[0] = '0';
275             length = 1;
276             decpt = 1;
277         }
278     }
279 #endif // QT_NO_DOUBLECONVERSION || QT_BOOTSTRAPPED
280     while (length > 1 && buf[length - 1] == '0') // drop trailing zeroes
281         --length;
282 }
283 
qt_asciiToDouble(const char * num,int numLen,bool & ok,int & processed,StrayCharacterMode strayCharMode)284 double qt_asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
285                         StrayCharacterMode strayCharMode)
286 {
287     auto string_equals = [](const char *needle, const char *haystack, qsizetype haystackLen) {
288         qsizetype needleLen = strlen(needle);
289         return needleLen == haystackLen && memcmp(needle, haystack, haystackLen) == 0;
290     };
291 
292     if (*num == '\0') {
293         ok = false;
294         processed = 0;
295         return 0.0;
296     }
297 
298     ok = true;
299 
300     // We have to catch NaN before because we need NaN as marker for "garbage" in the
301     // libdouble-conversion case and, in contrast to libdouble-conversion or sscanf, we don't allow
302     // "-nan" or "+nan"
303     if (string_equals("nan", num, numLen)) {
304         processed = 3;
305         return qt_qnan();
306     } else if (string_equals("+nan", num, numLen) || string_equals("-nan", num, numLen)) {
307         processed = 0;
308         ok = false;
309         return 0.0;
310     }
311 
312     // Infinity values are implementation defined in the sscanf case. In the libdouble-conversion
313     // case we need infinity as overflow marker.
314     if (string_equals("+inf", num, numLen)) {
315         processed = 4;
316         return qt_inf();
317     } else if (string_equals("inf", num, numLen)) {
318         processed = 3;
319         return qt_inf();
320     } else if (string_equals("-inf", num, numLen)) {
321         processed = 4;
322         return -qt_inf();
323     }
324 
325     double d = 0.0;
326 #if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
327     int conv_flags = double_conversion::StringToDoubleConverter::NO_FLAGS;
328     if (strayCharMode == TrailingJunkAllowed) {
329         conv_flags = double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK;
330     } else if (strayCharMode == WhitespacesAllowed) {
331         conv_flags = double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES
332                 | double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES;
333     }
334     double_conversion::StringToDoubleConverter conv(conv_flags, 0.0, qt_qnan(), nullptr, nullptr);
335     d = conv.StringToDouble(num, numLen, &processed);
336 
337     if (!qIsFinite(d)) {
338         ok = false;
339         if (qIsNaN(d)) {
340             // Garbage found. We don't accept it and return 0.
341             processed = 0;
342             return 0.0;
343         } else {
344             // Overflow. That's not OK, but we still return infinity.
345             return d;
346         }
347     }
348 #else
349     // need to ensure that our input is null-terminated for sscanf
350     // (this is a QVarLengthArray<char, 128> but this code here is too low-level for QVLA)
351     char reasonableBuffer[128];
352     char *buffer;
353     if (numLen < qsizetype(sizeof(reasonableBuffer)) - 1)
354         buffer = reasonableBuffer;
355     else
356         buffer = static_cast<char *>(malloc(numLen + 1));
357     memcpy(buffer, num, numLen);
358     buffer[numLen] = '\0';
359 
360     if (qDoubleSscanf(buffer, QT_CLOCALE, "%lf%n", &d, &processed) < 1)
361         processed = 0;
362 
363     if (buffer != reasonableBuffer)
364         free(buffer);
365 
366     if ((strayCharMode == TrailingJunkProhibited && processed != numLen) || qIsNaN(d)) {
367         // Implementation defined nan symbol or garbage found. We don't accept it.
368         processed = 0;
369         ok = false;
370         return 0.0;
371     }
372 
373     if (!qIsFinite(d)) {
374         // Overflow. Check for implementation-defined infinity symbols and reject them.
375         // We assume that any infinity symbol has to contain a character that cannot be part of a
376         // "normal" number (that is 0-9, ., -, +, e).
377         ok = false;
378         for (int i = 0; i < processed; ++i) {
379             char c = num[i];
380             if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e' && c != 'E') {
381                 // Garbage found
382                 processed = 0;
383                 return 0.0;
384             }
385         }
386         return d;
387     }
388 #endif // !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
389 
390     // Otherwise we would have gotten NaN or sorted it out above.
391     Q_ASSERT(strayCharMode == TrailingJunkAllowed || processed == numLen);
392 
393     // Check if underflow has occurred.
394     if (isZero(d)) {
395         for (int i = 0; i < processed; ++i) {
396             if (num[i] >= '1' && num[i] <= '9') {
397                 // if a digit before any 'e' is not 0, then a non-zero number was intended.
398                 ok = false;
399                 return 0.0;
400             } else if (num[i] == 'e' || num[i] == 'E') {
401                 break;
402             }
403         }
404     }
405     return d;
406 }
407 
408 unsigned long long
qstrtoull(const char * nptr,const char ** endptr,int base,bool * ok)409 qstrtoull(const char * nptr, const char **endptr, int base, bool *ok)
410 {
411     // strtoull accepts negative numbers. We don't.
412     // Use a different variable so we pass the original nptr to strtoul
413     // (we need that so endptr may be nptr in case of failure)
414     const char *begin = nptr;
415     while (ascii_isspace(*begin))
416         ++begin;
417     if (*begin == '-') {
418         *ok = false;
419         return 0;
420     }
421 
422     *ok = true;
423     errno = 0;
424     char *endptr2 = nullptr;
425     unsigned long long result = qt_strtoull(nptr, &endptr2, base);
426     if (endptr)
427         *endptr = endptr2;
428     if ((result == 0 || result == std::numeric_limits<unsigned long long>::max())
429             && (errno || endptr2 == nptr)) {
430         *ok = false;
431         return 0;
432     }
433     return result;
434 }
435 
436 long long
qstrtoll(const char * nptr,const char ** endptr,int base,bool * ok)437 qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)
438 {
439     *ok = true;
440     errno = 0;
441     char *endptr2 = nullptr;
442     long long result = qt_strtoll(nptr, &endptr2, base);
443     if (endptr)
444         *endptr = endptr2;
445     if ((result == 0 || result == std::numeric_limits<long long>::min()
446          || result == std::numeric_limits<long long>::max())
447             && (errno || nptr == endptr2)) {
448         *ok = false;
449         return 0;
450     }
451     return result;
452 }
453 
qulltoa(qulonglong l,int base,const QChar _zero)454 QString qulltoa(qulonglong l, int base, const QChar _zero)
455 {
456     ushort buff[65]; // length of MAX_ULLONG in base 2
457     ushort *p = buff + 65;
458 
459     if (base != 10 || _zero.unicode() == '0') {
460         while (l != 0) {
461             int c = l % base;
462 
463             --p;
464 
465             if (c < 10)
466                 *p = '0' + c;
467             else
468                 *p = c - 10 + 'a';
469 
470             l /= base;
471         }
472     }
473     else {
474         while (l != 0) {
475             int c = l % base;
476 
477             *(--p) = _zero.unicode() + c;
478 
479             l /= base;
480         }
481     }
482 
483     return QString(reinterpret_cast<QChar *>(p), 65 - (p - buff));
484 }
485 
decimalForm(QChar zero,QChar decimal,QChar group,QString & digits,int decpt,int precision,PrecisionMode pm,bool always_show_decpt,bool thousands_group)486 QString &decimalForm(QChar zero, QChar decimal, QChar group,
487                      QString &digits, int decpt, int precision,
488                      PrecisionMode pm,
489                      bool always_show_decpt,
490                      bool thousands_group)
491 {
492     if (decpt < 0) {
493         for (int i = 0; i < -decpt; ++i)
494             digits.prepend(zero);
495         decpt = 0;
496     }
497     else if (decpt > digits.length()) {
498         for (int i = digits.length(); i < decpt; ++i)
499             digits.append(zero);
500     }
501 
502     if (pm == PMDecimalDigits) {
503         uint decimal_digits = digits.length() - decpt;
504         for (int i = decimal_digits; i < precision; ++i)
505             digits.append(zero);
506     }
507     else if (pm == PMSignificantDigits) {
508         for (int i = digits.length(); i < precision; ++i)
509             digits.append(zero);
510     }
511     else { // pm == PMChopTrailingZeros
512     }
513 
514     if (always_show_decpt || decpt < digits.length())
515         digits.insert(decpt, decimal);
516 
517     if (thousands_group) {
518         for (int i = decpt - 3; i > 0; i -= 3)
519             digits.insert(i, group);
520     }
521 
522     if (decpt == 0)
523         digits.prepend(zero);
524 
525     return digits;
526 }
527 
exponentForm(QChar zero,QChar decimal,QChar exponential,QChar group,QChar plus,QChar minus,QString & digits,int decpt,int precision,PrecisionMode pm,bool always_show_decpt,bool leading_zero_in_exponent)528 QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
529                       QChar group, QChar plus, QChar minus,
530                       QString &digits, int decpt, int precision,
531                       PrecisionMode pm,
532                       bool always_show_decpt,
533                       bool leading_zero_in_exponent)
534 {
535     int exp = decpt - 1;
536 
537     if (pm == PMDecimalDigits) {
538         for (int i = digits.length(); i < precision + 1; ++i)
539             digits.append(zero);
540     }
541     else if (pm == PMSignificantDigits) {
542         for (int i = digits.length(); i < precision; ++i)
543             digits.append(zero);
544     }
545     else { // pm == PMChopTrailingZeros
546     }
547 
548     if (always_show_decpt || digits.length() > 1)
549         digits.insert(1, decimal);
550 
551     digits.append(exponential);
552     digits.append(QLocaleData::longLongToString(zero, group, plus, minus,
553                    exp, leading_zero_in_exponent ? 2 : 1, 10, -1, QLocaleData::AlwaysShowSign));
554 
555     return digits;
556 }
557 
qstrtod(const char * s00,const char ** se,bool * ok)558 double qstrtod(const char *s00, const char **se, bool *ok)
559 {
560     const int len = static_cast<int>(strlen(s00));
561     Q_ASSERT(len >= 0);
562     return qstrntod(s00, len, se, ok);
563 }
564 
565 /*!
566   \internal
567 
568   Converts the initial portion of the string pointed to by \a s00 to a double, using the 'C' locale.
569  */
qstrntod(const char * s00,int len,const char ** se,bool * ok)570 double qstrntod(const char *s00, int len, const char **se, bool *ok)
571 {
572     int processed = 0;
573     bool nonNullOk = false;
574     double d = qt_asciiToDouble(s00, len, nonNullOk, processed, TrailingJunkAllowed);
575     if (se)
576         *se = s00 + processed;
577     if (ok)
578         *ok = nonNullOk;
579     return d;
580 }
581 
qdtoa(qreal d,int * decpt,int * sign)582 QString qdtoa(qreal d, int *decpt, int *sign)
583 {
584     bool nonNullSign = false;
585     int nonNullDecpt = 0;
586     int length = 0;
587 
588     // Some versions of libdouble-conversion like an extra digit, probably for '\0'
589     char result[QLocaleData::DoubleMaxSignificant + 1];
590     qt_doubleToAscii(d, QLocaleData::DFSignificantDigits, QLocale::FloatingPointShortest, result,
591                      QLocaleData::DoubleMaxSignificant + 1, nonNullSign, length, nonNullDecpt);
592 
593     if (sign)
594         *sign = nonNullSign ? 1 : 0;
595     if (decpt)
596         *decpt = nonNullDecpt;
597 
598     return QLatin1String(result, length);
599 }
600 
601 QT_END_NAMESPACE
602