From f0693c8928161e7db8426e0e6d07de28b7e9b0ff Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Oct 2011 20:41:54 +0000 Subject: [PATCH] Put in code to defend against signed/unsigned character problems in the command-line shell. FossilOrigin-Name: b94a80a832777f0e639f6a81fcfe169bf970a8c0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 37 +++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index dd50da4e64..5fe5a99230 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scouple\sof\sasserts\strying\sto\smake\sthe\soperation\sof\s\nsqlite3SelectNew()\sclearer. -D 2011-10-11T20:14:41.773 +C Put\sin\scode\sto\sdefend\sagainst\ssigned/unsigned\scharacter\sproblems\nin\sthe\scommand-line\sshell. +D 2011-10-11T20:41:54.810 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 94b375306bfb4590fdfd76581ae663f57e94808f -F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f +F src/shell.c a07ce148dc665e4283edf878d0fb52fed2018408 F src/sqlite.h.in 821027573c481e45ba276b078a3ae9ebaeb9bb92 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 2f66bf068131f0e499dd5e0abea3f68cd6b27b2d @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P f1364004836078378e4005ab3eb9c0a04e3d4ce7 -R 3342cb35f3dfdd7fe1a8faa40e73a95e +P b21b1c7bc490b193da8d8a277489eb875a507e30 +R 7c8d9511406d6fc0a6ea749b1b39d02c U drh -Z ff666d79c8aac1b8165f8cc9911a51c1 +Z 1652abdbfcdbd0d6697e8d56e8019c87 diff --git a/manifest.uuid b/manifest.uuid index b659a6ea86..781d1198a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b21b1c7bc490b193da8d8a277489eb875a507e30 \ No newline at end of file +b94a80a832777f0e639f6a81fcfe169bf970a8c0 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 48933bc790..15a7b779e3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -74,6 +74,11 @@ extern int isatty(); /* True if the timer is enabled */ static int enableTimer = 0; +/* ctype macros that work with signed characters */ +#define IsSpace(X) isspace((unsigned char)X) +#define IsDigit(X) isdigit((unsigned char)X) +#define ToLower(X) (char)tolower((unsigned char)X) + #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) #include #include @@ -265,23 +270,23 @@ static void iotracePrintf(const char *zFormat, ...){ */ static int isNumber(const char *z, int *realnum){ if( *z=='-' || *z=='+' ) z++; - if( !isdigit(*z) ){ + if( !IsDigit(*z) ){ return 0; } z++; if( realnum ) *realnum = 0; - while( isdigit(*z) ){ z++; } + while( IsDigit(*z) ){ z++; } if( *z=='.' ){ z++; - if( !isdigit(*z) ) return 0; - while( isdigit(*z) ){ z++; } + if( !IsDigit(*z) ) return 0; + while( IsDigit(*z) ){ z++; } if( realnum ) *realnum = 1; } if( *z=='e' || *z=='E' ){ z++; if( *z=='+' || *z=='-' ) z++; - if( !isdigit(*z) ) return 0; - while( isdigit(*z) ){ z++; } + if( !IsDigit(*z) ) return 0; + while( IsDigit(*z) ){ z++; } if( realnum ) *realnum = 1; } return *z==0; @@ -1090,7 +1095,7 @@ static int shell_exec( if( !pStmt ){ /* this happens for a comment or white-space */ zSql = zLeftover; - while( isspace(zSql[0]) ) zSql++; + while( IsSpace(zSql[0]) ) zSql++; continue; } @@ -1170,7 +1175,7 @@ static int shell_exec( rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ zSql = zLeftover; - while( isspace(zSql[0]) ) zSql++; + while( IsSpace(zSql[0]) ) zSql++; }else if( pzErrMsg ){ *pzErrMsg = save_err_msg(db); } @@ -1441,7 +1446,7 @@ static int booleanValue(char *zArg){ int val = atoi(zArg); int j; for(j=0; zArg[j]; j++){ - zArg[j] = (char)tolower(zArg[j]); + zArg[j] = ToLower(zArg[j]); } if( strcmp(zArg,"on")==0 ){ val = 1; @@ -1467,7 +1472,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ /* Parse the input line into tokens. */ while( zLine[i] && nArg1 ){ int i; - for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]); + for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); if( strcmp(azArg[1],"sqlite_master")==0 ){ char *new_argv[2], *new_colv[2]; new_argv[0] = "CREATE TABLE sqlite_master (\n" @@ -2344,7 +2349,7 @@ static int _contains_semicolon(const char *z, int N){ */ static int _all_whitespace(const char *z){ for(; *z; z++){ - if( isspace(*(unsigned char*)z) ) continue; + if( IsSpace(z[0]) ) continue; if( *z=='/' && z[1]=='*' ){ z += 2; while( *z && (*z!='*' || z[1]!='/') ){ z++; } @@ -2369,11 +2374,11 @@ static int _all_whitespace(const char *z){ ** as is the Oracle "/". */ static int _is_command_terminator(const char *zLine){ - while( isspace(*(unsigned char*)zLine) ){ zLine++; }; + while( IsSpace(zLine[0]) ){ zLine++; }; if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){ return 1; /* Oracle */ } - if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o' + if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' && _all_whitespace(&zLine[2]) ){ return 1; /* SQL Server */ } @@ -2443,7 +2448,7 @@ static int process_input(struct callback_data *p, FILE *in){ nSqlPrior = nSql; if( zSql==0 ){ int i; - for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){} + for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} if( zLine[i]!=0 ){ nSql = strlen30(zLine); zSql = malloc( nSql+3 ); -- 2.47.2