From: drh Date: Wed, 12 Apr 2017 17:38:24 +0000 (+0000) Subject: Improved \n and \r escapes in the ext/misc/dbdump.c utility function. The X-Git-Tag: version-3.19.0~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=26849e14c22300e9aed8853d916cbd7d2058c719;p=thirdparty%2Fsqlite.git Improved \n and \r escapes in the ext/misc/dbdump.c utility function. The implementation of dbdump.c now matches the implementation in the CLI. FossilOrigin-Name: f2643315bb41a71eebd79f5d671f9163187e299a52ff8a481186f1e8fa7e5262 --- diff --git a/ext/misc/dbdump.c b/ext/misc/dbdump.c index db581a8325..90c2dd4c44 100644 --- a/ext/misc/dbdump.c +++ b/ext/misc/dbdump.c @@ -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: { diff --git a/manifest b/manifest index a15558d8d8..ce75a7afa6 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 4a4800c424..ceed2cbabf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7aae5c0f99aa2fda85654242cfc9e23a0f981d9ce4ab17610d619cd208540b3d \ No newline at end of file +f2643315bb41a71eebd79f5d671f9163187e299a52ff8a481186f1e8fa7e5262 \ No newline at end of file