diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-10-21 10:26:45 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-11-05 10:12:04 +0100 |
commit | edec095cf80b62057116ce75c581b5ca5866bdcc (patch) | |
tree | a849983cff625c80f9386865988f32ad552837cd /src/corelib/global/qnumeric_p.h | |
parent | e99b0016e8b639e40d5330e0c3eaa199b48e34f4 (diff) |
Fix 64-bit integer support in QtJSON
Fixes parsing writing and pass-through of integers with
higher precision than double can handle.
Note this adds extra precision compared to JavaScript, but the
JSON files read and written this way are still valid, and the extra
precision in reading and writing this way is used by many JSON
libraries.
Fixes: QTBUG-28560
Change-Id: I30b2415c928d1c34c8cb4e4c6218602095e7e8aa
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global/qnumeric_p.h')
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 86e7997680..c006296b3d 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -202,7 +202,7 @@ namespace { This function works for v containing infinities, but not NaN. It's the caller's responsibility to exclude that possibility before calling it. */ -template <typename T> static inline bool convertDoubleTo(double v, T *value) +template <typename T> static inline bool convertDoubleTo(double v, T *value, bool allow_precision_upgrade = true) { Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer); @@ -227,6 +227,10 @@ template <typename T> static inline bool convertDoubleTo(double v, T *value) supremum = -2.0 * std::numeric_limits<ST>::min(); // -2 * (-2^63) = 2^64, exact (for T = quint64) v = fabs(v); } + if (std::is_integral<T>::value && sizeof(T) > 4 && !allow_precision_upgrade) { + if (v > double(Q_INT64_C(1)<<53) || v < double(-((Q_INT64_C(1)<<53) + 1))) + return false; + } *value = std::numeric_limits<T>::max(); if (v >= supremum) |