From: drh <> Date: Sun, 23 Feb 2025 20:50:37 +0000 (+0000) Subject: Further improvements to control-character escapes in the CLI. X-Git-Tag: major-release~241^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9ba963f03530b2d0817d5b89c8e35e8b36430290;p=thirdparty%2Fsqlite.git Further improvements to control-character escapes in the CLI. FossilOrigin-Name: 9c2f974c17e3dfac78f3808fdfe916f7617cfdaa64430af38eae21bd6592e6f5 --- diff --git a/manifest b/manifest index bb780263ec..2225ae1b75 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\stoward\sVT100-safe\soutput\sfrom\sthe\sCLI\sby\sdefault. -D 2025-02-23T20:20:56.015 +C Further\simprovements\sto\scontrol-character\sescapes\sin\sthe\sCLI. +D 2025-02-23T20:50:37.078 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -782,7 +782,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 626c24b258b111f75c22107aa5614ad89810df3026f5ca071116d3fe75925c75 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c a076f7db3a0fcbd9f710d7746cfc07e0b3baadee45eb3136bedc29c598ef8f1c -F src/shell.c.in b1ee6353204a6b543a9e07d44339473db5d3b71c63ca05bbb452391948b66682 +F src/shell.c.in 46794cfa6cdd9b0bbbe35fcf7726ac1f5f7f61bb8f6578ec12ceeab5e0242108 F src/sqlite.h.in 8d4486fb28a90de818ac1e8c6206ea458e7de6bd8e0dfa3d554494f155be8c01 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2210,8 +2210,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 997391d42079783e294836f714ccd9526ecc442c8dbf8212d72cd17c67e7158a -R fb09ed0e2944dd462b4d95bf157b726f +P 44c44620e8648a4265053f194e32b3a5c65d25b4f1fff61ef9b944e7cb0ed624 +R b68c8cdbf574035092ab2e3bfafec994 U drh -Z 547baf0b0b8287880898ad372e983fdc +Z 1875645df727b6997bdc49f0eb677111 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2b72ba5769..a486e0cfcf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44c44620e8648a4265053f194e32b3a5c65d25b4f1fff61ef9b944e7cb0ed624 +9c2f974c17e3dfac78f3808fdfe916f7617cfdaa64430af38eae21bd6592e6f5 diff --git a/src/shell.c.in b/src/shell.c.in index a8ea0dd2ad..515da6adae 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1888,60 +1888,62 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ sqlite3_free(zStr); } -/* -** Find a string that is not found anywhere in z[]. Return a pointer -** to that string. -** -** Try to use zA and zB first. If both of those are already found in z[] -** then make up some string and store it in the buffer zBuf. -*/ -static const char *unused_string( - const char *z, /* Result must not appear anywhere in z */ - const char *zA, const char *zB, /* Try these first */ - char *zBuf /* Space to store a generated string */ -){ - unsigned i = 0; - if( strstr(z, zA)==0 ) return zA; - if( strstr(z, zB)==0 ) return zB; - do{ - sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++); - }while( strstr(z,zBuf)!=0 ); - return zBuf; -} - /* ** Output the given string as a quoted string using SQL quoting conventions. ** ** See also: output_quoted_escaped_string() */ -static void output_quoted_string(ShellState *p, const char *z){ +static void output_quoted_string(ShellState *p, const char *zInX){ int i; - char c; + int needUnistr = 0; + int needDblQuote = 0; + const unsigned char *z = (const unsigned char*)zInX; + unsigned char c; FILE *out = p->out; sqlite3_fsetmode(out, _O_BINARY); if( z==0 ) return; - for(i=0; (c = z[i])!=0 && c!='\''; i++){} - if( c==0 ){ + for(i=0; (c = z[i])!=0; i++){ + if( c=='\'' ){ needDblQuote = 1; } + if( c>0x1f ) continue; + if( c=='\t' || c=='\n' ) continue; + if( c=='\r' && z[i+1]=='\n' ) continue; + needUnistr = 1; + break; + } + if( needDblQuote==0 && needUnistr==0 ){ sqlite3_fprintf(out, "'%s'",z); }else{ - sqlite3_fputs("'", out); + if( needUnistr ){ + sqlite3_fputs("unistr('", out); + }else{ + sqlite3_fputs("'", out); + } while( *z ){ - for(i=0; (c = z[i])!=0 && c!='\''; i++){} - if( c=='\'' ) i++; + for(i=0; (c = z[i])!=0; i++){ + if( c=='\'' ) break; + if( c>0x1f ) continue; + if( c=='\t' || c=='\n' ) continue; + if( c=='\r' && z[i+1]=='\n' ) continue; + break; + } if( i ){ sqlite3_fprintf(out, "%.*s", i, z); z += i; } + if( c==0 ) break; if( c=='\'' ){ - sqlite3_fputs("'", out); + sqlite3_fputs("''", out); continue; - } - if( c==0 ){ - break; + }else{ + sqlite3_fprintf(out, "\\u%04x", c); } z++; } - sqlite3_fputs("'", out); + if( needUnistr ){ + sqlite3_fputs("')", out); + }else{ + sqlite3_fputs("'", out); + } } setCrlfMode(p); } @@ -1956,61 +1958,10 @@ static void output_quoted_string(ShellState *p, const char *z){ ** escape mechanism. */ static void output_quoted_escaped_string(ShellState *p, const char *z){ - int i; - char c; - FILE *out = p->out; + char *zEscaped = sqlite3_mprintf("%#Q", z); sqlite3_fsetmode(out, _O_BINARY); - for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} - if( c==0 ){ - sqlite3_fprintf(out, "'%s'",z); - }else{ - const char *zNL = 0; - const char *zCR = 0; - int nNL = 0; - int nCR = 0; - char zBuf1[20], zBuf2[20]; - for(i=0; z[i]; i++){ - if( z[i]=='\n' ) nNL++; - if( z[i]=='\r' ) nCR++; - } - if( nNL ){ - sqlite3_fputs("replace(", out); - zNL = unused_string(z, "\\n", "\\012", zBuf1); - } - if( nCR ){ - sqlite3_fputs("replace(", out); - zCR = unused_string(z, "\\r", "\\015", zBuf2); - } - sqlite3_fputs("'", out); - while( *z ){ - for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} - if( c=='\'' ) i++; - if( i ){ - sqlite3_fprintf(out, "%.*s", i, z); - z += i; - } - if( c=='\'' ){ - sqlite3_fputs("'", out); - continue; - } - if( c==0 ){ - break; - } - z++; - if( c=='\n' ){ - sqlite3_fputs(zNL, out); - continue; - } - sqlite3_fputs(zCR, out); - } - sqlite3_fputs("'", out); - if( nCR ){ - sqlite3_fprintf(out, ",'%s',char(13))", zCR); - } - if( nNL ){ - sqlite3_fprintf(out, ",'%s',char(10))", zNL); - } - } + sqlite3_fputs(zEscaped, p->out); + sqlite3_free(zEscaped); setCrlfMode(p); } @@ -4077,7 +4028,7 @@ static char *quoted_column(sqlite3_stmt *pStmt, int i){ return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i)); } case SQLITE_TEXT: { - return sqlite3_mprintf("%Q",sqlite3_column_text(pStmt,i)); + return sqlite3_mprintf("%#Q",sqlite3_column_text(pStmt,i)); } case SQLITE_BLOB: { int j;