Disallow the use of COLLATE clauses and the ASC and DESC keywords within
foreign key constraints and in the argument list to common table expressions. FossilOrigin-Name: 83cbc4d8761498647794affffa961a4fca311be7
This commit is contained in:
parent
80d874083b
commit
bc622bc045
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Improvements\sto\sJSON\sstring\sdequoting.
|
||||
D 2015-08-24T12:42:41.080
|
||||
C Disallow\sthe\suse\sof\sCOLLATE\sclauses\sand\sthe\sASC\sand\sDESC\skeywords\swithin\nforeign\skey\sconstraints\sand\sin\sthe\sargument\slist\sto\scommon\stable\sexpressions.
|
||||
D 2015-08-24T15:39:42.405
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -282,14 +282,14 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
||||
F src/build.c 5eb5d055a1d1cdaaea25e01b12607aa894bc0911
|
||||
F src/build.c f49c55c1fba430c2d6af5039d0bf14de5ae6a427
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
F src/date.c 8ec787fed4929d8ccdf6b1bc360fccc3e1d2ca58
|
||||
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
||||
F src/delete.c 8857a6f27560718f65d43bdbec86c967ae1f8dfa
|
||||
F src/expr.c c34408e0ac1c57cf58ffa2003b339715ee9bda57
|
||||
F src/expr.c c05d67f1a03c097d5c29839d5a538cfde9c472ce
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
|
||||
F src/func.c 824bea430d3a2b7dbc62806ad54da8fdb8ed9e3f
|
||||
@ -326,7 +326,7 @@ F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f
|
||||
F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
|
||||
F src/parse.y ad9af8552f6f340bd646577ca63356a6f82b6a7e
|
||||
F src/parse.y b5e0a5f8bb9ec33a58aa34850b6fae46aac51fdd
|
||||
F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
|
||||
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
|
||||
F src/pcache1.c a3fe31b17e841ec70beee72a2c960e9c787a8857
|
||||
@ -342,7 +342,7 @@ F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23
|
||||
F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h f700e6a9dd1fdcccc9951ab022b366fb66b9e413
|
||||
F src/sqliteInt.h 89e68539d645db597366a91411468b51e73c21a0
|
||||
F src/sqliteInt.h 1741691824491c330dda1e49f370920bfd3aa230
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
@ -910,6 +910,7 @@ F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
|
||||
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
||||
F test/parser1.test 23867b6f2c4758c7774108826d9f17e9cd17bcde
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
@ -1378,7 +1379,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P f0aba0e120074430cd7ad93291fcc97b8a25a054
|
||||
R 3625d17566ea8cc316dd4952d6bffb99
|
||||
P 196d66d34d9783622e6f2f79eafea1488fc6f5cf
|
||||
R 2a74528f51d8172b5387a3b7f110bb2b
|
||||
U drh
|
||||
Z 6090b9f6d755a9917a579931aff72e9d
|
||||
Z ffc4f8e604c67b08cae8ed1eda808a43
|
||||
|
@ -1 +1 @@
|
||||
196d66d34d9783622e6f2f79eafea1488fc6f5cf
|
||||
83cbc4d8761498647794affffa961a4fca311be7
|
35
src/build.c
35
src/build.c
@ -1321,7 +1321,7 @@ void sqlite3AddPrimaryKey(
|
||||
}
|
||||
if( nTerm==1
|
||||
&& zType && sqlite3StrICmp(zType, "INTEGER")==0
|
||||
&& sortOrder==SQLITE_SO_ASC
|
||||
&& sortOrder!=SQLITE_SO_DESC
|
||||
){
|
||||
pTab->iPKey = iCol;
|
||||
pTab->keyConf = (u8)onError;
|
||||
@ -2600,6 +2600,8 @@ void sqlite3CreateForeignKey(
|
||||
|
||||
assert( pTo!=0 );
|
||||
if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
|
||||
sqlite3RestrictColumnListSyntax(pParse, pFromCol);
|
||||
sqlite3RestrictColumnListSyntax(pParse, pToCol);
|
||||
if( pFromCol==0 ){
|
||||
int iCol = p->nCol-1;
|
||||
if( NEVER(iCol<0) ) goto fk_end;
|
||||
@ -3038,7 +3040,8 @@ Index *sqlite3CreateIndex(
|
||||
if( pList==0 ) goto exit_create_index;
|
||||
pList->a[0].zName = sqlite3DbStrDup(pParse->db,
|
||||
pTab->aCol[pTab->nCol-1].zName);
|
||||
pList->a[0].sortOrder = (u8)sortOrder;
|
||||
assert( pList->nExpr==1 );
|
||||
sqlite3ExprListSetSortOrder(pList, sortOrder);
|
||||
}
|
||||
|
||||
/* Figure out how many bytes of space are required to store explicitly
|
||||
@ -4283,6 +4286,32 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
||||
return pKey;
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate a syntax error if the expression list provided contains
|
||||
** any COLLATE or ASC or DESC keywords.
|
||||
**
|
||||
** Some legacy versions of SQLite allowed constructs like:
|
||||
**
|
||||
** CREATE TABLE x(..., FOREIGN KEY(x COLLATE binary DESC) REFERENCES...);
|
||||
** ^^^^^^^^^^^^^^^^^^^
|
||||
**
|
||||
** The COLLATE and sort order terms were ignored. To prevent compatibility
|
||||
** problems in case something like this appears in a legacy sqlite_master
|
||||
** table, only enforce the restriction on new SQL statements, not when
|
||||
** parsing the schema out of the sqlite_master table.
|
||||
*/
|
||||
void sqlite3RestrictColumnListSyntax(Parse *pParse, ExprList *p){
|
||||
int i;
|
||||
if( p==0 || pParse->db->init.busy ) return;
|
||||
for(i=0; i<p->nExpr; i++){
|
||||
if( p->a[i].pExpr!=0 || p->a[i].bDefinedSO ){
|
||||
sqlite3ErrorMsg(pParse, "syntax error after column name \"%w\"",
|
||||
p->a[i].zName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_CTE
|
||||
/*
|
||||
** This routine is invoked once per CTE by the parser while parsing a
|
||||
@ -4299,6 +4328,8 @@ With *sqlite3WithAdd(
|
||||
With *pNew;
|
||||
char *zName;
|
||||
|
||||
sqlite3RestrictColumnListSyntax(pParse, pArglist);
|
||||
|
||||
/* Check that the CTE name is unique within this WITH clause. If
|
||||
** not, store an error in the Parse structure. */
|
||||
zName = sqlite3NameFromToken(pParse->db, pName);
|
||||
|
15
src/expr.c
15
src/expr.c
@ -1160,6 +1160,21 @@ no_mem:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the sort order for the last element on the given ExprList.
|
||||
*/
|
||||
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
|
||||
if( p==0 ) return;
|
||||
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
|
||||
assert( p->nExpr>0 );
|
||||
if( iSortOrder<0 ){
|
||||
assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
|
||||
return;
|
||||
}
|
||||
p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
|
||||
p->a[p->nExpr-1].bDefinedSO = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the ExprList.a[].zName element of the most recently added item
|
||||
** on the expression list.
|
||||
|
10
src/parse.y
10
src/parse.y
@ -680,18 +680,18 @@ orderby_opt(A) ::= . {A = 0;}
|
||||
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
||||
sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
|
||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
}
|
||||
sortlist(A) ::= expr(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
|
||||
if( A && ALWAYS(A->a) ) A->a[0].sortOrder = (u8)Z;
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
}
|
||||
|
||||
%type sortorder {int}
|
||||
|
||||
sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
||||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_ASC;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;}
|
||||
|
||||
%type groupby_opt {ExprList*}
|
||||
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
@ -1229,14 +1229,14 @@ idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,X, p);
|
||||
sqlite3ExprListSetName(pParse,A,&Y,1);
|
||||
sqlite3ExprListCheckLength(pParse, A, "index");
|
||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
}
|
||||
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
||||
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
||||
A = sqlite3ExprListAppend(pParse,0, p);
|
||||
sqlite3ExprListSetName(pParse, A, &Y, 1);
|
||||
sqlite3ExprListCheckLength(pParse, A, "index");
|
||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
}
|
||||
|
||||
%type collate {Token}
|
||||
|
@ -1525,6 +1525,7 @@ struct CollSeq {
|
||||
*/
|
||||
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
|
||||
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
|
||||
#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
|
||||
|
||||
/*
|
||||
** Column affinity types.
|
||||
@ -2189,6 +2190,7 @@ struct ExprList {
|
||||
unsigned done :1; /* A flag to indicate when processing is finished */
|
||||
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
|
||||
unsigned reusable :1; /* Constant expression is reusable */
|
||||
unsigned bDefinedSO :1; /* True if either DESC or ASC keywords present */
|
||||
union {
|
||||
struct {
|
||||
u16 iOrderByCol; /* For ORDER BY, column number in result set */
|
||||
@ -3244,6 +3246,7 @@ Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
|
||||
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
|
||||
void sqlite3ExprDelete(sqlite3*, Expr*);
|
||||
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
||||
void sqlite3ExprListSetSortOrder(ExprList*,int);
|
||||
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
||||
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
|
||||
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
@ -3755,6 +3758,7 @@ const char *sqlite3JournalModename(int);
|
||||
int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
|
||||
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
|
||||
#endif
|
||||
void sqlite3RestrictColumnListSyntax(Parse*,ExprList*);
|
||||
#ifndef SQLITE_OMIT_CTE
|
||||
With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
|
||||
void sqlite3WithDelete(sqlite3*,With*);
|
||||
|
58
test/parser1.test
Normal file
58
test/parser1.test
Normal file
@ -0,0 +1,58 @@
|
||||
# 2014-08-24
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
# The focus of this script is testing details of the SQL language parser.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_catchsql_test parser1-1.1 {
|
||||
CREATE TABLE t1(
|
||||
a TEXT PRIMARY KEY,
|
||||
b TEXT,
|
||||
FOREIGN KEY(b COLLATE nocase DESC) REFERENCES t1(a COLLATE binary ASC)
|
||||
);
|
||||
} {1 {syntax error after column name "a"}}
|
||||
do_execsql_test parser1-1.2 {
|
||||
CREATE TABLE t1(
|
||||
a TEXT PRIMARY KEY,
|
||||
b TEXT,
|
||||
FOREIGN KEY(b) REFERENCES t1(a)
|
||||
);
|
||||
INSERT INTO t1 VALUES('abc',NULL),('xyz','abc');
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET sql='CREATE TABLE t1(
|
||||
a TEXT PRIMARY KEY,
|
||||
b TEXT,
|
||||
FOREIGN KEY(b COLLATE nocase) REFERENCES t1(a)
|
||||
)' WHERE name='t1';
|
||||
SELECT name FROM sqlite_master WHERE sql LIKE '%collate%';
|
||||
} {t1}
|
||||
sqlite3 db2 test.db
|
||||
do_test parser1-1.3 {
|
||||
sqlite3 db2 test.db
|
||||
db2 eval {SELECT * FROM t1 ORDER BY 1}
|
||||
} {abc {} xyz abc}
|
||||
|
||||
|
||||
do_catchsql_test parser1-2.1 {
|
||||
WITH RECURSIVE
|
||||
c(x COLLATE binary) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<5)
|
||||
SELECT x FROM c;
|
||||
} {1 {syntax error after column name "x"}}
|
||||
do_catchsql_test parser1-2.2 {
|
||||
WITH RECURSIVE
|
||||
c(x ASC) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<5)
|
||||
SELECT x FROM c;
|
||||
} {1 {syntax error after column name "x"}}
|
||||
|
||||
finish_test
|
Loading…
Reference in New Issue
Block a user