1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Update extension ext/misc/totext.c to avoid both ubsan warnings and dubious real->integer conversions.

FossilOrigin-Name: c626aa108a7a30cef54af8d93ac9e45749568ed38e4e06623a6bad6b4bf6e8ec
This commit is contained in:
dan
2024-01-05 15:53:58 +00:00
parent 76da0dcbc4
commit 1cfc040bba
4 changed files with 34 additions and 18 deletions

View File

@ -350,6 +350,20 @@ totype_atof_calc:
return z>=zEnd && nDigits>0 && eValid && nonNum==0;
}
/*
** Convert a floating point value to an integer. Or, if this cannot be
** done in a way that avoids 'outside the range of representable values'
** warnings from UBSAN, return 0.
**
** This function is a modified copy of internal SQLite function
** sqlite3RealToI64().
*/
static sqlite3_int64 totypeDoubleToInt(double r){
if( r<-9223372036854774784.0 ) return 0;
if( r>+9223372036854774784.0 ) return 0;
return (sqlite3_int64)r;
}
/*
** tointeger(X): If X is any value (integer, double, blob, or string) that
** can be losslessly converted into an integer, then make the conversion and
@ -365,7 +379,7 @@ static void tointegerFunc(
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_FLOAT: {
double rVal = sqlite3_value_double(argv[0]);
sqlite3_int64 iVal = (sqlite3_int64)rVal;
sqlite3_int64 iVal = totypeDoubleToInt(rVal);
if( rVal==(double)iVal ){
sqlite3_result_int64(context, iVal);
}
@ -440,7 +454,7 @@ static void torealFunc(
case SQLITE_INTEGER: {
sqlite3_int64 iVal = sqlite3_value_int64(argv[0]);
double rVal = (double)iVal;
if( iVal==(sqlite3_int64)rVal ){
if( iVal==totypeDoubleToInt(rVal) ){
sqlite3_result_double(context, rVal);
}
break;