]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved \n and \r escapes in the ext/misc/dbdump.c utility function. The
authordrh <drh@noemail.net>
Wed, 12 Apr 2017 17:38:24 +0000 (17:38 +0000)
committerdrh <drh@noemail.net>
Wed, 12 Apr 2017 17:38:24 +0000 (17:38 +0000)
implementation of dbdump.c now matches the implementation in the CLI.

FossilOrigin-Name: f2643315bb41a71eebd79f5d671f9163187e299a52ff8a481186f1e8fa7e5262

ext/misc/dbdump.c
manifest
manifest.uuid

index db581a8325e5e04fc560bd991d1405f86ca465e9..90c2dd4c44be7f6c46df1d743028516aab3883d6 100644 (file)
@@ -324,54 +324,86 @@ static void output_formatted(DState *p, const char *zFormat, ...){
 }
 
 /*
-** Output the given string as a quoted string using SQL quoting conventions.
+** Find a string that is not found anywhere in z[].  Return a pointer
+** to that string.
 **
-** The "\n" and "\r" characters are converted to char(10) and char(13)
-** to prevent them from being transformed by end-of-line translators.
+** 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.
+** Additionallly , escape the "\n" and "\r" characters so that they do not
+** get corrupted by end-of-line translation facilities in some operating
+** systems.
 */
-static void output_quoted_string(DState *p, const unsigned char *z){
+static void output_quoted_escaped_string(DState *p, const char *z){
   int i;
   char c;
-  int inQuote = 0;
-  int bStarted = 0;
-
   for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
   if( c==0 ){
-    output_formatted(p, "'%s'", z);
-    return;
-  }
-  while( *z ){
-    for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
-    if( c=='\'' ) i++;
-    if( i ){
-      if( !inQuote ){
-        if( bStarted ) p->xCallback("||", p->pArg);
-        p->xCallback("'", p->pArg);
-        inQuote = 1;
-      }
-      output_formatted(p, "%.*s", i, z);
-      z += i;
-      bStarted = 1;
+    output_formatted(p,"'%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( c=='\'' ){
-      p->xCallback("'", p->pArg);
-      continue;
+    if( nNL ){
+      p->xCallback("replace(", p->pArg);
+      zNL = unused_string(z, "\\n", "\\012", zBuf1);
     }
-    if( inQuote ){
-      p->xCallback("'", p->pArg);
-      inQuote = 0;
+    if( nCR ){
+      p->xCallback("replace(", p->pArg);
+      zCR = unused_string(z, "\\r", "\\015", zBuf2);
+    }
+    p->xCallback("'", p->pArg);
+    while( *z ){
+      for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
+      if( c=='\'' ) i++;
+      if( i ){
+        output_formatted(p, "%.*s", i, z);
+        z += i;
+      }
+      if( c=='\'' ){
+        p->xCallback("'", p->pArg);
+        continue;
+      }
+      if( c==0 ){
+        break;
+      }
+      z++;
+      if( c=='\n' ){
+        p->xCallback(zNL, p->pArg);
+        continue;
+      }
+      p->xCallback(zCR, p->pArg);
     }
-    if( c==0 ){
-      break;
+    p->xCallback("'", p->pArg);
+    if( nCR ){
+      output_formatted(p, ",'%s',char(13))", zCR);
     }
-    for(i=0; (c = z[i])=='\r' || c=='\n'; i++){
-      if( bStarted ) p->xCallback("||", p->pArg);
-      output_formatted(p, "char(%d)", c);
-      bStarted = 1;
+    if( nNL ){
+      output_formatted(p, ",'%s',char(10))", zNL);
     }
-    z += i;
   }
-  if( inQuote ) p->xCallback("'", p->pArg);
 }
 
 /*
@@ -495,7 +527,8 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
               break;
             }
             case SQLITE_TEXT: {
-              output_quoted_string(p, sqlite3_column_text(pStmt,i));
+              output_quoted_escaped_string(p, 
+                   (const char*)sqlite3_column_text(pStmt,i));
               break;
             }
             case SQLITE_BLOB: {
index a15558d8d8240fd4458d748cd883a9b325787a4d..ce75a7afa6ddcb928282564d1337bb3b6519f2a7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\supdating\sunaffected\sindexes\son\sa\stable\sas\spart\sof\san\sUPDATE\sthat\nrequires\sforeign\skey\sprocessing\sin\ssome\scases.
-D 2017-04-11T20:48:30.136
+C Improved\s\\n\sand\s\\r\sescapes\sin\sthe\sext/misc/dbdump.c\sutility\sfunction.\s\sThe\nimplementation\sof\sdbdump.c\snow\smatches\sthe\simplementation\sin\sthe\sCLI.
+D 2017-04-12T17:38:24.004
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
@@ -213,7 +213,7 @@ F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d
 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
 F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d
-F ext/misc/dbdump.c 34174d537318027b159e3341105866c05a4149376ede59988c82280bed144e6d
+F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e
 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
 F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
@@ -1571,8 +1571,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 1f68c184596912d742b50b1ca38252a9e783aacf121619a27b17a7ae9f6df041 477bea9ed0dd0fa69896bfd16d9b1d22170cbab784e3279ce65c29c47e032f34
-R 64d829e1406f8fce120ec976a7526a63
-T +closed 477bea9ed0dd0fa69896bfd16d9b1d22170cbab784e3279ce65c29c47e032f34
-U dan
-Z 4b9ca8a969671d2c2632520dbc5c02e5
+P 7aae5c0f99aa2fda85654242cfc9e23a0f981d9ce4ab17610d619cd208540b3d
+R 8af8a0ed024db0518fa75f74af560a36
+U drh
+Z 8e506040e94c8b0ee35c49d49bd8bac0
index 4a4800c42493a16e62ce160118ce252afbe66b0e..ceed2cbabfff3021cbeee534557ae7b74bcadf81 100644 (file)
@@ -1 +1 @@
-7aae5c0f99aa2fda85654242cfc9e23a0f981d9ce4ab17610d619cd208540b3d
\ No newline at end of file
+f2643315bb41a71eebd79f5d671f9163187e299a52ff8a481186f1e8fa7e5262
\ No newline at end of file