Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix some crashes in the sqlite3changeset_apply() function that could be caused by corrupt changeset blobs. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
745a9a7fef0f28a57ea3f44899058993 |
User & Date: | dan 2018-03-01 12:05:51.293 |
Context
2018-03-01
| ||
15:20 | Fix further crashes in sqlite3changeset_apply() caused by corrupt changeset blobs. (check-in: 2c01c72e35 user: dan tags: trunk) | |
13:44 | Merge the latest enhancements from trunk. (check-in: c8083de14b user: drh tags: memdb) | |
12:05 | Fix some crashes in the sqlite3changeset_apply() function that could be caused by corrupt changeset blobs. (check-in: 745a9a7fef user: dan tags: trunk) | |
2018-02-28
| ||
22:21 | Enhance the sessions documentation to show the methods of the various objects. (check-in: e01177754a user: drh tags: trunk) | |
Changes
Changes to ext/session/session4.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 66 67 | list [catch { sqlite3changeset_invert $x } msg] $msg } {1 SQLITE_CORRUPT} do_test 1.3 { set x [binary format "ca*" 0 [string range $changeset 1 end]] list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg } {1 SQLITE_CORRUPT} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | list [catch { sqlite3changeset_invert $x } msg] $msg } {1 SQLITE_CORRUPT} do_test 1.3 { set x [binary format "ca*" 0 [string range $changeset 1 end]] list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg } {1 SQLITE_CORRUPT} #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d); CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g); CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y); CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID; } foreach {tn blob} { 1 {54010174340012000000} 2 {54fefe8bcb0012000300} 3 {5480809280808001017434001200fb} 4 {50af9c939c9c9cb09c9c6400b09c9c6400} 5 {12000300} 6 {09847304} 7 {5401017434001208} } { if {$tn==7} breakpoint do_test 2.$tn { set changeset [binary decode hex $blob] list [catch { sqlite3changeset_apply db $changeset xConflict } msg] $msg } {1 SQLITE_CORRUPT} } finish_test |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
2714 2715 2716 2717 2718 2719 2720 | ){ int i; /* Used to iterate through columns */ int rc = SQLITE_OK; 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; | > > > | > < < | | | | > | 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 | ){ int i; /* Used to iterate through columns */ int rc = SQLITE_OK; 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; 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; } } if( rc==SQLITE_OK ){ u8 *aVal = &pIn->aData[pIn->iNext]; if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ int nByte; pIn->iNext += sessionVarintGet(aVal, &nByte); |
︙ | ︙ | |||
2853 2854 2855 2856 2857 2858 2859 | assert( p->rc==SQLITE_OK ); rc = sessionChangesetBufferTblhdr(&p->in, &nCopy); if( rc==SQLITE_OK ){ int nByte; int nVarint; nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol); | > | | | | | > > > | 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 | assert( p->rc==SQLITE_OK ); rc = sessionChangesetBufferTblhdr(&p->in, &nCopy); if( rc==SQLITE_OK ){ int nByte; int nVarint; nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol); 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 ){ int iPK = sizeof(sqlite3_value*)*p->nCol*2; memset(p->tblhdr.aBuf, 0, iPK); memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy); p->in.iNext += nCopy; |
︙ | ︙ | |||
2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 | p->bPatchset = (op=='P'); if( sessionChangesetReadTblhdr(p) ) return p->rc; if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; p->in.iCurrent = p->in.iNext; if( p->in.iNext>=p->in.nData ) return SQLITE_DONE; op = p->in.aData[p->in.iNext++]; } p->op = op; p->bIndirect = p->in.aData[p->in.iNext++]; if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ return (p->rc = SQLITE_CORRUPT_BKPT); } | > > > > > > > | 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 | p->bPatchset = (op=='P'); if( sessionChangesetReadTblhdr(p) ) return p->rc; if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; p->in.iCurrent = p->in.iNext; if( p->in.iNext>=p->in.nData ) return SQLITE_DONE; 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 ){ return (p->rc = SQLITE_CORRUPT_BKPT); } |
︙ | ︙ | |||
3704 3705 3706 3707 3708 3709 3710 | ** in the code below. */ assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new ); for(i=0; rc==SQLITE_OK && i<nCol; i++){ if( !abPK || abPK[i] ){ sqlite3_value *pVal; (void)xValue(pIter, i, &pVal); | > > > > > | > | 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 | ** in the code below. */ assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new ); for(i=0; rc==SQLITE_OK && i<nCol; i++){ if( !abPK || abPK[i] ){ sqlite3_value *pVal; (void)xValue(pIter, i, &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; } /* ** SQL statement pSelect is as generated by the sessionSelectRow() function. |
︙ | ︙ |