Add the --safe to the CLI. Also the --nonce option and the .nonce command.
FossilOrigin-Name: c76870cb1a8e2e1389ad864c51b9f596dff21df8bb58f438f0a2cacfa63b22a4
This commit is contained in:
parent
5ced0a914e
commit
b97e2ad10a
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Correctly\spreserve\sthe\scollating\ssequence\sfor\sa\scolumn\swhen\schanging\nits\sdatatype.\s\sFix\sfor\sthe\sproblem\sreported\sby\n[forum:/forumpost/e5c76b738e|forum\spost\se5c76b738e].\s\sTest\scases\nin\sTH3.
|
||||
D 2021-08-24T17:07:44.447
|
||||
C Add\sthe\s--safe\sto\sthe\sCLI.\s\sAlso\sthe\s--nonce\soption\sand\sthe\s.nonce\scommand.
|
||||
D 2021-08-26T18:31:39.329
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -545,7 +545,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
||||
F src/resolve.c 42b94d37a54200707a95566eff4f7e8a380e32d080016b699f23bd79a73a5028
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c b2c48dfc02b486fd2da2be1605503615958ba1997d40d994c2946975d0150a31
|
||||
F src/shell.c.in f795a4ae3c35631f5edcfa754c7824ff1d8a75b23a07e22e664b50f82e826346
|
||||
F src/shell.c.in 34cc533f27d522c7c93fe38c99867c460b0b08be9c1c315dbd360ba5d865b19f
|
||||
F src/sqlite.h.in 4e977a5e2ed1a9e8987ff65a2cab5f99a4298ebf040ea5ff636e1753339ff45a
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
|
||||
@ -1922,7 +1922,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 d953646a63bf96a8e6e57fefaa60ae1487e5e4eb776fb38cd9c4ce002e74d016
|
||||
R d53f561ead2efd21aac670378e59272f
|
||||
P c7f0813cabf9d8ab367bead5ba8cf20132b8bb9274d8e47b76ad66a10517dd2a
|
||||
R 96ba0fa0400f19ae37fbb446bcbce223
|
||||
U drh
|
||||
Z c6e1ab5b9f0457c342ae407c84026d23
|
||||
Z c0d94ba9195f86107b44ea4e3e28e613
|
||||
|
@ -1 +1 @@
|
||||
c7f0813cabf9d8ab367bead5ba8cf20132b8bb9274d8e47b76ad66a10517dd2a
|
||||
c76870cb1a8e2e1389ad864c51b9f596dff21df8bb58f438f0a2cacfa63b22a4
|
124
src/shell.c.in
124
src/shell.c.in
@ -1104,6 +1104,8 @@ struct ShellState {
|
||||
u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
|
||||
u8 nEqpLevel; /* Depth of the EQP output graph */
|
||||
u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
|
||||
u8 bSafeMode; /* True to prohibit unsafe operations */
|
||||
u8 bSafeModePersist; /* The long-term value of bSafeMode */
|
||||
unsigned statsOn; /* True to display memory stats before each finalize */
|
||||
unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
|
||||
int outCount; /* Revert to stdout when reaching zero */
|
||||
@ -1155,8 +1157,9 @@ struct ShellState {
|
||||
int *aiIndent; /* Array of indents used in MODE_Explain */
|
||||
int nIndent; /* Size of array aiIndent[] */
|
||||
int iIndent; /* Index of current op in aiIndent[] */
|
||||
char *zNonce; /* Nonce for temporary safe-mode excapes */
|
||||
EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
|
||||
ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
|
||||
ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
|
||||
};
|
||||
|
||||
|
||||
@ -1292,6 +1295,27 @@ static void shellPutsFunc(
|
||||
sqlite3_result_value(pCtx, apVal[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
** If in safe mode, print an error message described by the arguments
|
||||
** and exit immediately.
|
||||
*/
|
||||
static void failIfSafeMode(
|
||||
ShellState *p,
|
||||
const char *zErrMsg,
|
||||
...
|
||||
){
|
||||
if( p->bSafeMode ){
|
||||
va_list ap;
|
||||
char *zMsg;
|
||||
va_start(ap, zErrMsg);
|
||||
zMsg = sqlite3_vmprintf(zErrMsg, ap);
|
||||
va_end(ap);
|
||||
raw_printf(stderr, "line %d: ", p->lineno);
|
||||
utf8_printf(stderr, "%s\n", zMsg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** SQL function: edit(VALUE)
|
||||
** edit(VALUE,EDITOR)
|
||||
@ -1769,6 +1793,49 @@ static BOOL WINAPI ConsoleCtrlHandler(
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
/*
|
||||
** This authorizer runs in safe mode.
|
||||
*/
|
||||
static int safeModeAuth(
|
||||
void *pClientData,
|
||||
int op,
|
||||
const char *zA1,
|
||||
const char *zA2,
|
||||
const char *zA3,
|
||||
const char *zA4
|
||||
){
|
||||
ShellState *p = (ShellState*)pClientData;
|
||||
static const char *azProhibitedFunctions[] = {
|
||||
"edit",
|
||||
"fts3_tokenizer",
|
||||
"load_extension",
|
||||
"readfile",
|
||||
"writefile",
|
||||
"zipfile",
|
||||
"zipfile_cds",
|
||||
};
|
||||
UNUSED_PARAMETER(zA2);
|
||||
UNUSED_PARAMETER(zA3);
|
||||
UNUSED_PARAMETER(zA4);
|
||||
switch( op ){
|
||||
case SQLITE_ATTACH: {
|
||||
failIfSafeMode(p, "cannot run ATTACH in safe mode");
|
||||
break;
|
||||
}
|
||||
case SQLITE_FUNCTION: {
|
||||
int i;
|
||||
for(i=0; i<ArraySize(azProhibitedFunctions); i++){
|
||||
if( sqlite3_stricmp(zA1, azProhibitedFunctions[i])==0 ){
|
||||
failIfSafeMode(p, "cannot use the %s() function in safe mode",
|
||||
azProhibitedFunctions[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** When the ".auth ON" is set, the following authorizer callback is
|
||||
** invoked. It always returns SQLITE_OK.
|
||||
@ -1811,6 +1878,7 @@ static int shellAuth(
|
||||
}
|
||||
}
|
||||
raw_printf(p->out, "\n");
|
||||
if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
@ -3984,6 +4052,7 @@ static const char *(azHelp[]) = {
|
||||
" table ASCII-art table",
|
||||
" tabs Tab-separated values",
|
||||
" tcl TCL list elements",
|
||||
".nonce STRING Disable safe mode for one command if the nonce matches",
|
||||
".nullvalue STRING Use STRING in place of NULL values",
|
||||
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
|
||||
" If FILE begins with '|' then open as a pipe",
|
||||
@ -4698,6 +4767,9 @@ static void open_db(ShellState *p, int openFlags){
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if( p->bSafeModePersist && p->db!=0 ){
|
||||
sqlite3_set_authorizer(p->db, safeModeAuth, p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -7461,6 +7533,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
open_db(p, 0);
|
||||
if( booleanValue(azArg[1]) ){
|
||||
sqlite3_set_authorizer(p->db, shellAuth, p);
|
||||
}else if( p->bSafeModePersist ){
|
||||
sqlite3_set_authorizer(p->db, safeModeAuth, p);
|
||||
}else{
|
||||
sqlite3_set_authorizer(p->db, 0, 0);
|
||||
}
|
||||
@ -7470,6 +7544,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
||||
if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
|
||||
open_db(p, 0);
|
||||
failIfSafeMode(p, "cannot run .archive in safe mode");
|
||||
rc = arDotCommand(p, 0, azArg, nArg);
|
||||
}else
|
||||
#endif
|
||||
@ -7484,6 +7559,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int j;
|
||||
int bAsync = 0;
|
||||
const char *zVfs = 0;
|
||||
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
|
||||
for(j=1; j<nArg; j++){
|
||||
const char *z = azArg[j];
|
||||
if( z[0]=='-' ){
|
||||
@ -7572,6 +7648,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
|
||||
if( c=='c' && strcmp(azArg[0],"cd")==0 ){
|
||||
failIfSafeMode(p, "cannot run .cd in safe mode");
|
||||
if( nArg==2 ){
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
|
||||
@ -7625,6 +7702,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
|
||||
if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
|
||||
failIfSafeMode(p, "cannot run .clone in safe mode");
|
||||
if( nArg==2 ){
|
||||
tryToClone(p, azArg[1]);
|
||||
}else{
|
||||
@ -8186,6 +8264,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int nSkip = 0; /* Initial lines to skip */
|
||||
int useOutputMode = 1; /* Use output mode to determine separators */
|
||||
|
||||
failIfSafeMode(p, "cannot run .import in safe mode");
|
||||
memset(&sCtx, 0, sizeof(sCtx));
|
||||
if( p->mode==MODE_Ascii ){
|
||||
xRead = ascii_read_one_field;
|
||||
@ -8637,6 +8716,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
|
||||
const char *zFile, *zProc;
|
||||
char *zErrMsg = 0;
|
||||
failIfSafeMode(p, "cannot run .load in safe mode");
|
||||
if( nArg<2 ){
|
||||
raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
|
||||
rc = 1;
|
||||
@ -8655,6 +8735,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#endif
|
||||
|
||||
if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
|
||||
failIfSafeMode(p, "cannot run .log in safe mode");
|
||||
if( nArg!=2 ){
|
||||
raw_printf(stderr, "Usage: .log FILENAME\n");
|
||||
rc = 1;
|
||||
@ -8725,6 +8806,19 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
p->cMode = p->mode;
|
||||
}else
|
||||
|
||||
if( c=='n' && strcmp(azArg[0], "nonce")==0 ){
|
||||
if( nArg!=2 ){
|
||||
raw_printf(stderr, "Usage: .nonce NONCE\n");
|
||||
rc = 1;
|
||||
}else if( p->zNonce==0 || strcmp(azArg[1],p->zNonce)!=0 ){
|
||||
raw_printf(stderr, "line %d: incorrect nonce: \"%s\"\n", p->lineno, azArg[1]);
|
||||
exit(1);
|
||||
}
|
||||
p->bSafeMode = 0;
|
||||
return 0; /* Return immediately to bypass the safe mode reset
|
||||
** at the end of this procedure */
|
||||
}else
|
||||
|
||||
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
|
||||
@ -8816,7 +8910,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
/* If a filename is specified, try to open it first */
|
||||
if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
|
||||
if( newFlag ) shellDeleteFile(zNewFilename);
|
||||
if( newFlag && !p->bSafeMode ) shellDeleteFile(zNewFilename);
|
||||
if( p->bSafeMode
|
||||
&& p->openMode!=SHELL_OPEN_HEXDB
|
||||
&& zNewFilename
|
||||
&& strcmp(zNewFilename,":memory:")!=0
|
||||
){
|
||||
failIfSafeMode(p, "cannot open disk-based database files in safe mode");
|
||||
}
|
||||
p->pAuxDb->zDbFilename = zNewFilename;
|
||||
open_db(p, OPEN_DB_KEEPALIVE);
|
||||
if( p->db==0 ){
|
||||
@ -8844,6 +8945,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int bBOM = 0;
|
||||
int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
|
||||
|
||||
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
|
||||
if( c=='e' ){
|
||||
eMode = 'x';
|
||||
bOnce = 2;
|
||||
@ -9116,6 +9218,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
|
||||
FILE *inSaved = p->in;
|
||||
int savedLineno = p->lineno;
|
||||
failIfSafeMode(p, "cannot run .read in safe mode");
|
||||
if( nArg!=2 ){
|
||||
raw_printf(stderr, "Usage: .read FILE\n");
|
||||
rc = 1;
|
||||
@ -9154,6 +9257,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_backup *pBackup;
|
||||
int nTimeout = 0;
|
||||
|
||||
failIfSafeMode(p, "cannot run .restore in safe mode");
|
||||
if( nArg==2 ){
|
||||
zSrcFile = azArg[1];
|
||||
zDb = "main";
|
||||
@ -9403,6 +9507,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
*/
|
||||
if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
|
||||
FILE *out = 0;
|
||||
failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]);
|
||||
if( nCmd!=2 ) goto session_syntax_error;
|
||||
if( pSession->p==0 ) goto session_not_open;
|
||||
out = fopen(azCmd[1], "wb");
|
||||
@ -9817,6 +9922,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
){
|
||||
char *zCmd;
|
||||
int i, x;
|
||||
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
|
||||
if( nArg<2 ){
|
||||
raw_printf(stderr, "Usage: .system COMMAND\n");
|
||||
rc = 1;
|
||||
@ -10488,6 +10594,7 @@ meta_command_exit:
|
||||
p->outCount--;
|
||||
if( p->outCount==0 ) output_reset(p);
|
||||
}
|
||||
p->bSafeMode = p->bSafeModePersist;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -10685,6 +10792,7 @@ static int process_input(ShellState *p){
|
||||
}else{
|
||||
clearTempFile(p);
|
||||
}
|
||||
p->bSafeMode = p->bSafeModePersist;
|
||||
}else if( nSql && _all_whitespace(zSql) ){
|
||||
if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
|
||||
nSql = 0;
|
||||
@ -10851,10 +10959,12 @@ static const char zOptions[] =
|
||||
#endif
|
||||
" -newline SEP set output row separator. Default: '\\n'\n"
|
||||
" -nofollow refuse to open symbolic links to database files\n"
|
||||
" -nonce STRING set the safe-mode escape nonce\n"
|
||||
" -nullvalue TEXT set text string for NULL values. Default ''\n"
|
||||
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
|
||||
" -quote set output mode to 'quote'\n"
|
||||
" -readonly open the database read-only\n"
|
||||
" -safe enable safe-mode\n"
|
||||
" -separator SEP set output column separator. Default: '|'\n"
|
||||
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
||||
" -sorterref SIZE sorter references threshold size\n"
|
||||
@ -11200,6 +11310,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
sqlite3MemTraceActivate(stderr);
|
||||
}else if( strcmp(z,"-bail")==0 ){
|
||||
bail_on_error = 1;
|
||||
}else if( strcmp(z,"-nonce")==0 ){
|
||||
free(data.zNonce);
|
||||
data.zNonce = strdup(argv[++i]);
|
||||
}else if( strcmp(z,"-safe")==0 ){
|
||||
/* no-op - catch this on the second pass */
|
||||
}
|
||||
}
|
||||
verify_uninitialized();
|
||||
@ -11362,6 +11477,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
i+=2;
|
||||
}else if( strcmp(z,"-threadsafe")==0 ){
|
||||
i+=2;
|
||||
}else if( strcmp(z,"-nonce")==0 ){
|
||||
i += 2;
|
||||
}else if( strcmp(z,"-mmap")==0 ){
|
||||
i++;
|
||||
}else if( strcmp(z,"-memtrace")==0 ){
|
||||
@ -11420,6 +11537,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
readStdin = 0;
|
||||
break;
|
||||
#endif
|
||||
}else if( strcmp(z,"-safe")==0 ){
|
||||
data.bSafeMode = data.bSafeModePersist = 1;
|
||||
}else{
|
||||
utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
|
||||
raw_printf(stderr,"Use -help for a list of options.\n");
|
||||
@ -11522,6 +11641,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
free(argvToFree);
|
||||
#endif
|
||||
free(data.colWidth);
|
||||
free(data.zNonce);
|
||||
/* Clear the global data structure so that valgrind will detect memory
|
||||
** leaks */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
Loading…
x
Reference in New Issue
Block a user