diff options
author | dan <dan@noemail.net> | 2018-03-01 12:05:51 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2018-03-01 12:05:51 +0000 |
commit | dd8a4af8e77795f8d0982db57e3e959b7ba108ec (patch) | |
tree | 72a32f9532863192f3501c2eddff04254217c4d8 /ext/session/sqlite3session.c | |
parent | bda30ce4d82fa2f26309028e93dbacf2e7612818 (diff) | |
download | sqlite-dd8a4af8e77795f8d0982db57e3e959b7ba108ec.tar.gz sqlite-dd8a4af8e77795f8d0982db57e3e959b7ba108ec.zip |
Fix some crashes in the sqlite3changeset_apply() function that could be caused
by corrupt changeset blobs.
FossilOrigin-Name: 745a9a7fef0f28a57ea3f44899058993f6ecdedda52c81a09a4a9ce09c9004d6
Diffstat (limited to 'ext/session/sqlite3session.c')
-rw-r--r-- | ext/session/sqlite3session.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index bdecdd103..2a130c7e9 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2718,15 +2718,18 @@ static int sessionReadRecord( for(i=0; i<nCol && rc==SQLITE_OK; i++){ int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */ if( abPK && abPK[i]==0 ) continue; - rc = sessionInputBuffer(pIn, 9); + if( pIn->iNext>=pIn->nData ){ + rc = SQLITE_CORRUPT; + }else{ + rc = sessionInputBuffer(pIn, 9); + } if( rc==SQLITE_OK ){ eType = pIn->aData[pIn->iNext++]; - } - - assert( apOut[i]==0 ); - if( eType ){ - apOut[i] = sqlite3ValueNew(0); - if( !apOut[i] ) rc = SQLITE_NOMEM; + assert( apOut[i]==0 ); + if( eType ){ + apOut[i] = sqlite3ValueNew(0); + if( !apOut[i] ) rc = SQLITE_NOMEM; + } } if( rc==SQLITE_OK ){ @@ -2857,11 +2860,15 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ int nByte; int nVarint; nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol); - nCopy -= nVarint; - p->in.iNext += nVarint; - nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; - p->tblhdr.nBuf = 0; - sessionBufferGrow(&p->tblhdr, nByte, &rc); + if( p->nCol>0 ){ + nCopy -= nVarint; + p->in.iNext += nVarint; + nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; + p->tblhdr.nBuf = 0; + sessionBufferGrow(&p->tblhdr, nByte, &rc); + }else{ + rc = SQLITE_CORRUPT; + } } if( rc==SQLITE_OK ){ @@ -2939,6 +2946,13 @@ static int sessionChangesetNext( op = p->in.aData[p->in.iNext++]; } + if( p->zTab==0 ){ + /* The first record in the changeset is not a table header. Must be a + ** corrupt changeset. */ + assert( p->in.iNext==1 ); + return (p->rc = SQLITE_CORRUPT_BKPT); + } + p->op = op; p->bIndirect = p->in.aData[p->in.iNext++]; if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ @@ -3708,7 +3722,13 @@ static int sessionBindRow( if( !abPK || abPK[i] ){ sqlite3_value *pVal; (void)xValue(pIter, i, &pVal); - rc = sessionBindValue(pStmt, i+1, pVal); + if( pVal==0 ){ + /* The value in the changeset was "undefined". This indicates a + ** corrupt changeset blob. */ + rc = SQLITE_CORRUPT; + }else{ + rc = sessionBindValue(pStmt, i+1, pVal); + } } } return rc; |