]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further improvements to control-character escapes in the CLI.
authordrh <>
Sun, 23 Feb 2025 20:50:37 +0000 (20:50 +0000)
committerdrh <>
Sun, 23 Feb 2025 20:50:37 +0000 (20:50 +0000)
FossilOrigin-Name: 9c2f974c17e3dfac78f3808fdfe916f7617cfdaa64430af38eae21bd6592e6f5

manifest
manifest.uuid
src/shell.c.in

index bb780263ec79bafa5128eb111ad98fc57a62493e..2225ae1b75ac705bfebcfea45508c3772c5de815 100644 (file)
--- 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.
index 2b72ba576954764d03c6489c06d086745f56cba2..a486e0cfcf273fa154d36989df4a91e20fa07d0c 100644 (file)
@@ -1 +1 @@
-44c44620e8648a4265053f194e32b3a5c65d25b4f1fff61ef9b944e7cb0ed624
+9c2f974c17e3dfac78f3808fdfe916f7617cfdaa64430af38eae21bd6592e6f5
index a8ea0dd2adb401483fd445ac219e2b9d38603294..515da6adae3f87665d2ee8ceb38d32968a5e0a36 100644 (file)
@@ -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;