From 21b431e6851c5f652932b27cf67c4a541b5ea97a Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 24 Feb 2025 12:41:30 +0000 Subject: [PATCH] Ongoing work to get all the quoting and escaping variations in the CLI working correctly. FossilOrigin-Name: b77aea93e7eff0af408f598727caedcfc4428361b8440fbc1cc54c18f93abb69 --- manifest | 12 +++++------ manifest.uuid | 2 +- src/shell.c.in | 54 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 640183e406..f506fa17f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\scolumn\soutput\smodes\sin\sthe\sCLI\sresponsive\sto\sthe\s--escape\ssetting. -D 2025-02-24T00:40:36.130 +C Ongoing\swork\sto\sget\sall\sthe\squoting\sand\sescaping\svariations\sin\sthe\sCLI\nworking\scorrectly. +D 2025-02-24T12:41:30.706 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 93b115083f702bfef5b4cfabc908ff7c56275a8eb43837695940e953cd98b1d6 +F src/shell.c.in 10182a36de8c86c90c59933d9d8a41657c34ecf4b80986d1e4f508c5d39f1cb8 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 b5adb52fc0dc1838cb9c66cff422f2b8ec147e546cf909dd3c48731fa1edfe50 -R e22b9c730b45578a252088be598cc957 +P 14ff5557d450475ad959f8c753c0cecb85dfca7346fcacd91da16e4d36e30508 +R 11c66d594c249e2c939f76c526b8b2e2 U drh -Z 0141780f340c58ec2ae1b4be639dc53e +Z 582aa1340d3741b95a01f42fe569eeff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fc19a63267..3f039c96a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14ff5557d450475ad959f8c753c0cecb85dfca7346fcacd91da16e4d36e30508 +b77aea93e7eff0af408f598727caedcfc4428361b8440fbc1cc54c18f93abb69 diff --git a/src/shell.c.in b/src/shell.c.in index 401c4bcc05..6b363d1791 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1892,9 +1892,18 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ } /* -** Output the given string as a quoted string using SQL quoting conventions. +** Output the given string as a quoted string using SQL quoting conventions: +** +** (1) Single quotes (') within the string are doubled +** (2) The whle string is enclosed in '...' +** (3) Control characters other than \n, \t, and \r\n are escaped +** using \u00XX notation and if such substitutions occur, +** the whole string is enclosed in unistr('...') instead of '...'. +** +** Step (3) is omitted if the control-character escape mode is OFF. ** -** See also: output_quoted_escaped_string() +** See also: output_quoted_escaped_string() which does the same except +** that it does not make exceptions for \n, \t, and \r\n in step (3). */ static void output_quoted_string(ShellState *p, const char *zInX){ int i; @@ -1913,8 +1922,14 @@ static void output_quoted_string(ShellState *p, const char *zInX){ needUnistr = 1; break; } - if( needDblQuote==0 && needUnistr==0 ){ + if( (needDblQuote==0 && needUnistr==0) + || (needDblQuote==0 && p->eEscMode==SHELL_ESC_OFF) + ){ sqlite3_fprintf(out, "'%s'",z); + }else if( p->eEscMode==SHELL_ESC_OFF ){ + char *zEncoded = sqlite3_mprintf("%Q", z); + sqlite3_fputs(zEncoded, out); + sqlite3_free(zEncoded); }else{ if( needUnistr ){ sqlite3_fputs("unistr('", out); @@ -1936,7 +1951,6 @@ static void output_quoted_string(ShellState *p, const char *zInX){ if( c==0 ) break; if( c=='\'' ){ sqlite3_fputs("''", out); - continue; }else{ sqlite3_fprintf(out, "\\u%04x", c); } @@ -1961,8 +1975,13 @@ static void output_quoted_string(ShellState *p, const char *zInX){ ** escape mechanism. */ static void output_quoted_escaped_string(ShellState *p, const char *z){ - char *zEscaped = sqlite3_mprintf("%#Q", z); + char *zEscaped; sqlite3_fsetmode(out, _O_BINARY); + if( p->eEscMode==SHELL_ESC_OFF ){ + zEscaped = sqlite3_mprintf("%Q", z); + }else{ + zEscaped = sqlite3_mprintf("%#Q", z); + } sqlite3_fputs(zEscaped, p->out); sqlite3_free(zEscaped); setCrlfMode(p); @@ -9857,37 +9876,39 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zMode = 0; const char *zTabname = 0; int i, n2; - int chng = 0; + int chng = 0; /* 0x01: change to cmopts. 0x02: Any other change */ ColModeOpts cmOpts = ColModeOpts_default; for(i=1; ieEscMode = k; - chng = 1; + chng |= 2; break; } } if( k>=ArraySize(shell_EscModeNames) ){ - sqlite3_fprintf(stderr, "unknown escape mod \"%s\" - choices:", zEsc); + sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\"" + " - choices:", zEsc); for(k=0; kmode]; + if( (chng&1)==0 ) cmOpts = p->cmOpts; } n2 = strlen30(zMode); if( cli_strncmp(zMode,"lines",n2)==0 ){ @@ -13236,6 +13258,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ data.mode = MODE_Csv; memcpy(data.colSeparator,",",2); }else if( cli_strcmp(z,"-escape")==0 && i+1=ArraySize(shell_EscModeNames) ){ - sqlite3_fprintf(stderr, "unknown escape mode \"%s\" - choices:", zEsc); + sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\"" + " - choices:", zEsc); for(k=0; k