Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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 post 569a7209179a7f5e. Fixed by this check-in. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
81342fa6dd03fffbe7d4d699ff049dce |
User & Date: | drh 2024-12-07 14:48:55 |
References
2024-12-07
| ||
19:06 | A cleaner and more robust solution to the floating-point conversion problem originally fixed by [81342fa6dd03fffb]. (check-in: 351de57f user: drh tags: trunk) | |
Context
2024-12-09
| ||
11:12 | Fix an obscure problem with multiple outer joins, ON clauses and query flattening. Forum thread 5c8a069d23. (Closed-Leaf check-in: 289daf6c user: dan tags: forum-5c8a069d23-fix) | |
2024-12-07
| ||
16:53 | Fix harmless compiler warning caused by the previous check-in. (check-in: 462700ae user: drh tags: trunk) | |
14:51 | 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. Fixed by this check-in. (check-in: 17537a98 user: drh tags: branch-3.47) | |
14:48 | 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 post 569a7209179a7f5e. Fixed by this check-in. (check-in: 81342fa6 user: drh tags: trunk) | |
2024-12-06
| ||
18:35 | Add the SQLITE_PREPARE_DONT_LOG option for sqlite3_prepare_v3(), that prevents errors in the compilation of the SQL from being sent to sqlite3_log(). (check-in: 87040342 user: drh tags: trunk) | |
Changes
Changes to src/util.c.
︙ | ︙ | |||
639 640 641 642 643 644 645 | goto atof_return; } /* adjust exponent by d, and update sign */ e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ | | > | | | > > > > > | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | goto atof_return; } /* adjust exponent by d, and update sign */ e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } while( e<0 && (s%10)==0 ){ s /= 10; e++; } rr[0] = (double)s; 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]); } #endif 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; dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); } while( e>=10 ){ e -= 10; |
︙ | ︙ |
Changes to test/atof1.test.
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 | CREATE INDEX i1 ON t1(a); SELECT count(*) FROM t1 WHERE substr(a,','); } {1} # 2020-08-27 OSSFuzz find related to the above. do_execsql_test atof1-2.40 { SELECT randomblob(0) - 1; } {-1} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | CREATE INDEX i1 ON t1(a); SELECT count(*) FROM t1 WHERE substr(a,','); } {1} # 2020-08-27 OSSFuzz find related to the above. do_execsql_test atof1-2.40 { SELECT randomblob(0) - 1; } {-1} # 2024-12-07 https://sqlite.org/forum/forumpost/569a7209179a7f5e # Incorrect conversion of floating point or integer literals that # have significant digits that begin with 1844674407370955 followed # by more digits in the range 0592 throgh 1609. # do_execsql_test atof-3.1 { WITH RECURSIVE bigval(i,vtxt) AS ( SELECT 0, '18446744073709550000' UNION ALL SELECT i+1, format('1844674407370955%04d',i+1) FROM bigval WHERE i+1<=9999 ) SELECT vtxt, CAST(vtxt AS REAL) FROM bigval WHERE CAST(vtxt AS REAL) NOT GLOB '1.8446744073709[56]*'; } {} do_execsql_test atof-3.2 { WITH RECURSIVE bigval(i,vtxt) AS ( SELECT 0, '18.446744073709550000' UNION ALL SELECT i+1, format('18.44674407370955%04d',i+1) FROM bigval WHERE i+1<=9999 ) SELECT vtxt, CAST(vtxt AS REAL) FROM bigval WHERE CAST(vtxt AS REAL) NOT GLOB '18.446744073709*'; } {} do_execsql_test atof-3.3 { WITH RECURSIVE exp(n,v1,v2) AS ( SELECT -200, '1.8446744073709550592e-200', '1.8446744073709551609e-200' UNION ALL SELECT n+1, ('1.8446744073709550592e'||n),('1.8446744073709551609e'||n) FROM exp WHERE n<200 ) SELECT n, v1, v2 FROM exp WHERE format('%.10e',CAST(v1 AS REAL)) NOT GLOB '1.8446*' OR format('%.10e',CAST(v2 AS REAL)) NOT GLOB '1.8446*'; } {} finish_test |