diff options
author | drh <> | 2024-12-07 14:48:55 +0000 |
---|---|---|
committer | drh <> | 2024-12-07 14:48:55 +0000 |
commit | 1a4b2117f11fba43ca892936df22681a7c496d46 (patch) | |
tree | a88720f4f076e63b1919ff288ea2199957e50251 /src | |
parent | ef636cc3cd72b2a7f5803777b95419b279baacab (diff) | |
download | sqlite-1a4b2117f11fba43ca892936df22681a7c496d46.tar.gz sqlite-1a4b2117f11fba43ca892936df22681a7c496d46.zip |
On x64 hardware, round-trip uint64_t→double→uint64_t conversions
fail for values greater than UINT64_MAX-2047. This caused the SQLite
text-to-float converter routine to give incorrect results for values
between '1.8446744073709550592eNNN' and '1.8446744073709551609eNNN' for any
exponent NNN. This problem was introduced by check-in [761d8fd18b0ee868]
and first appeared in version 3.47.0 and was reported by
[forum:/forumpost/569a7209179a7f5e|forum post 569a7209179a7f5e]. Fixed
by this check-in.
FossilOrigin-Name: 81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036
Diffstat (limited to 'src')
-rw-r--r-- | src/util.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/util.c b/src/util.c index 52c2a744c..31b05666a 100644 --- a/src/util.c +++ b/src/util.c @@ -643,7 +643,7 @@ do_atof_calc: e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ - while( e>0 && s<(LARGEST_UINT64/10) ){ + while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } @@ -653,11 +653,17 @@ do_atof_calc: } rr[0] = (double)s; - s2 = (u64)rr[0]; + if( s<(LARGEST_UINT64-0x7ff) ){ + s2 = (u64)rr[0]; #if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } + if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } #endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + }else{ + s2 = s; + rr[1] = 0.0; + } + if( e>0 ){ while( e>=100 ){ e -= 100; |