From 40e0e0dbe7f7a70b437325aae41c865bcb87ab24 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Sep 2015 18:51:17 +0000 Subject: [PATCH] Add the --export-sql and --export-db options to the fuzzcheck utility program. FossilOrigin-Name: 760af4455115669b934c3115d45cffe89c085faf --- manifest | 12 +++---- manifest.uuid | 2 +- test/fuzzcheck.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e3d2e7de02..43c8af7630 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\s--help\sscreen\sof\sthe\sfuzzcheck\sutility. -D 2015-09-22T17:46:11.412 +C Add\sthe\s--export-sql\sand\s--export-db\soptions\sto\sthe\sfuzzcheck\sutility\sprogram. +D 2015-09-22T18:51:17.054 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2047811644c5bac91ccdfc2720e49b60965a63a7 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -749,7 +749,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c ae800b0288688e403b9d41ae6666b49a5b4c174a +F test/fuzzcheck.c b8eb7ee40f6d28548a0b028e0676293522f3427f F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db 1d6044c33a114007f02b6e6846f1fa232f607bfd @@ -1387,7 +1387,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fcb1e327a64134e5ac539ec3d52733422d3061fd -R f5e3ce74d9e1f17ec1b801d8a8e1e8b9 +P b6ae61fe3b3de3aa296b3e56cd2ec425a5141c73 +R 67147fe50bd6bcd304574882b2915749 U drh -Z b2d72598222b1fd845b80ebe0256ddec +Z f2fe8ea148ad21aa4f5e236ec8c81968 diff --git a/manifest.uuid b/manifest.uuid index 5e7bb9aff3..36534fefd4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6ae61fe3b3de3aa296b3e56cd2ec425a5141c73 \ No newline at end of file +760af4455115669b934c3115d45cffe89c085faf \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 7718326785..4597891c3a 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -296,6 +296,38 @@ static void readfileFunc( fclose(in); } +/* +** Implementation of the "writefile(X,Y)" SQL function. The argument Y +** is written into file X. The number of bytes written is returned. Or +** NULL is returned if something goes wrong, such as being unable to open +** file X for writing. +*/ +static void writefileFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + FILE *out; + const char *z; + sqlite3_int64 rc; + const char *zFile; + + (void)argc; + zFile = (const char*)sqlite3_value_text(argv[0]); + if( zFile==0 ) return; + out = fopen(zFile, "wb"); + if( out==0 ) return; + z = (const char*)sqlite3_value_blob(argv[1]); + if( z==0 ){ + rc = 0; + }else{ + rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); + } + fclose(out); + sqlite3_result_int64(context, rc); +} + + /* ** Load a list of Blob objects from the database */ @@ -751,6 +783,8 @@ static void showHelp(void){ "Options:\n" " --cell-size-check Set the PRAGMA cell_size_check=ON\n" " --dbid N Use only the database where dbid=N\n" +" --export-db DIR Write databases to files(s) in DIR. Works with --dbid\n" +" --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n" " --help Show this help text\n" " -q Reduced output\n" " --quiet Reduced output\n" @@ -799,6 +833,8 @@ int main(int argc, char **argv){ int sqlFuzz = 0; /* True for SQL fuzz testing. False for DB fuzz */ int iTimeout = 120; /* Default 120-second timeout */ int nMem = 0; /* Memory limit */ + char *zExpDb = 0; /* Write Databases to files in this directory */ + char *zExpSql = 0; /* Write SQL to files in this directory */ iBegin = timeOfDay(); #ifdef __unix__ @@ -818,6 +854,14 @@ int main(int argc, char **argv){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); onlyDbid = integerValue(argv[++i]); }else + if( strcmp(z,"export-db")==0 ){ + if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); + zExpDb = argv[++i]; + }else + if( strcmp(z,"export-sql")==0 ){ + if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); + zExpSql = argv[++i]; + }else if( strcmp(z,"help")==0 ){ showHelp(); return 0; @@ -943,6 +987,50 @@ int main(int argc, char **argv){ sqlite3_close(db); return 0; } + if( zExpDb!=0 || zExpSql!=0 ){ + sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, + writefileFunc, 0, 0); + if( zExpDb!=0 ){ + const char *zExDb = + "SELECT writefile(printf('%s/db%06d.db',?1,dbid),dbcontent)," + " dbid, printf('%s/db%06d.db',?1,dbid), length(dbcontent)" + " FROM db WHERE ?2<0 OR dbid=?2;"; + rc = sqlite3_prepare_v2(db, zExDb, -1, &pStmt, 0); + if( rc ) fatalError("cannot prepare statement [%s]: %s", + zExDb, sqlite3_errmsg(db)); + sqlite3_bind_text64(pStmt, 1, zExpDb, strlen(zExpDb), + SQLITE_STATIC, SQLITE_UTF8); + sqlite3_bind_int(pStmt, 2, onlyDbid); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + printf("write db-%d (%d bytes) into %s\n", + sqlite3_column_int(pStmt,1), + sqlite3_column_int(pStmt,3), + sqlite3_column_text(pStmt,2)); + } + sqlite3_finalize(pStmt); + } + if( zExpSql!=0 ){ + const char *zExSql = + "SELECT writefile(printf('%s/sql%06d.txt',?1,sqlid),sqltext)," + " sqlid, printf('%s/sql%06d.txt',?1,sqlid), length(sqltext)" + " FROM xsql WHERE ?2<0 OR sqlid=?2;"; + rc = sqlite3_prepare_v2(db, zExSql, -1, &pStmt, 0); + if( rc ) fatalError("cannot prepare statement [%s]: %s", + zExSql, sqlite3_errmsg(db)); + sqlite3_bind_text64(pStmt, 1, zExpSql, strlen(zExpSql), + SQLITE_STATIC, SQLITE_UTF8); + sqlite3_bind_int(pStmt, 2, onlySqlid); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + printf("write sql-%d (%d bytes) into %s\n", + sqlite3_column_int(pStmt,1), + sqlite3_column_int(pStmt,3), + sqlite3_column_text(pStmt,2)); + } + sqlite3_finalize(pStmt); + } + sqlite3_close(db); + return 0; + } /* Load all SQL script content and all initial database images from the ** source db