Fix a problem with using sqlite3_bind_value() with sqlite3_value objects obtained from sqlite3_preupdate_new() when an integer value is written to a column with real affinity.

FossilOrigin-Name: c006515ae6faff6525d589827d99092b06004472e32b7f586845c00c4732d695
This commit is contained in:
dan 2022-02-09 18:42:15 +00:00
parent 9f4ce3b19f
commit 252fe67bdd
5 changed files with 165 additions and 10 deletions

View File

@ -1,5 +1,5 @@
C Writes\sto\sthe\ssubjournal\sshould\sbe\sall-or-nothing.\s\sFix\sfor\ndbsqlfuzz\sfe3c397fb90029313446c4e0f4a6cd0c81dd9621.
D 2022-02-08T15:14:18.391
C Fix\sa\sproblem\swith\susing\ssqlite3_bind_value()\swith\ssqlite3_value\sobjects\sobtained\sfrom\ssqlite3_preupdate_new()\swhen\san\sinteger\svalue\sis\swritten\sto\sa\scolumn\swith\sreal\saffinity.
D 2022-02-09T18:42:15.785
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -562,7 +562,7 @@ F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a3
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 48f291e1a7e672a7204884d4c164a8ed3a522ff087c361ada2991f5d54e987f6
F src/test1.c 9287559cc1f7c5a25f927aa172e69778237f0e037960dbcdb4257d0bea500114
F src/test1.c ac0e7eeea18230c9c315abedd5a91db7bea91743880d9371b60d3bf2b40c9796
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
@ -627,7 +627,7 @@ F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
F src/vdbe.c 13a4de20ee07bdfb3dc74ab49b7912208e309caf762a8d1678fb111e2223af35
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
F src/vdbeInt.h b45599a2b59f1ce042512ab6786b0b82a8cf3002f6b0fa60b4834e2cd3ac61d8
F src/vdbeapi.c 06bff35393ca5daa3e02e38fb516df320bd52720a2781eb70c2db23ea1c746dd
F src/vdbeapi.c c38f1642bb2e31a3e2f1bbd185984455e277022bdd618698a036557686721e8a
F src/vdbeaux.c 0d7659fe8cb38ce86092b9bc5131c99a834a04eb78745e54acb77d79d7af2fb5
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
F src/vdbemem.c eb6042667c02c3ef1f968235b4a170e31b23a4b6a57f65a8454eab4d36f14b7f
@ -739,6 +739,7 @@ F test/bigmmap.test b820c234daa56d24bc3bf006e3ac7aa9d9623c8ac656a38f59063b444a2d
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2
F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483
F test/bind2.test ce26f19475c933e59e80028fc44073b84c2aba8650dadfdfbd057a4c5adbeb3a
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
@ -1943,8 +1944,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 1269206db810460e55a52e178ba3332add42a11f66c5f292f8f0d29ccd61a4b8
R 152bd288ae589530fc2745d322f45fd2
U drh
Z b4c4dbfb44e2c416fb7b7bc180b39619
P 22cc55e84f67f6f39b7dba07a4ef7ae958b2d926633faec91a278922053e50c6
R 17abaf30f93ccdc5511b2021ebdd531b
U dan
Z a19c7c2fd597f947d750ad2fbbbad2d2
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
22cc55e84f67f6f39b7dba07a4ef7ae958b2d926633faec91a278922053e50c6
c006515ae6faff6525d589827d99092b06004472e32b7f586845c00c4732d695

View File

