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:
+33
-2
@@ -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
@@ -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.
|
||||
|
||||
+5
-5
@@ -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*);
|
||||
|
||||
Reference in New Issue
Block a user