From 6193d49cdf063444cd1d0c0bfa64e4569a8353be Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Apr 2017 11:45:58 +0000 Subject: [PATCH] Use replace() instead of char() to quote newline and return characters in strings in the output of .dump, to avoid excess expression complexity. FossilOrigin-Name: 4c2b572969ea2ed2a925444ecfa356aa877018cbb9c4f57d081ab4b535cd1dd0 --- manifest | 17 +++++++------ manifest.uuid | 2 +- src/shell.c | 69 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 50c2d8faef..58a053dc81 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".lint\sfkey"\sshell\scommand\sfor\scases\swhere\sthe\schild\skey\sis\salso\san\nINTEGER\sPRIMARY\sKEY. -D 2017-04-06T14:56:26.887 +C Use\sreplace()\sinstead\sof\schar()\sto\squote\snewline\sand\sreturn\scharacters\sin\nstrings\sin\sthe\soutput\sof\s.dump,\sto\savoid\sexcess\sexpression\scomplexity. +D 2017-04-07T11:45:58.111 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 -F src/shell.c e9fede684f847402c0373fe5e270918e6ef47f51e57ba5aebff121d8c2bc1ea8 +F src/shell.c 3680725485ce5022dc683d593e8a4b95f973597d843ddb8be788d7dc24d16de9 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1570,7 +1570,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba -R 260410c30d599e0993c58e23cef69640 -U dan -Z 25db1dc906fb1b522f7b655980ddd579 +P 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 +R 33164644836f84aff2e4df2bff5189e1 +T *branch * shell-fix +T *sym-shell-fix * +T -sym-trunk * +U drh +Z d4f7ac77bbed43ce1dcbcb86734fd32f diff --git a/manifest.uuid b/manifest.uuid index 3814e9cddf..258bb7d642 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 \ No newline at end of file +4c2b572969ea2ed2a925444ecfa356aa877018cbb9c4f57d081ab4b535cd1dd0 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b28a1421d3..5562fd61c2 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1488,6 +1488,27 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ raw_printf(out,"'"); } +/* +** 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. ** @@ -1502,40 +1523,52 @@ static void output_quoted_string(FILE *out, const char *z){ if( c==0 ){ utf8_printf(out,"'%s'",z); }else{ - int inQuote = 0; - int bStarted = 0; + 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 ){ + raw_printf(out, "replace("); + zNL = unused_string(z, "\\n", "\\012", zBuf1); + } + if( nCR ){ + raw_printf(out, "replace("); + zCR = unused_string(z, "\\r", "\\015", zBuf2); + } + raw_printf(out, "'"); while( *z ){ for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} if( c=='\'' ) i++; if( i ){ - if( !inQuote ){ - if( bStarted ) raw_printf(out, "||"); - raw_printf(out, "'"); - inQuote = 1; - } utf8_printf(out, "%.*s", i, z); z += i; - bStarted = 1; } if( c=='\'' ){ raw_printf(out, "'"); continue; } - if( inQuote ){ - raw_printf(out, "'"); - inQuote = 0; - } if( c==0 ){ break; } - for(i=0; (c = z[i])=='\r' || c=='\n'; i++){ - if( bStarted ) raw_printf(out, "||"); - raw_printf(out, "char(%d)", c); - bStarted = 1; + z++; + if( c=='\n' ){ + raw_printf(out, "%s", zNL); + continue; } - z += i; + raw_printf(out, "%s", zCR); + } + raw_printf(out, "'"); + if( nCR ){ + raw_printf(out, ",'%s',char(13))", zCR); + } + if( nNL ){ + raw_printf(out, ",'%s',char(10))", zNL); } - if( inQuote ) raw_printf(out, "'"); } setTextMode(out, 1); } -- 2.39.5