/ Check-in [e6e9dd5c]
Login

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

Overview
Comment:Fix OOM handling in sqlite3NestedParse().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | nested-parse-oom
Files: files | file ages | folders
SHA3-256: e6e9dd5c17405a3e5547076d4004455621a318de46233312557ed9e48ebc821d
User & Date: dan 2019-02-21 18:11:12
Context
2019-02-21
18:11
Fix OOM handling in sqlite3NestedParse(). Leaf check-in: e6e9dd5c user: dan tags: nested-parse-oom
16:41
Detect oversized strings in the OP_String opcode even if the P4 argument is originally UTF8 and has to be converted to UTF16 to match the database file and that conversion causes the string to become shorter and cross below SQLITE_LIMIT_LENGTH threshold. This might fix an OSSFuzz problem that we have been so far unable to reproduce. check-in: c13d5639 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

   246    246   ** Not everything is nestable.  This facility is designed to permit
   247    247   ** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
   248    248   ** care if you decide to try to use this routine for some other purposes.
   249    249   */
   250    250   void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
   251    251     va_list ap;
   252    252     char *zSql;
   253         -  char *zErrMsg = 0;
   254    253     sqlite3 *db = pParse->db;
   255         -  char saveBuf[PARSE_TAIL_SZ];
   256    254   
   257    255     if( pParse->nErr ) return;
   258    256     assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
   259    257     va_start(ap, zFormat);
   260    258     zSql = sqlite3VMPrintf(db, zFormat, ap);
   261    259     va_end(ap);
   262         -  if( zSql==0 ){
   263         -    return;   /* A malloc must have failed */
          260  +  assert( zSql!=0 || db->mallocFailed );
          261  +  if( db->mallocFailed==0 ){
          262  +    char *zErrMsg = 0;
          263  +    char saveBuf[PARSE_TAIL_SZ];
          264  +    pParse->nested++;
          265  +    memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
          266  +    memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
          267  +    sqlite3RunParser(pParse, zSql, &zErrMsg);
          268  +    sqlite3DbFree(db, zErrMsg);
          269  +    memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
          270  +    pParse->nested--;
   264    271     }
   265         -  pParse->nested++;
   266         -  memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
   267         -  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
   268         -  sqlite3RunParser(pParse, zSql, &zErrMsg);
   269         -  sqlite3DbFree(db, zErrMsg);
   270    272     sqlite3DbFree(db, zSql);
   271         -  memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
   272         -  pParse->nested--;
   273    273   }
   274    274   
   275    275   #if SQLITE_USER_AUTHENTICATION
   276    276   /*
   277    277   ** Return TRUE if zTable is the name of the system table that stores the
   278    278   ** list of users and their access credentials.
   279    279   */

Changes to test/indexfault.test.

   332    332     faultsim_restore_and_reopen
   333    333     set ::nReadCall 0
   334    334     sqlite3_soft_heap_limit 0
   335    335   } -body {
   336    336     execsql { CREATE INDEX i1 ON t1(x) }
   337    337     faultsim_test_result {0 {}} 
   338    338   }
          339  +
          340  +do_faultsim_test 5 -prep {
          341  +  reset_db
          342  +} -body {
          343  +  execsql { 
          344  + CREATE TABLE reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongname(a PRIMARY KEY) WITHOUT ROWID;
          345  +  }
          346  +} -test {
          347  +  faultsim_test_result {0 {}} 
          348  +}
   339    349   
   340    350   uninstall_custom_faultsim
   341    351   
   342    352   finish_test