@ -3977,6 +3977,100 @@ static int SQLITE_TCLAPI test_bind_blob(
return TCL_OK;
}
/*
** Usage: sqlite3_bind_value_from_preupdate STMT N NEW|OLD IDX
**
** Test the sqlite3_bind_value interface using sqlite3_value objects
** obtained from either sqlite3_preupdate_new() (if arg[3]=="new") or
** sqlite3_preupdate_old() if (arg[3]=="old"). IDX is the index to
** pass to the sqlite3_preupdate_xxx() function.
*/
static int SQLITE_TCLAPI test_bind_value_from_preupdate(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt;
int idx;
int bidx;
const char *z3 = 0;
sqlite3 *db = 0;
sqlite3_value *pVal = 0;
if( objc!=5 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT N NEW|OLD IDX");
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
z3 = Tcl_GetString(objv[3]);
if( Tcl_GetIntFromObj(interp, objv[4], &bidx) ) return TCL_ERROR;
db = sqlite3_db_handle(pStmt);
if( z3[0]=='n' ){
sqlite3_preupdate_new(db, bidx, &pVal);
}else if( z3[0]=='o' ){
sqlite3_preupdate_old(db, bidx, &pVal);
}else{
Tcl_AppendResult(interp, "expected new or old, got: ", z3, (char*)0);
return TCL_ERROR;
}
sqlite3_bind_value(pStmt, idx, pVal);
return TCL_OK;
}
/*
** Usage: sqlite3_bind_value_from_select STMT N SELECT
**
** Test the sqlite3_bind_value interface. STMT is a prepared statement.
** N is the index of a wildcard in the prepared statement.
*/
static int SQLITE_TCLAPI test_bind_value_from_select(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt;
sqlite3_stmt *pStmt2;
int idx;
const char *zSql = 0;
sqlite3 *db = 0;
int rc = SQLITE_OK;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT N SELECT");
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
zSql = Tcl_GetString(objv[3]);
db = sqlite3_db_handle(pStmt);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt2, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, "error in SQL: ", sqlite3_errmsg(db), (char*)0);
return TCL_ERROR;
}
if( sqlite3_step(pStmt2)==SQLITE_ROW ){
sqlite3_value *pVal = sqlite3_column_value(pStmt2, 0);
sqlite3_bind_value(pStmt, idx, pVal);
}
rc = sqlite3_finalize(pStmt2);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp,
"error runnning SQL: ", sqlite3_errmsg(db), (char*)0
);
return TCL_ERROR;
}
return TCL_OK;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
@ -8442,6 +8536,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_bind_text", test_bind_text ,0 },
{ "sqlite3_bind_text16", test_bind_text16 ,0 },
{ "sqlite3_bind_blob", test_bind_blob ,0 },
{ "sqlite3_bind_value_from_select",test_bind_value_from_select ,0 },
{ "sqlite3_bind_value_from_preupdate",test_bind_value_from_preupdate ,0 },
#ifndef SQLITE_OMIT_VIRTUALTABLE
{ "sqlite3_carray_bind", test_carray_bind ,0 },
#endif

View File

@ -1594,7 +1594,7 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
break;
}
case SQLITE_FLOAT: {
rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
rc = sqlite3_bind_double(pStmt, i, sqlite3VdbeRealValue((Mem*)pValue));
break;
}
case SQLITE_BLOB: {

58
test/bind2.test Normal file
View File

@ -0,0 +1,58 @@
# 2022 Feb 10
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bind2
# Test that using bind_value() on a REAL sqlite3_value that was stored
# as an INTEGER works properly.
#
# 1.1: An IntReal value read from a table,
# 1.2: IntReal values obtained via the sqlite3_preupdate_old|new()
# interfaces.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a REAL);
INSERT INTO t1 VALUES(42.0);
SELECT * FROM t1;
} {42.0}
do_test 1.1 {
set stmt [sqlite3_prepare db "SELECT ?" -1 tail]
sqlite3_bind_value_from_select $stmt 1 "SELECT a FROM t1"
sqlite3_step $stmt
sqlite3_column_text $stmt 0
} {42.0}
sqlite3_finalize $stmt
proc preup {args} {
set stmt [sqlite3_prepare db "SELECT ?" -1 tail]
sqlite3_bind_value_from_preupdate $stmt 1 old 0
sqlite3_step $stmt
lappend ::reslist [sqlite3_column_text $stmt 0]
sqlite3_reset $stmt
sqlite3_bind_value_from_preupdate $stmt 1 new 0
sqlite3_step $stmt
lappend ::reslist [sqlite3_column_text $stmt 0]
sqlite3_finalize $stmt
}
db preupdate hook preup
do_test 1.2 {
set ::reslist [list]
execsql { UPDATE t1 SET a=43; }
set ::reslist
} {42.0 43.0}
finish_test