aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-12-07 14:48:55 +0000
committerdrh <>2024-12-07 14:48:55 +0000
commit1a4b2117f11fba43ca892936df22681a7c496d46 (patch)
treea88720f4f076e63b1919ff288ea2199957e50251 /src
parentef636cc3cd72b2a7f5803777b95419b279baacab (diff)
downloadsqlite-1a4b2117f11fba43ca892936df22681a7c496d46.tar.gz
sqlite-1a4b2117f11fba43ca892936df22681a7c496d46.zip
On x64 hardware, round-trip uint64_t&rarr;double&rarr;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.c14
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;