Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhance fuzzershell to support multiple blocks of SQL, each run in its own private in-memory database. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ab0a96ca73cfe92d5a837c71c148e836 |
User & Date: | drh 2015-04-20 12:50:13.942 |
Context
2015-04-20
| ||
13:59 | Fix an obscure memory leak in sqlite3Stat4ProbeFree() (check-in: c72abbe2c1 user: drh tags: trunk) | |
12:50 | Enhance fuzzershell to support multiple blocks of SQL, each run in its own private in-memory database. (check-in: ab0a96ca73 user: drh tags: trunk) | |
01:13 | Add an ALWAYS() around a new branch that was made unreachable by an even newer change. (check-in: 592c010478 user: drh tags: trunk) | |
Changes
Changes to tool/fuzzershell.c.
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** ** (3) The main in-memory database can be initialized from a template ** disk database so that the fuzzer starts with a database containing ** content. ** ** (4) The eval() SQL function is added, allowing the fuzzer to do ** interesting recursive operations. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include "sqlite3.h" | > > > > > > > > > > > > > > > > > > > > > > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | ** ** (3) The main in-memory database can be initialized from a template ** disk database so that the fuzzer starts with a database containing ** content. ** ** (4) The eval() SQL function is added, allowing the fuzzer to do ** interesting recursive operations. ** ** 2015-04-20: The input text can be divided into separate SQL chunks using ** lines of the form: ** ** |****<...>****| ** ** where the "..." is arbitrary text, except the "|" should really be "/". ** ("|" is used here to avoid compiler warnings about nested comments.) ** Each such SQL comment is printed as it is encountered. A separate ** in-memory SQLite database is created to run each chunk of SQL. This ** feature allows the "queue" of AFL to be captured into a single big ** file using a command like this: ** ** (for i in id:*; do echo '|****<'$i'>****|'; cat $i; done) >~/all-queue.txt ** ** (Once again, change the "|" to "/") Then all elements of the AFL queue ** can be run in a single go (for regression testing, for example, by typing: ** ** fuzzershell -f ~/all-queue.txt >out.txt ** ** After running each chunk of SQL, the database connection is closed. The ** program aborts if the close fails or if there is any unfreed memory after ** the close. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include "sqlite3.h" |
︙ | ︙ | |||
214 215 216 217 218 219 220 221 | char *zIn = 0; /* Input text */ int nAlloc = 0; /* Number of bytes allocated for zIn[] */ int nIn = 0; /* Number of bytes of zIn[] used */ size_t got; /* Bytes read from input */ FILE *in = stdin; /* Where to read SQL text from */ int rc = SQLITE_OK; /* Result codes from API functions */ int i; /* Loop counter */ sqlite3 *db; /* Open database */ | > | | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | char *zIn = 0; /* Input text */ int nAlloc = 0; /* Number of bytes allocated for zIn[] */ int nIn = 0; /* Number of bytes of zIn[] used */ size_t got; /* Bytes read from input */ FILE *in = stdin; /* Where to read SQL text from */ int rc = SQLITE_OK; /* Result codes from API functions */ int i; /* Loop counter */ int iNext; /* Next block of SQL */ sqlite3 *db; /* Open database */ sqlite3 *dbInit = 0; /* On-disk database used to initialize the in-memory db */ const char *zInitDb = 0;/* Name of the initialization database file */ char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */ g.zArgv0 = argv[0]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' ){ |
︙ | ︙ | |||
246 247 248 249 250 251 252 | abendError("unknown option: %s", argv[i]); } }else{ abendError("unknown argument: %s", argv[i]); } } sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0); | < < < < < < < < < < < < < < < < < < < < < < < < | | > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | > > > > > > > > > | | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | abendError("unknown option: %s", argv[i]); } }else{ abendError("unknown argument: %s", argv[i]); } } sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0); while( !feof(in) ){ nAlloc += nAlloc+1000; zIn = realloc(zIn, nAlloc); if( zIn==0 ) fatalError("out of memory"); got = fread(zIn+nIn, 1, nAlloc-nIn-1, in); nIn += (int)got; zIn[nIn] = 0; if( got==0 ) break; } if( zInitDb ){ rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0); if( rc!=SQLITE_OK ){ abendError("unable to open initialization database \"%s\"", zInitDb); } } for(i=0; i<nIn; i=iNext){ char cSaved; if( strncmp(&zIn[i], "/****<",6)==0 ){ char *z = strstr(&zIn[i], ">****/"); if( z ){ z += 6; printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]); i += (int)(z-&zIn[i]); } } for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){} rc = sqlite3_open_v2( "main.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); if( rc!=SQLITE_OK ){ abendError("Unable to open the in-memory database"); } if( zInitDb ){ sqlite3_backup *pBackup; pBackup = sqlite3_backup_init(db, "main", dbInit, "main"); rc = sqlite3_backup_step(pBackup, -1); if( rc!=SQLITE_DONE ){ abendError("attempt to initialize the in-memory database failed (rc=%d)", rc); } sqlite3_backup_finish(pBackup); } sqlite3_trace(db, traceCallback, 0); sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000); cSaved = zIn[iNext]; zIn[iNext] = 0; printf("INPUT (offset: %d, size: %d): [%s]\n", i, (int)strlen(&zIn[i]), &zIn[i]); rc = sqlite3_exec(db, &zIn[i], execCallback, 0, &zErrMsg); zIn[iNext] = cSaved; printf("RESULT-CODE: %d\n", rc); if( zErrMsg ){ printf("ERROR-MSG: [%s]\n", zErrMsg); sqlite3_free(zErrMsg); } rc = sqlite3_close(db); if( rc ){ abendError("sqlite3_close() failed with rc=%d", rc); } if( sqlite3_memory_used()>0 ){ abendError("memory in use after close: %lld bytes", sqlite3_memory_used()); } } free(zIn); return 0; } |