Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the --unique-cases option to fuzzershell. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7cb718491b5de77d4a73d8484324b66a |
User & Date: | drh 2015-04-24 14:47:59.444 |
Context
2015-04-24
| ||
16:09 | Add AFL-generated test cases in the test/fuzzdata1.txt file. Automatically run fuzzershell against those cases on a "make test". (check-in: 627ea83c26 user: drh tags: trunk) | |
14:47 | Add the --unique-cases option to fuzzershell. (check-in: 7cb718491b user: drh tags: trunk) | |
13:00 | Fuzzershell enhancements: (1) Add the --verbose and --quiet flags (2) Show percentage complete and final test count for multi-test inputs (3) Omit trace and result logs unless the --verbose flag is used. (check-in: ed202ffac2 user: drh tags: trunk) | |
Changes
Changes to tool/fuzzershell.c.
︙ | ︙ | |||
35 36 37 38 39 40 41 | ** 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.) | < | | | > > > > > > | 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 64 65 66 67 68 | ** 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.) ** 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 ** ** 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. ** ** New cases can be appended to all-queue.txt at any time. If redundant cases ** are added, that can be eliminated by running: ** ** fuzzershell -f ~/all-queue.txt --unique-cases ~/unique-cases.txt ** */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <ctype.h> #include "sqlite3.h" |
︙ | ︙ | |||
242 243 244 245 246 247 248 | ** Print sketchy documentation for this utility program */ static void showHelp(void){ printf("Usage: %s [options]\n", g.zArgv0); printf( "Read SQL text from standard input and evaluate it.\n" "Options:\n" | | | | | | | | | | | | > | | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | ** Print sketchy documentation for this utility program */ static void showHelp(void){ printf("Usage: %s [options]\n", g.zArgv0); printf( "Read SQL text from standard input and evaluate it.\n" "Options:\n" " --autovacuum Enable AUTOVACUUM mode\n" " -f FILE Read SQL text from FILE instead of standard input\n" " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" " --help Show this help text\n" " --initdb DBFILE Initialize the in-memory database using template DBFILE\n" " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n" " --pagesize N Set the page size to N\n" " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n" " -q Reduced output\n" " --quiet Reduced output\n" " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n" " --unique-cases FILE Write all unique test cases to FILE\n" " --utf16be Set text encoding to UTF-16BE\n" " --utf16le Set text encoding to UTF-16LE\n" " -v Increased output\n" " --verbose Increased output\n" ); } /* ** Return the value of a hexadecimal digit. Return -1 if the input ** is not a hex digit. */ |
︙ | ︙ | |||
360 361 362 363 364 365 366 367 368 369 370 371 372 373 | int iMode = FZMODE_Generic; /* Operating mode */ const char *zCkGlob = 0; /* Inputs must match this glob */ int verboseFlag = 0; /* --verbose or -v flag */ int quietFlag = 0; /* --quiet or -q flag */ int nTest = 0; /* Number of test cases run */ int multiTest = 0; /* True if there will be multiple test cases */ int lastPct = -1; /* Previous percentage done output */ g.zArgv0 = argv[0]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' ){ z++; | > > > | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | int iMode = FZMODE_Generic; /* Operating mode */ const char *zCkGlob = 0; /* Inputs must match this glob */ int verboseFlag = 0; /* --verbose or -v flag */ int quietFlag = 0; /* --quiet or -q flag */ int nTest = 0; /* Number of test cases run */ int multiTest = 0; /* True if there will be multiple test cases */ int lastPct = -1; /* Previous percentage done output */ sqlite3 *dataDb = 0; /* Database holding compacted input data */ sqlite3_stmt *pStmt = 0; /* Statement to insert testcase into dataDb */ const char *zDataOut = 0; /* Write compacted data to this output file */ g.zArgv0 = argv[0]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' ){ z++; |
︙ | ︙ | |||
434 435 436 437 438 439 440 441 442 443 444 445 446 447 | verboseFlag = 0; }else if( strcmp(z,"scratch")==0 ){ if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]); nScratch = integerValue(argv[i+1]); szScratch = integerValue(argv[i+2]); i += 2; }else if( strcmp(z,"utf16le")==0 ){ zEncoding = "utf16le"; }else if( strcmp(z,"utf16be")==0 ){ zEncoding = "utf16be"; }else | > > > > > | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | verboseFlag = 0; }else if( strcmp(z,"scratch")==0 ){ if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]); nScratch = integerValue(argv[i+1]); szScratch = integerValue(argv[i+2]); i += 2; }else if( strcmp(z, "unique-cases")==0 ){ if( i>=argc-1 ) abendError("missing arguments on %s", argv[i]); if( zDataOut ) abendError("only one --minimize allowed"); zDataOut = argv[++i]; }else if( strcmp(z,"utf16le")==0 ){ zEncoding = "utf16le"; }else if( strcmp(z,"utf16be")==0 ){ zEncoding = "utf16be"; }else |
︙ | ︙ | |||
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | 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=nTest=0; i<nIn; i=iNext, nTest++){ char cSaved; if( strncmp(&zIn[i], "/****<",6)==0 ){ char *z = strstr(&zIn[i], ">****/"); if( z ){ z += 6; if( verboseFlag ) printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]); i += (int)(z-&zIn[i]); multiTest = 1; } } for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){} cSaved = zIn[iNext]; zIn[iNext] = 0; if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){ zIn[iNext] = cSaved; continue; } rc = sqlite3_open_v2( | > > > > > > > > > > > > > > > > > > | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | 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( in!=stdin ) fclose(in); if( zDataOut ){ rc = sqlite3_open(":memory:", &dataDb); if( rc ) abendError("cannot open :memory: database"); rc = sqlite3_exec(dataDb, "CREATE TABLE testcase(sql BLOB PRIMARY KEY) WITHOUT ROWID;",0,0,0); if( rc ) abendError("%s", sqlite3_errmsg(dataDb)); rc = sqlite3_prepare_v2(dataDb, "INSERT OR IGNORE INTO testcase(sql)VALUES(?1)", -1, &pStmt, 0); if( rc ) abendError("%s", sqlite3_errmsg(dataDb)); } 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=nTest=0; i<nIn; i=iNext, nTest++){ char cSaved; if( strncmp(&zIn[i], "/****<",6)==0 ){ char *z = strstr(&zIn[i], ">****/"); if( z ){ z += 6; if( verboseFlag ) printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]); i += (int)(z-&zIn[i]); multiTest = 1; } } for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){} if( zDataOut ){ sqlite3_bind_blob(pStmt, 1, &zIn[i], iNext-i, SQLITE_STATIC); rc = sqlite3_step(pStmt); if( rc!=SQLITE_DONE ) abendError("%s", sqlite3_errmsg(dataDb)); sqlite3_reset(pStmt); continue; } cSaved = zIn[iNext]; zIn[iNext] = 0; if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){ zIn[iNext] = cSaved; continue; } rc = sqlite3_open_v2( |
︙ | ︙ | |||
587 588 589 590 591 592 593 | abendError("sqlite3_close() failed with rc=%d", rc); } if( sqlite3_memory_used()>0 ){ abendError("memory in use after close: %lld bytes", sqlite3_memory_used()); } } if( nTest>1 && !quietFlag ){ | | > > > > > > > > > > > > > > > > | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | abendError("sqlite3_close() failed with rc=%d", rc); } if( sqlite3_memory_used()>0 ){ abendError("memory in use after close: %lld bytes", sqlite3_memory_used()); } } if( nTest>1 && !quietFlag ){ printf("%d tests with no errors\nSQLite %s %s\n", nTest, sqlite3_libversion(), sqlite3_sourceid()); } if( zDataOut ){ FILE *out = fopen(zDataOut, "wb"); int n = 0; if( out==0 ) abendError("cannot open %s for writing", zDataOut); sqlite3_finalize(pStmt); rc = sqlite3_prepare_v2(dataDb, "SELECT sql FROM testcase", -1, &pStmt, 0); if( rc ) abendError("%s", sqlite3_errmsg(dataDb)); while( sqlite3_step(pStmt)==SQLITE_ROW ){ fprintf(out,"/****<%d>****/", ++n); fwrite(sqlite3_column_blob(pStmt,0),sqlite3_column_bytes(pStmt,0),1,out); } fclose(out); sqlite3_finalize(pStmt); sqlite3_close(dataDb); } free(zIn); free(pHeap); free(pLook); free(pScratch); free(pPCache); return 0; } |