From: drh <> Date: Thu, 16 Dec 2021 13:29:28 +0000 (+0000) Subject: Add more tests for OOM conditions in the CLI. X-Git-Tag: version-3.38.0~174 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3e2565daa2d7f6c325b91304919b5b5b3effce4;p=thirdparty%2Fsqlite.git Add more tests for OOM conditions in the CLI. FossilOrigin-Name: b6fa402d159b2475a7b99ef6a5180d7bf800f90afe28cea726d346d071405045 --- diff --git a/manifest b/manifest index 9ffb0be7d0..e2a8249a6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sgeneration\sof\sthe\ssqlite3_index_info\sobject\sduring\squery\splanning\nfor\svirtual\stables. -D 2021-12-15T20:48:15.594 +C Add\smore\stests\sfor\sOOM\sconditions\sin\sthe\sCLI. +D 2021-12-16T13:29:28.610 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 4a1db4aadd802683db40ca2dbbb268187bd195f10cbdb7206dbd8ac988795571 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c a7a3d9f54eb24821ec5f67f2e5589b68a5d42d46fc5849d7376886777d93a85a -F src/shell.c.in 239bee1085d94964f02582b0714dc3fc85cfc16e27e95813e4dbc24bb215a7e0 +F src/shell.c.in 487402a1242eda123a7765415765c2ba5fd80b251af968ac5cd753a21361dca7 F src/sqlite.h.in 5999d6db0e65afbd686b76cddc385b310aa3815624edba43987913067f50e209 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8ff2fd2c166150b2e48639f5e506fb44e29f1a3f65031710b9e89d1c126ac839 @@ -1934,7 +1934,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c3d398d20b86a1558720e995eddf11403aec2d160590571fa9525fe8f6efff9 -R 508a1ec856c9c59ad14d9d50f3ec0f6a +P 241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19 +R c242be18b9914b844987d57ba93b7d7b U drh -Z 7cfa744adc9adca884cde06b49136ec0 +Z 275dad0e920745aee275fd4bee05334a diff --git a/manifest.uuid b/manifest.uuid index b41eacb4bb..47e19b4667 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19 \ No newline at end of file +b6fa402d159b2475a7b99ef6a5180d7bf800f90afe28cea726d346d071405045 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 3262f98c12..7cabf94ec2 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -487,6 +487,13 @@ static void shell_out_of_memory(void){ exit(1); } +/* Check a pointer to see if it is NULL. If it is NULL, exit with an +** out-of-memory error. +*/ +static void shell_check_oom(void *p){ + if( p==0 ) shell_out_of_memory(); +} + #ifdef SQLITE_DEBUG /* This routine is called when a simulated OOM occurs. It is broken ** out as a separate routine to make it easy to set a breakpoint on @@ -685,7 +692,7 @@ static char *local_getline(char *zLine, FILE *in){ if( n+100>nLine ){ nLine = nLine*2 + 100; zLine = realloc(zLine, nLine); - if( zLine==0 ) shell_out_of_memory(); + shell_check_oom(zLine); } if( fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ @@ -712,7 +719,7 @@ static char *local_getline(char *zLine, FILE *in){ int nTrans = strlen30(zTrans)+1; if( nTrans>nLine ){ zLine = realloc(zLine, nTrans); - if( zLine==0 ) shell_out_of_memory(); + shell_check_oom(zLine); } memcpy(zLine, zTrans, nTrans); sqlite3_free(zTrans); @@ -859,7 +866,7 @@ static void appendText(ShellText *p, char const *zAppend, char quote){ if( p->z==0 || p->n+len>=p->nAlloc ){ p->nAlloc = p->nAlloc*2 + len + 20; p->z = realloc(p->z, p->nAlloc); - if( p->z==0 ) shell_out_of_memory(); + shell_check_oom(p->z); } if( quote ){ @@ -914,6 +921,7 @@ static char *shellFakeSchema( zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;", zSchema ? zSchema : "main", zName); + shell_check_oom(zSql); sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); initText(&s); @@ -1775,6 +1783,7 @@ static void output_csv(ShellState *p, const char *z, int bSep){ } if( i==0 || strstr(z, p->colSeparator)!=0 ){ char *zQuoted = sqlite3_mprintf("\"%w\"", z); + shell_check_oom(zQuoted); utf8_printf(out, "%s", zQuoted); sqlite3_free(zQuoted); }else{ @@ -1949,7 +1958,7 @@ static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); } pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); - if( pNew==0 ) shell_out_of_memory(); + shell_check_oom(pNew); pNew->iEqpId = iEqpId; pNew->iParentId = p2; memcpy(pNew->zText, zText, nText+1); @@ -2170,6 +2179,7 @@ static int shell_callback( break; } z = sqlite3_mprintf("%s", azArg[0]); + shell_check_oom(z); j = 0; for(i=0; IsSpace(z[i]); i++){} for(; (c = z[i])!=0; i++){ @@ -2301,6 +2311,7 @@ static int shell_callback( if( i>0 ) raw_printf(p->out, ","); if( quoteChar(azCol[i]) ){ char *z = sqlite3_mprintf("\"%w\"", azCol[i]); + shell_check_oom(z); utf8_printf(p->out, "%s", z); sqlite3_free(z); }else{ @@ -2546,7 +2557,7 @@ static void set_table_name(ShellState *p, const char *zName){ n = strlen30(zName); if( cQuote ) n += n+2; z = p->zDestTable = malloc( n+1 ); - if( z==0 ) shell_out_of_memory(); + shell_check_oom(z); n = 0; if( cQuote ) z[n++] = cQuote; for(i=0; zName[i]; i++){ @@ -2618,9 +2629,11 @@ static char *save_err_msg( const char *zWhen, /* Qualifier (format) wrapper */ int rc /* Error code returned from API */ ){ - if( zWhen==0 ) - zWhen = "%s (%d)"; - return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc); + char *zErr; + if( zWhen==0 ) zWhen = "%s (%d)"; + zErr = sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc); + shell_check_oom(zErr); + return zErr; } #ifdef __linux__ @@ -2968,9 +2981,9 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ } nAlloc += 100; p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); - if( p->aiIndent==0 ) shell_out_of_memory(); + shell_check_oom(p->aiIndent); abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); - if( abYield==0 ) shell_out_of_memory(); + shell_check_oom(abYield); } abYield[iOp] = str_in_array(zOp, azYield); p->aiIndent[iOp] = 0; @@ -3179,7 +3192,7 @@ static void exec_prepared_stmt_columnar( nAlloc = nColumn*4; if( nAlloc<=0 ) nAlloc = 1; azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); - if( azData==0 ) shell_out_of_memory(); + shell_check_oom(azData); for(i=0; i= nAlloc ){ nAlloc *= 2; azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*)); - if( azData==0 ) shell_out_of_memory(); + shell_check_oom(azData); } nRow++; for(i=0; ip->nWidth ){ p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int)); - if( p->colWidth==0 ) shell_out_of_memory(); + shell_check_oom(p->colWidth); for(i=p->nWidth; icolWidth[i] = 0; p->nWidth = nColumn; p->actualWidth = &p->colWidth[nColumn]; @@ -3588,6 +3601,7 @@ static int shell_exec( sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); } zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); + shell_check_oom(zEQP); rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc==SQLITE_OK ){ while( sqlite3_step(pExplain)==SQLITE_ROW ){ @@ -3605,6 +3619,7 @@ static int shell_exec( if( pArg->autoEQP>=AUTOEQP_full ){ /* Also do an EXPLAIN for ".eqp full" mode */ zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); + shell_check_oom(zEQP); rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc==SQLITE_OK ){ pArg->cMode = MODE_Explain; @@ -3717,6 +3732,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ int rc; zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); + shell_check_oom(zSql); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ) return 0; @@ -3724,9 +3740,10 @@ static char **tableColumnList(ShellState *p, const char *zTab){ if( nCol>=nAlloc-2 ){ nAlloc = nAlloc*2 + nCol + 10; azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); - if( azCol==0 ) shell_out_of_memory(); + shell_check_oom(azCol); } azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); + shell_check_oom(azCol[nCol]); if( sqlite3_column_int(pStmt, 5) ){ nPK++; if( nPK==1 @@ -3760,6 +3777,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ */ zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" " WHERE origin='pk'", zTab); + shell_check_oom(zSql); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ){ @@ -3851,6 +3869,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)" "VALUES('table','%q','%q',0,'%q');", zTable, zTable, zSql); + shell_check_oom(zIns); utf8_printf(p->out, "%s\n", zIns); sqlite3_free(zIns); return 0; @@ -4252,6 +4271,7 @@ static int showHelp(FILE *out, const char *zPattern){ }else{ /* Look for commands that for which zPattern is an exact prefix */ zPat = sqlite3_mprintf(".%s*", zPattern); + shell_check_oom(zPat); for(i=0; i65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ a = sqlite3_malloc( n ? n : 1 ); - if( a==0 ){ - utf8_printf(stderr, "Out of memory!\n"); - goto readHexDb_error; - } + shell_check_oom(a); memset(a, 0, n); if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ utf8_printf(stderr, "invalid pagesize\n"); @@ -4773,6 +4791,7 @@ static void open_db(ShellState *p, int openFlags){ if( p->openMode==SHELL_OPEN_ZIPFILE ){ char *zSql = sqlite3_mprintf( "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename); + shell_check_oom(zSql); sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } @@ -4830,6 +4849,7 @@ static char *readline_completion_generator(const char *text, int state){ sqlite3_finalize(pStmt); zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" " FROM completion(%Q) ORDER BY 1", text); + shell_check_oom(zSql); sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); sqlite3_free(zSql); } @@ -4867,6 +4887,7 @@ static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" " FROM completion(%Q,%Q) ORDER BY 1", &zLine[iStart], zLine); + shell_check_oom(zSql); sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); sqlite3_free(zSql); sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */ @@ -5108,7 +5129,7 @@ static void import_append_char(ImportCtx *p, int c){ if( p->n+1>=p->nAlloc ){ p->nAlloc += p->nAlloc + 100; p->z = sqlite3_realloc64(p->z, p->nAlloc); - if( p->z==0 ) shell_out_of_memory(); + shell_check_oom(p->z); } p->z[p->n++] = (char)c; } @@ -5260,6 +5281,7 @@ static void tryToCloneData( const int spinRate = 10000; zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); + shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ utf8_printf(stderr, "Error %d: %s on [%s]\n", @@ -5269,7 +5291,7 @@ static void tryToCloneData( } n = sqlite3_column_count(pQuery); zInsert = sqlite3_malloc64(200 + nTable + n*3); - if( zInsert==0 ) shell_out_of_memory(); + shell_check_oom(zInsert); sqlite3_snprintf(200+nTable,zInsert, "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); i = strlen30(zInsert); @@ -5332,6 +5354,7 @@ static void tryToCloneData( sqlite3_free(zQuery); zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;", zTable); + shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable); @@ -5368,6 +5391,7 @@ static void tryToCloneSchema( zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" " WHERE %s", zWhere); + shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ utf8_printf(stderr, "Error: (%d) %s on [%s]\n", @@ -5395,6 +5419,7 @@ static void tryToCloneSchema( sqlite3_free(zQuery); zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" " WHERE %s ORDER BY rowid DESC", zWhere); + shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ utf8_printf(stderr, "Error: (%d) %s on [%s]\n", @@ -5789,9 +5814,7 @@ static void newTempFile(ShellState *p, const char *zSuffix){ }else{ p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix); } - if( p->zTempFile==0 ){ - shell_out_of_memory(); - } + shell_check_oom(p->zTempFile); } @@ -7864,7 +7887,7 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); const char *zFile = (const char*)sqlite3_column_text(pStmt,2); azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*)); - if( azName==0 ){ shell_out_of_memory(); /* Does not return */ } + shell_check_oom(azName); azName[nName*2] = strdup(zSchema); azName[nName*2+1] = strdup(zFile); nName++; @@ -9076,7 +9099,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else if( zFile==0 && eMode!='e' && eMode!='x' ){ zFile = sqlite3_mprintf("%s", z); - if( zFile[0]=='|' ){ + if( zFile && zFile[0]=='|' ){ while( i+1outCount = 2; }else{ @@ -9116,6 +9141,7 @@ static int do_meta_command(char *zLine, ShellState *p){ zFile = sqlite3_mprintf("%s", p->zTempFile); } #endif /* SQLITE_NOHAVE_SYSTEM */ + shell_check_oom(zFile); if( zFile[0]=='|' ){ #ifdef SQLITE_OMIT_POPEN raw_printf(stderr, "Error: pipes are not supported in this OS\n"); @@ -9212,7 +9238,7 @@ static int do_meta_command(char *zLine, ShellState *p){ zSql = sqlite3_mprintf( "REPLACE INTO temp.sqlite_parameters(key,value)" "VALUES(%Q,%s);", zKey, zValue); - if( zSql==0 ) shell_out_of_memory(); + shell_check_oom(zSql); pStmt = 0; rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); @@ -9222,7 +9248,7 @@ static int do_meta_command(char *zLine, ShellState *p){ zSql = sqlite3_mprintf( "REPLACE INTO temp.sqlite_parameters(key,value)" "VALUES(%Q,%Q);", zKey, zValue); - if( zSql==0 ) shell_out_of_memory(); + shell_check_oom(zSql); rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rx!=SQLITE_OK ){ @@ -9243,7 +9269,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 && strcmp(azArg[1],"unset")==0 ){ char *zSql = sqlite3_mprintf( "DELETE FROM temp.sqlite_parameters WHERE key=%Q", azArg[2]); - if( zSql==0 ) shell_out_of_memory(); + shell_check_oom(zSql); sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); }else @@ -9469,6 +9495,7 @@ static int do_meta_command(char *zLine, ShellState *p){ " rootpage integer,\n" " sql text\n" ")", zName); + shell_check_oom(new_argv[0]); new_argv[1] = 0; new_colv[0] = "sql"; new_colv[1] = 0; @@ -9520,6 +9547,7 @@ static int do_meta_command(char *zLine, ShellState *p){ appendText(&sSelect, ") WHERE ", 0); if( zName ){ char *zQarg = sqlite3_mprintf("%Q", zName); + shell_check_oom(zQarg); int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || strchr(zName, '[') != 0; if( strchr(zName, '.') ){ @@ -9684,7 +9712,8 @@ static int do_meta_command(char *zLine, ShellState *p){ exit(1); } for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); + char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); + shell_check_oom(x); } pSession->nFilter = ii-1; } @@ -9756,6 +9785,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3session_table_filter(pSession->p, session_filter, pSession); pAuxDb->nSession++; pSession->zName = sqlite3_mprintf("%s", zName); + shell_check_oom(pSession->zName); }else /* If no command name matches, show a syntax error */ session_syntax_error: @@ -9851,9 +9881,7 @@ static int do_meta_command(char *zLine, ShellState *p){ k = 0; if( bVerbose>0 ){ - char *zQuote = sqlite3_mprintf("%q", zSql); printf("%d: %s %s\n", tno, zOp, zSql); - sqlite3_free(zQuote); } if( strcmp(zOp,"memo")==0 ){ utf8_printf(p->out, "%s\n", zSql); @@ -10011,6 +10039,7 @@ static int do_meta_command(char *zLine, ShellState *p){ " FROM [sha3sum$query]", sSql.z, iSize); } + shell_check_oom(zSql); freeText(&sQuery); freeText(&sSql); if( bDebug ){ @@ -10034,11 +10063,11 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); - for(i=2; i>1)+nLine+100; zSql = realloc(zSql, nAlloc); - if( zSql==0 ) shell_out_of_memory(); + shell_check_oom(zSql); } if( nSql==0 ){ int i; @@ -11080,6 +11109,7 @@ static void process_sqliterc( return; } zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); + shell_check_oom(zBuf); sqliterc = zBuf; } p->in = fopen(sqliterc,"rb"); @@ -11321,16 +11351,16 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #if !SQLITE_SHELL_IS_UTF8 sqlite3_initialize(); argvToFree = malloc(sizeof(argv[0])*argc*2); + shell_check_oom(argvToFree); argcToFree = argc; argv = argvToFree + argc; - if( argv==0 ) shell_out_of_memory(); for(i=0; i