SQLite

Check-in [e6e9dd5c17]
Login

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

Overview
Comment:Fix OOM handling in sqlite3NestedParse().
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | nested-parse-oom
Files: files | file ages | folders
SHA3-256: e6e9dd5c17405a3e5547076d4004455621a318de46233312557ed9e48ebc821d
User & Date: dan 2019-02-21 18:11:12.457
Context
2019-02-21
18:11
Fix OOM handling in sqlite3NestedParse(). (Leaf check-in: e6e9dd5c17 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: c13d563925 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264


265
266
267
268
269
270
271
272


273
274
275
276
277
278
279
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  char *zErrMsg = 0;
  sqlite3 *db = pParse->db;
  char saveBuf[PARSE_TAIL_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(db, zFormat, ap);
  va_end(ap);
  if( zSql==0 ){
    return;   /* A malloc must have failed */
  }


  pParse->nested++;
  memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
  sqlite3RunParser(pParse, zSql, &zErrMsg);
  sqlite3DbFree(db, zErrMsg);
  sqlite3DbFree(db, zSql);
  memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
  pParse->nested--;


}

#if SQLITE_USER_AUTHENTICATION
/*
** Return TRUE if zTable is the name of the system table that stores the
** list of users and their access credentials.
*/







<

<






|
|
<
>
>
|
|
|
|
|
<
|
|
>
>







246
247
248
249
250
251
252

253

254
255
256
257
258
259
260
261

262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;

  sqlite3 *db = pParse->db;


  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(db, zFormat, ap);
  va_end(ap);
  assert( zSql!=0 || db->mallocFailed );
  if( db->mallocFailed==0 ){

    char *zErrMsg = 0;
    char saveBuf[PARSE_TAIL_SZ];
    pParse->nested++;
    memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
    memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
    sqlite3RunParser(pParse, zSql, &zErrMsg);
    sqlite3DbFree(db, zErrMsg);

    memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
    pParse->nested--;
  }
  sqlite3DbFree(db, zSql);
}

#if SQLITE_USER_AUTHENTICATION
/*
** Return TRUE if zTable is the name of the system table that stores the
** list of users and their access credentials.
*/
Changes to test/indexfault.test.
332
333
334
335
336
337
338










339
340
341
342
  faultsim_restore_and_reopen
  set ::nReadCall 0
  sqlite3_soft_heap_limit 0
} -body {
  execsql { CREATE INDEX i1 ON t1(x) }
  faultsim_test_result {0 {}} 
}











uninstall_custom_faultsim

finish_test







>
>
>
>
>
>
>
>
>
>




332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  faultsim_restore_and_reopen
  set ::nReadCall 0
  sqlite3_soft_heap_limit 0
} -body {
  execsql { CREATE INDEX i1 ON t1(x) }
  faultsim_test_result {0 {}} 
}

do_faultsim_test 5 -prep {
  reset_db
} -body {
  execsql { 
 CREATE TABLE reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongname(a PRIMARY KEY) WITHOUT ROWID;
  }
} -test {
  faultsim_test_result {0 {}} 
}

uninstall_custom_faultsim

finish_test