]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Ongoing work to get all the quoting and escaping variations in the CLI
authordrh <>
Mon, 24 Feb 2025 12:41:30 +0000 (12:41 +0000)
committerdrh <>
Mon, 24 Feb 2025 12:41:30 +0000 (12:41 +0000)
working correctly.

FossilOrigin-Name: b77aea93e7eff0af408f598727caedcfc4428361b8440fbc1cc54c18f93abb69

manifest
manifest.uuid
src/shell.c.in

index 640183e40695b17559de1367218cbf10dca297f8..f506fa17f2cd54bdcb7057eafdee900274eadcfd 100644 (file)
--- 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.
index fc19a63267492ef4d86477059ccfb5a50fa12b0c..3f039c96a335042eac3761730884eec76b66ef6a 100644 (file)
@@ -1 +1 @@
-14ff5557d450475ad959f8c753c0cecb85dfca7346fcacd91da16e4d36e30508
+b77aea93e7eff0af408f598727caedcfc4428361b8440fbc1cc54c18f93abb69
index 401c4bcc0522f37ad3579797a30d5de001d80d15..6b363d1791784ae4acb0f61b1e2026dbabeee3da 100644 (file)
@@ -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; i<nArg; i++){
       const char *z = azArg[i];
       if( optionMatch(z,"wrap") && i+1<nArg ){
         cmOpts.iWrap = integerValue(azArg[++i]);
-        chng = 1;
+        chng |= 1;
       }else if( optionMatch(z,"ww") ){
         cmOpts.bWordWrap = 1;
-        chng = 1;
+        chng |= 1;
       }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
         cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
-        chng = 1;
+        chng |= 1;
       }else if( optionMatch(z,"quote") ){
         cmOpts.bQuote = 1;
-        chng = 1;
+        chng |= 1;
       }else if( optionMatch(z,"noquote") ){
         cmOpts.bQuote = 0;
-        chng = 1;
+        chng |= 1;
       }else if( optionMatch(z,"escape") && i+1<nArg ){
+        /* See similar code at tag-20250224-1 */
         const char *zEsc = azArg[++i];
         int k;
         for(k=0; k<ArraySize(shell_EscModeNames); k++){
           if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){
             p->eEscMode = 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; k<ArraySize(shell_EscModeNames); k++){
             sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]);
           }
@@ -9900,7 +9921,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         /* Apply defaults for qbox pseudo-mode.  If that
          * overwrites already-set values, user was informed of this.
          */
-        chng = 1;
+        chng |= 1;
         if( cli_strcmp(z, "qbox")==0 ){
           ColModeOpts cmo = ColModeOpts_default_qbox;
           zMode = "box";
@@ -9947,6 +9968,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     }
     if( zMode==0 ){
       zMode = modeDescr[p->mode];
+      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<argc ){
+      /* See similar code at tag-20250224-1 */
       const char *zEsc = argv[++i];
       int k;
       for(k=0; k<ArraySize(shell_EscModeNames); k++){
@@ -13245,7 +13268,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
         }
       }
       if( k>=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<ArraySize(shell_EscModeNames); k++){
           sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]);
         }