Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a buffer overread during compilation of CREATE VIRTUAL TABLE statements that featured an explicit database name but no virtual table arguments. For example, "CREATE VIRTUAL TABLE main.ft USING fts4". |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f095cde579e7417306e11b5c1d2dd90b |
User & Date: | dan 2014-11-27 11:36:36.295 |
Context
2014-11-28
| ||
11:54 | Add the -end option to the command-line shell, which forces it to exit after reading prior command-line options (presumably including one or more -cmd options) and without reading standard input. (check-in: b59397b1f1 user: drh tags: trunk) | |
2014-11-27
| ||
11:36 | Fix a buffer overread during compilation of CREATE VIRTUAL TABLE statements that featured an explicit database name but no virtual table arguments. For example, "CREATE VIRTUAL TABLE main.ft USING fts4". (check-in: f095cde579 user: dan tags: trunk) | |
04:23 | More test cases for the balancer. (check-in: 358ea818f7 user: drh tags: trunk) | |
Changes
Changes to src/test1.c.
︙ | ︙ | |||
3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; const char *zSql; int bytes; const char *zTail = 0; sqlite3_stmt *pStmt = 0; char zBuf[50]; int rc; if( objc!=5 && objc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zSql = Tcl_GetString(objv[2]); if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; | > > > > > > > > > > > > | > > > | 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; const char *zSql; char *zCopy = 0; /* malloc() copy of zSql */ int bytes; const char *zTail = 0; sqlite3_stmt *pStmt = 0; char zBuf[50]; int rc; if( objc!=5 && objc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zSql = Tcl_GetString(objv[2]); if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; /* Instead of using zSql directly, make a copy into a buffer obtained ** directly from malloc(). The idea is to make it easier for valgrind ** to spot buffer overreads. */ if( bytes>=0 ){ zCopy = malloc(bytes); memcpy(zCopy, zSql, bytes); }else{ int n = strlen(zSql) + 1; zCopy = malloc(n); memcpy(zCopy, zSql, n); } rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0); free(zCopy); zTail = &zSql[(zTail - zCopy)]; assert(rc==SQLITE_OK || pStmt==0); Tcl_ResetResult(interp); if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; if( zTail && objc>=5 ){ if( bytes>=0 ){ bytes = bytes - (int)(zTail-zSql); } |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
328 329 330 331 332 333 334 | assert( iDb>=0 ); pTable->tabFlags |= TF_Virtual; pTable->nModuleArg = 0; addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, 0); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); | > > > | > > | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | assert( iDb>=0 ); pTable->tabFlags |= TF_Virtual; pTable->nModuleArg = 0; addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, 0); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) || (pParse->sNameToken.z==pName1->z && pName2->z==0) ); pParse->sNameToken.n = (int)( &pModuleName->z[pModuleName->n] - pParse->sNameToken.z ); #ifndef SQLITE_OMIT_AUTHORIZATION /* Creating a virtual table invokes the authorization callback twice. ** The first invocation, to obtain permission to INSERT a row into the ** sqlite_master table, has already been made by sqlite3StartTable(). ** The second call, to obtain permission to create the table, is made now. */ |
︙ | ︙ |
Changes to test/vtab1.test.
︙ | ︙ | |||
1390 1391 1392 1393 1394 1395 1396 1397 1398 | do_execsql_test 21.2 { SELECT * FROM t9v WHERE a<b; } {1 2 3} do_execsql_test 21.3 { SELECT * FROM t9v WHERE a=b; } {2 2 2} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | do_execsql_test 21.2 { SELECT * FROM t9v WHERE a<b; } {1 2 3} do_execsql_test 21.3 { SELECT * FROM t9v WHERE a=b; } {2 2 2} #------------------------------------------------------------------------- # At one point executing a CREATE VIRTUAL TABLE statement that specified # a database name but no virtual table arguments was causing an internal # buffer overread. Valgrind would report errors while running the following # tests. Specifically: # # CREATE VIRTUAL TABLE t1 USING fts4; -- Ok - no db name. # CREATE VIRTUAL TABLE main.t1 USING fts4(x); -- Ok - has vtab arguments. # CREATE VIRTUAL TABLE main.t1 USING fts4; -- Had the problem. # ifcapable fts3 { forcedelete test.db2 set nm [string repeat abcdefghij 100] do_execsql_test 22.1 { ATTACH 'test.db2' AS $nm } execsql "SELECT * FROM sqlite_master" do_execsql_test 22.2 "CREATE VIRTUAL TABLE ${nm}.t1 USING fts4" do_test 22.3.1 { set sql "CREATE VIRTUAL TABLE ${nm}.t2 USING fts4" set stmt [sqlite3_prepare_v2 db $sql -1 dummy] sqlite3_step $stmt } {SQLITE_DONE} do_test 22.3.2 { sqlite3_finalize $stmt } {SQLITE_OK} do_test 22.4.1 { set sql "CREATE VIRTUAL TABLE ${nm}.t3 USING fts4" set n [string length $sql] set stmt [sqlite3_prepare db "${sql}xyz" $n dummy] sqlite3_step $stmt } {SQLITE_DONE} do_test 22.4.2 { sqlite3_finalize $stmt } {SQLITE_OK} } finish_test |