aboutsummaryrefslogtreecommitdiff
path: root/src/build.c
diff options
context:
space:
mode:
authordrh <>2025-02-21 20:35:37 +0000
committerdrh <>2025-02-21 20:35:37 +0000
commitcc803b209f2ffa9dcaad43c37eb8ccafaed199bd (patch)
treed58455eecf8e403f2ecf00a75fb28a22f8d23a2d /src/build.c
parentd9959bf48b13bffda4c073de17eb13752b9cb5c9 (diff)
downloadsqlite-cc803b209f2ffa9dcaad43c37eb8ccafaed199bd.tar.gz
sqlite-cc803b209f2ffa9dcaad43c37eb8ccafaed199bd.zip
The number of declared columns in an index is limited to SQLITE_LIMIT_COLUMN.
But the actual number of columns in the implementation might need to be twice as much to account for the primary key at the end. Ensure that the code is able to deal with this. This is a correction to check-in [d7729dbbf231d57c]. FossilOrigin-Name: 5822feec43be9352fd87bf9968c39c0218e01ab5fe3ba50431ae21cba79e6c89
Diffstat (limited to 'src/build.c')
-rw-r--r--src/build.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/src/build.c b/src/build.c
index 18bf27b83..907494b19 100644
--- a/src/build.c
+++ b/src/build.c
@@ -1067,7 +1067,7 @@ Index *sqlite3PrimaryKeyIndex(Table *pTab){
** find the (first) offset of that column in index pIdx. Or return -1
** if column iCol is not used in index pIdx.
*/
-i16 sqlite3TableColumnToIndex(Index *pIdx, int iCol){
+int sqlite3TableColumnToIndex(Index *pIdx, int iCol){
int i;
i16 iCol16;
assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN );
@@ -2175,16 +2175,15 @@ static char *createTableStmt(sqlite3 *db, Table *p){
*/
static int resizeIndexObject(Parse *pParse, Index *pIdx, int N){
char *zExtra;
- int nByte;
+ u64 nByte;
sqlite3 *db;
if( pIdx->nColumn>=N ) return SQLITE_OK;
db = pParse->db;
- if( N>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns on %s", pIdx->zName);
- return SQLITE_ERROR;
- }
+ assert( N>0 );
+ assert( N <= SQLITE_MAX_COLUMN*2 /* tag-20250221-1 */ );
+ testcase( N==2*pParse->db->aLimit[SQLITE_LIMIT_COLUMN] );
assert( pIdx->isResized==0 );
- nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N;
+ nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*(u64)N;
zExtra = sqlite3DbMallocZero(db, nByte);
if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
@@ -2198,7 +2197,7 @@ static int resizeIndexObject(Parse *pParse, Index *pIdx, int N){
zExtra += sizeof(i16)*N;
memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn);
pIdx->aSortOrder = (u8*)zExtra;
- pIdx->nColumn = N;
+ pIdx->nColumn = (u16)N; /* See tag-20250221-1 above for proof of safety */
pIdx->isResized = 1;
return SQLITE_OK;
}
@@ -3860,13 +3859,14 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
*/
Index *sqlite3AllocateIndexObject(
sqlite3 *db, /* Database connection */
- i16 nCol, /* Total number of columns in the index */
+ int nCol, /* Total number of columns in the index */
int nExtra, /* Number of bytes of extra space to alloc */
char **ppExtra /* Pointer to the "extra" space */
){
Index *p; /* Allocated index object */
i64 nByte; /* Bytes of space for Index object + arrays */
+ assert( nCol <= 2*db->aLimit[SQLITE_LIMIT_COLUMN] );
nByte = ROUND8(sizeof(Index)) + /* Index structure */
ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */
@@ -3879,8 +3879,9 @@ Index *sqlite3AllocateIndexObject(
p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
p->aSortOrder = (u8*)pExtra;
- p->nColumn = nCol;
- p->nKeyCol = nCol - 1;
+ assert( nCol>0 );
+ p->nColumn = (u16)nCol;
+ p->nKeyCol = (u16)(nCol - 1);
*ppExtra = ((char*)p) + nByte;
}
return p;