SQLite

Check-in [17537a98]
Login

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. Fixed by this check-in.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | branch-3.47
Files: files | file ages | folders
SHA3-256: 17537a98cb31ab41f0e02a8403b1480f8d86ddbfc263fd766e73b6b5a7dbba2f
User & Date: drh 2024-12-07 14:51:32
Context
2024-12-07
14:53
Increment the version number to 3.47.2 (check-in: 42aa7157 user: drh tags: branch-3.47)
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-02
19:32
Ensure that the query flattener does not change an ON clause term to a WHERE clause term. (check-in: e487d3b3 user: drh tags: branch-3.47)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch
Changes to src/util.c.
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
    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/10) ){
    s *= 10;
    e--;
  }
  while( e<0 && (s%10)==0 ){
    s /= 10;
    e++;
  }

  rr[0] = (double)s;

  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);





  if( e>0 ){
    while( e>=100  ){
      e -= 100;
      dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
    }
    while( e>=10   ){
      e -= 10;







|









>
|

|

|
>
>
>
>
>







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