Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Do not allow indexing of any table whose name begins with "sqlite_". Ticket #3284. Improve handling of databases with malformed schemas - just in case somebody has actually indexed a system table. (CVS 5553) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0e1d8d14a153483e65bd0246d23db2b8 |
User & Date: | drh 2008-08-11 18:44:58 |
Context
2008-08-11
| ||
19:12 | Make the CLI more tolerant of malformed schemas by setting the writable_schema pragma prior to running the ".dump" command. (CVS 5554) check-in: 860babd841 user: drh tags: trunk | |
18:44 | Do not allow indexing of any table whose name begins with "sqlite_". Ticket #3284. Improve handling of databases with malformed schemas - just in case somebody has actually indexed a system table. (CVS 5553) check-in: 0e1d8d14a1 user: drh tags: trunk | |
18:29 | The GCC magic to warn about experimental interfaces does not work on gcc version 4.1.0. Add #ifdefs to work around this. (CVS 5552) check-in: 90cae83169 user: drh tags: trunk | |
Changes
Changes to src/build.c.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 .... 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 .... 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 |
** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.494 2008/08/06 13:47:41 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. ................................................................................ goto exit_drop_table; } if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ goto exit_drop_table; } } #endif if( pTab->readOnly || pTab==db->aDb[iDb].pSchema->pSeqTab ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } #ifndef SQLITE_OMIT_VIEW /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used ** on a table. ................................................................................ pTab = pParse->pNewTable; if( !pTab ) goto exit_create_index; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); } pDb = &db->aDb[iDb]; if( pTab==0 || pParse->nErr ) goto exit_create_index; if( pTab->readOnly ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; |
| | | |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 .... 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 .... 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 |
** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.495 2008/08/11 18:44:58 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. ................................................................................ goto exit_drop_table; } if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ goto exit_drop_table; } } #endif if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } #ifndef SQLITE_OMIT_VIEW /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used ** on a table. ................................................................................ pTab = pParse->pNewTable; if( !pTab ) goto exit_create_index; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); } pDb = &db->aDb[iDb]; if( pTab==0 || pParse->nErr ) goto exit_create_index; if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; |
Changes to src/prepare.c.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 .. 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 .. 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 ... 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ... 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.91 2008/08/02 03:50:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema( InitData *pData, /* Initialization context */ const char *zObj, /* Object being parsed at the point of error */ const char *zExtra /* Error information */ ){ if( !pData->db->mallocFailed ){ if( zObj==0 ) zObj = "?"; sqlite3SetString(pData->pzErrMsg, pData->db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ){ *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } ................................................................................ */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb = pData->iDb; assert( sqlite3_mutex_held(db->mutex) ); pData->rc = SQLITE_OK; DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ corruptSchema(pData, argv[0], 0); return SQLITE_NOMEM; } assert( argc==3 ); ................................................................................ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, argv[0], zErr); } sqlite3DbFree(db, zErr); return 1; } }else if( argv[0]==0 ){ corruptSchema(pData, 0, 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ................................................................................ /* Construct the schema tables. */ azArg[0] = zMasterName; azArg[1] = "1"; azArg[2] = zMasterSchema; azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = pzErrMsg; (void)sqlite3SafetyOff(db); rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0); (void)sqlite3SafetyOn(db); if( rc ){ rc = initData.rc; goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; } ................................................................................ db->xAuth = 0; #endif rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; } #endif if( rc==SQLITE_ABORT ) rc = initData.rc; (void)sqlite3SafetyOn(db); sqlite3DbFree(db, zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif |
| > | < < > | < > | |
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 .. 54 55 56 57 58 59 60 61 62 63 64 65 66 67 .. 93 94 95 96 97 98 99 100 101 102 103 104 105 106 ... 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ... 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.92 2008/08/11 18:44:58 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema( InitData *pData, /* Initialization context */ const char *zObj, /* Object being parsed at the point of error */ const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ if( zObj==0 ) zObj = "?"; sqlite3SetString(pData->pzErrMsg, pData->db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ){ *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } ................................................................................ */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb = pData->iDb; assert( sqlite3_mutex_held(db->mutex) ); DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ corruptSchema(pData, argv[0], 0); return SQLITE_NOMEM; } assert( argc==3 ); ................................................................................ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, argv[0], zErr); } sqlite3DbFree(db, zErr); } }else if( argv[0]==0 ){ corruptSchema(pData, 0, 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ................................................................................ /* Construct the schema tables. */ azArg[0] = zMasterName; azArg[1] = "1"; azArg[2] = zMasterSchema; azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.rc = SQLITE_OK; initData.pzErrMsg = pzErrMsg; (void)sqlite3SafetyOff(db); sqlite3InitCallback(&initData, 3, (char **)azArg, 0); (void)sqlite3SafetyOn(db); if( initData.rc ){ rc = initData.rc; goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; } ................................................................................ db->xAuth = 0; #endif rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; } #endif if( rc==SQLITE_OK ) rc = initData.rc; (void)sqlite3SafetyOn(db); sqlite3DbFree(db, zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif |
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
|
** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.772 2008/08/02 15:10:09 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor ................................................................................ zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", db->aDb[iDb].zName, zMaster, pOp->p4.z); if( zSql==0 ) goto no_mem; (void)sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3DbFree(db, zSql); db->init.busy = 0; (void)sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } break; |
|
>
|
|
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
|
** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.773 2008/08/11 18:44:58 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor ................................................................................ zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", db->aDb[iDb].zName, zMaster, pOp->p4.z); if( zSql==0 ) goto no_mem; (void)sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; initData.rc = SQLITE_OK; assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_OK ) rc = initData.rc; sqlite3DbFree(db, zSql); db->init.busy = 0; (void)sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } break; |
Changes to src/vdbeapi.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.138 2008/08/02 03:50:39 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** The following structure contains pointers to the end points of a ................................................................................ assert(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } /* Assert that malloc() has not failed */ db = p->db; assert( !db->mallocFailed ); if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } rc = SQLITE_ERROR; goto end_of_step; |
|
|
>
>
|
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.139 2008/08/11 18:44:58 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** The following structure contains pointers to the end points of a ................................................................................ assert(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } /* Assert that malloc() has not failed */ db = p->db; if( db->mallocFailed ){ return SQLITE_NOMEM; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } rc = SQLITE_ERROR; goto end_of_step; |
Changes to test/analyze.test.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 .. 57 58 59 60 61 62 63 64 65 66 67 68 69 70 ... 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # This file implements tests for the ANALYZE command. # # $Id: analyze.test,v 1.8 2008/08/01 18:47:02 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # There is nothing to test if ANALYZE is disable for this build. # ifcapable {!analyze} { ................................................................................ } } {0 {}} do_test analyze-1.6 { execsql { SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1' } } {1} do_test analyze-1.7 { execsql { SELECT * FROM sqlite_stat1 } } {} do_test analyze-1.8 { catchsql { ................................................................................ # This test corrupts the database file so it must be the last test # in the series. # do_test analyze-99.1 { execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense'; } db close sqlite3 db test.db catchsql { ANALYZE } } {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}} finish_test |
| > > > > > > > > > > | |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 .. 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 ... 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
# May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # This file implements tests for the ANALYZE command. # # $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # There is nothing to test if ANALYZE is disable for this build. # ifcapable {!analyze} { ................................................................................ } } {0 {}} do_test analyze-1.6 { execsql { SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1' } } {1} do_test analyze-1.6.2 { catchsql { CREATE INDEX stat1idx ON sqlite_stat1(idx); } } {1 {table sqlite_stat1 may not be indexed}} do_test analyze-1.6.3 { catchsql { CREATE INDEX main.stat1idx ON SQLite_stat1(idx); } } {1 {table sqlite_stat1 may not be indexed}} do_test analyze-1.7 { execsql { SELECT * FROM sqlite_stat1 } } {} do_test analyze-1.8 { catchsql { ................................................................................ # This test corrupts the database file so it must be the last test # in the series. # do_test analyze-99.1 { execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1'; } db close sqlite3 db test.db catchsql { ANALYZE } } {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}} finish_test |
Changes to test/autoinc.test.
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the AUTOINCREMENT features. # # $Id: autoinc.test,v 1.12 2008/05/29 03:20:59 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # If the library is not compiled with autoincrement support then # skip all tests in this file. ................................................................................ # The SQLITE_SEQUENCE table is initially empty # do_test autoinc-1.3 { execsql { SELECT * FROM sqlite_sequence; } } {} # Close and reopen the database. Verify that everything is still there. # do_test autoinc-1.4 { db close sqlite3 db test.db execsql { |
|
>
>
>
>
>
|
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the AUTOINCREMENT features. # # $Id: autoinc.test,v 1.13 2008/08/11 18:44:58 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # If the library is not compiled with autoincrement support then # skip all tests in this file. ................................................................................ # The SQLITE_SEQUENCE table is initially empty # do_test autoinc-1.3 { execsql { SELECT * FROM sqlite_sequence; } } {} do_test autoinc-1.3.1 { catchsql { CREATE INDEX seqidx ON sqlite_sequence(name) } } {1 {table sqlite_sequence may not be indexed}} # Close and reopen the database. Verify that everything is still there. # do_test autoinc-1.4 { db close sqlite3 db test.db execsql { |
Changes to test/trigger7.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
112
113
114
115
116
117
118
119
120
121
|
# May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to increase coverage of trigger.c. # # $Id: trigger7.test,v 1.2 2008/03/19 13:03:34 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!trigger} { finish_test return } ................................................................................ UPDATE sqlite_master SET sql='nonsense'; } db close sqlite3 db test.db catchsql { DROP TRIGGER t2r5 } } {1 {malformed database schema (t1) - near "nonsense": syntax error}} finish_test |
|
|
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
112
113
114
115
116
117
118
119
120
121
|
# May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to increase coverage of trigger.c. # # $Id: trigger7.test,v 1.3 2008/08/11 18:44:58 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!trigger} { finish_test return } ................................................................................ UPDATE sqlite_master SET sql='nonsense'; } db close sqlite3 db test.db catchsql { DROP TRIGGER t2r5 } } {1 {malformed database schema (t2r12) - near "nonsense": syntax error}} finish_test |