/ Check-in [598d7358]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:If the OP_ParseSchema opcode with a non-NULL P4 operand does not parse any rows out of the sqlite_master table, that indicates that the sqlite_master table is corrupt, so raise an SQLITE_CORRUPT error.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 598d7358e7329f0de6e3defc217665909e46874258ac29592ee2fd53e6411cda
User & Date: drh 2019-01-05 21:09:37
Context
2019-01-05
21:56
Add the exprNodeCopy() routine that will safely memcpy() an Expr node that might be a size-reduced node. check-in: a874c649 user: drh tags: trunk
21:09
If the OP_ParseSchema opcode with a non-NULL P4 operand does not parse any rows out of the sqlite_master table, that indicates that the sqlite_master table is corrupt, so raise an SQLITE_CORRUPT error. check-in: 598d7358 user: drh tags: trunk
07:17
Fix two more problems with corrupt database handling in fts5. check-in: 444c7c99 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/prepare.c.

    61     61     sqlite3 *db = pData->db;
    62     62     int iDb = pData->iDb;
    63     63   
    64     64     assert( argc==3 );
    65     65     UNUSED_PARAMETER2(NotUsed, argc);
    66     66     assert( sqlite3_mutex_held(db->mutex) );
    67     67     DbClearProperty(db, iDb, DB_Empty);
           68  +  pData->nInitRow++;
    68     69     if( db->mallocFailed ){
    69     70       corruptSchema(pData, argv[0], 0);
    70     71       return 1;
    71     72     }
    72     73   
    73     74     assert( iDb>=0 && iDb<db->nDb );
    74     75     if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
................................................................................
   172    173                               "rootpage int,sql text)";
   173    174     azArg[3] = 0;
   174    175     initData.db = db;
   175    176     initData.iDb = iDb;
   176    177     initData.rc = SQLITE_OK;
   177    178     initData.pzErrMsg = pzErrMsg;
   178    179     initData.mInitFlags = mFlags;
          180  +  initData.nInitRow = 0;
   179    181     sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
   180    182     if( initData.rc ){
   181    183       rc = initData.rc;
   182    184       goto error_out;
   183    185     }
   184    186   
   185    187     /* Create a cursor to hold the database open

Changes to src/sqliteInt.h.

  3358   3358   */
  3359   3359   typedef struct {
  3360   3360     sqlite3 *db;        /* The database being initialized */
  3361   3361     char **pzErrMsg;    /* Error message stored here */
  3362   3362     int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
  3363   3363     int rc;             /* Result code stored here */
  3364   3364     u32 mInitFlags;     /* Flags controlling error messages */
         3365  +  u32 nInitRow;       /* Number of rows processed */
  3365   3366   } InitData;
  3366   3367   
  3367   3368   /*
  3368   3369   ** Allowed values for mInitFlags
  3369   3370   */
  3370   3371   #define INITFLAG_AlterTable   0x0001  /* This is a reparse after ALTER TABLE */
  3371   3372   

Changes to src/vdbe.c.

  5795   5795          db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
  5796   5796       if( zSql==0 ){
  5797   5797         rc = SQLITE_NOMEM_BKPT;
  5798   5798       }else{
  5799   5799         assert( db->init.busy==0 );
  5800   5800         db->init.busy = 1;
  5801   5801         initData.rc = SQLITE_OK;
         5802  +      initData.nInitRow = 0;
  5802   5803         assert( !db->mallocFailed );
  5803   5804         rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  5804   5805         if( rc==SQLITE_OK ) rc = initData.rc;
         5806  +      if( rc==SQLITE_OK && initData.nInitRow==0 ){
         5807  +        /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
         5808  +        ** at least one SQL statement. Any less than that indicates that
         5809  +        ** the sqlite_master table is corrupt. */
         5810  +        rc = SQLITE_CORRUPT_BKPT;
         5811  +      }
  5805   5812         sqlite3DbFreeNN(db, zSql);
  5806   5813         db->init.busy = 0;
  5807   5814       }
  5808   5815     }
  5809   5816     if( rc ){
  5810   5817       sqlite3ResetAllSchemasOfConnection(db);
  5811   5818       if( rc==SQLITE_NOMEM ){