SQLite

Changes On Branch dbsqlfuzz-in-fuzzcheck
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch dbsqlfuzz-in-fuzzcheck Excluding Merge-Ins

This is equivalent to a diff from d0d56893 to 2c1ef40e

2019-01-25
14:23
Extend fuzzcheck so that it can process dbsqlfuzz cases. Add a collection of interesting dbsqlfuzz cases to the standard test suite. (check-in: e2991a7e user: drh tags: trunk)
14:16
Fix the xFetch method of the "memdb" VFS (used by deserialize) so that it is robust against corrupt database file. (Closed-Leaf check-in: 2c1ef40e user: drh tags: dbsqlfuzz-in-fuzzcheck)
13:42
Fix a couple of assert() statments in btree.c that could fail with corrupt databases. (check-in: 5eb5e828 user: dan tags: trunk)
13:03
In fuzzcheck, activate vdbe_debug for dbsqlfuzz cases when using the -vvvvv verbosity level or above. (check-in: 2e6f7c2a user: drh tags: dbsqlfuzz-in-fuzzcheck)
04:00
Add the ability to process dbsqlfuzz cases in fuzzcheck and add an initial set of interesting dbsqlfuzz cases. (check-in: fb9074ff user: drh tags: dbsqlfuzz-in-fuzzcheck)
2019-01-24
17:41
Fix a buffer overread in fts3 that could occur in a prefix query on a corrupted database. (check-in: d0d56893 user: dan tags: trunk)
16:27
Fix a problem with running ALTER TABLE on a schema that contains expressions of the type "col IN ()" (empty set on RHS of IN operator). (check-in: 2d9cd067 user: dan tags: trunk)

Changes to Makefile.in.

585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
FUZZDATA = \
  $(TOP)/test/fuzzdata1.db \
  $(TOP)/test/fuzzdata2.db \
  $(TOP)/test/fuzzdata3.db \
  $(TOP)/test/fuzzdata4.db \
  $(TOP)/test/fuzzdata5.db \
  $(TOP)/test/fuzzdata6.db \
  $(TOP)/test/fuzzdata7.db


# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#







|
>







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
FUZZDATA = \
  $(TOP)/test/fuzzdata1.db \
  $(TOP)/test/fuzzdata2.db \
  $(TOP)/test/fuzzdata3.db \
  $(TOP)/test/fuzzdata4.db \
  $(TOP)/test/fuzzdata5.db \
  $(TOP)/test/fuzzdata6.db \
  $(TOP)/test/fuzzdata7.db \
  $(TOP)/test/fuzzdata8.db

# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
608
609
610
611
612
613
614






615
616
617
618
619
620
621
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000






FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)







>
>
>
>
>
>







609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)

Changes to Makefile.msc.

1622
1623
1624
1625
1626
1627
1628
1629

1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647






1648
1649
1650
1651
1652
1653
1654
FUZZDATA = \
  $(TOP)\test\fuzzdata1.db \
  $(TOP)\test\fuzzdata2.db \
  $(TOP)\test\fuzzdata3.db \
  $(TOP)\test\fuzzdata4.db \
  $(TOP)\test\fuzzdata5.db \
  $(TOP)\test\fuzzdata6.db \
  $(TOP)\test\fuzzdata7.db

# <</mark>>

# Additional compiler options for the shell.  These are only effective
# when the shell is not being dynamically linked.
#
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF

# <<mark>>
# Extra compiler options for various test tools.
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000






FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0

# Standard options to testfixture.







|
>

















|
>
>
>
>
>
>







1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
FUZZDATA = \
  $(TOP)\test\fuzzdata1.db \
  $(TOP)\test\fuzzdata2.db \
  $(TOP)\test\fuzzdata3.db \
  $(TOP)\test\fuzzdata4.db \
  $(TOP)\test\fuzzdata5.db \
  $(TOP)\test\fuzzdata6.db \
  $(TOP)\test\fuzzdata7.db \
  $(TOP)\test\fuzzdata8.db
# <</mark>>

# Additional compiler options for the shell.  These are only effective
# when the shell is not being dynamically linked.
#
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF

# <<mark>>
# Extra compiler options for various test tools.
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB

FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0

# Standard options to testfixture.
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
fuzzershell.exe:	$(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

dbfuzz.exe:	$(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

fuzzcheck.exe:	$(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

ossshell.exe:	$(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

sessionfuzz.exe:	zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)

mptester.exe:	$(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)








|


|







1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
fuzzershell.exe:	$(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

dbfuzz.exe:	$(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

fuzzcheck.exe:	$(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

ossshell.exe:	$(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

sessionfuzz.exe:	zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)

mptester.exe:	$(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
	$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

Changes to main.mk.

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
FUZZDATA = \
  $(TOP)/test/fuzzdata1.db \
  $(TOP)/test/fuzzdata2.db \
  $(TOP)/test/fuzzdata3.db \
  $(TOP)/test/fuzzdata4.db \
  $(TOP)/test/fuzzdata5.db \
  $(TOP)/test/fuzzdata6.db \
  $(TOP)/test/fuzzdata7.db


# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000





DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#







|
>




















>
>
>
>
>







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
FUZZDATA = \
  $(TOP)/test/fuzzdata1.db \
  $(TOP)/test/fuzzdata2.db \
  $(TOP)/test/fuzzdata3.db \
  $(TOP)/test/fuzzdata4.db \
  $(TOP)/test/fuzzdata5.db \
  $(TOP)/test/fuzzdata6.db \
  $(TOP)/test/fuzzdata7.db \
  $(TOP)/test/fuzzdata8.db

# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#

Changes to src/memdb.c.

306
307
308
309
310
311
312




313
314

315
316
317
318
319
320
321
static int memdbFetch(
  sqlite3_file *pFile,
  sqlite3_int64 iOfst,
  int iAmt,
  void **pp
){
  MemFile *p = (MemFile *)pFile;




  p->nMmap++;
  *pp = (void*)(p->aData + iOfst);

  return SQLITE_OK;
}

/* Release a memory-mapped page */
static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
  MemFile *p = (MemFile *)pFile;
  p->nMmap--;







>
>
>
>
|
|
>







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
static int memdbFetch(
  sqlite3_file *pFile,
  sqlite3_int64 iOfst,
  int iAmt,
  void **pp
){
  MemFile *p = (MemFile *)pFile;
  if( iOfst+iAmt>p->sz ){
    assert( CORRUPT_DB );
    *pp = 0;
  }else{
    p->nMmap++;
    *pp = (void*)(p->aData + iOfst);
  }
  return SQLITE_OK;
}

/* Release a memory-mapped page */
static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
  MemFile *p = (MemFile *)pFile;
  p->nMmap--;

Changes to test/fuzzcheck.c.

65
66
67
68
69
70
71

72
73
74
75
76
77
78
** DB values that were running when the crash occurred.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>

#include "sqlite3.h"
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))


#ifdef __unix__
# include <signal.h>







>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
** DB values that were running when the crash occurred.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <assert.h>
#include "sqlite3.h"
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))


#ifdef __unix__
# include <signal.h>
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420




































































































































































































































































































































































































































































421
422
423
424
425
426
427
  while( p ){
    pNext = p->pNext;
    free(p);
    p = pNext;
  }
}


/* Return the current wall-clock time */
static sqlite3_int64 timeOfDay(void){
  static sqlite3_vfs *clockVfs = 0;
  sqlite3_int64 t;
  if( clockVfs==0 ){
    clockVfs = sqlite3_vfs_find(0);
    if( clockVfs==0 ) return 0;
  }
  if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
    clockVfs->xCurrentTimeInt64(clockVfs, &t);
  }else{
    double r;
    clockVfs->xCurrentTime(clockVfs, &r);
    t = (sqlite3_int64)(r*86400000.0);
  }
  return t;
}





































































































































































































































































































































































































































































/* Methods for the VHandle object
*/
static int inmemClose(sqlite3_file *pFile){
  VHandle *p = (VHandle*)pFile;
  VFile *pVFile = p->pVFile;
  pVFile->nRef--;







<

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
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
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
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
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
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
  while( p ){
    pNext = p->pNext;
    free(p);
    p = pNext;
  }
}


/* Return the current wall-clock time */
static sqlite3_int64 timeOfDay(void){
  static sqlite3_vfs *clockVfs = 0;
  sqlite3_int64 t;
  if( clockVfs==0 ){
    clockVfs = sqlite3_vfs_find(0);
    if( clockVfs==0 ) return 0;
  }
  if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
    clockVfs->xCurrentTimeInt64(clockVfs, &t);
  }else{
    double r;
    clockVfs->xCurrentTime(clockVfs, &r);
    t = (sqlite3_int64)(r*86400000.0);
  }
  return t;
}

/***************************************************************************
** Code to process combined database+SQL scripts generated by the
** dbsqlfuzz fuzzer.
*/

/* An instance of the following object is passed by pointer as the
** client data to various callbacks.
*/
typedef struct FuzzCtx {
  sqlite3 *db;               /* The database connection */
  sqlite3_int64 iCutoffTime; /* Stop processing at this time. */
  sqlite3_int64 iLastCb;     /* Time recorded for previous progress callback */
  sqlite3_int64 mxInterval;  /* Longest interval between two progress calls */
  unsigned nCb;              /* Number of progress callbacks */
  unsigned mxCb;             /* Maximum number of progress callbacks allowed */
  unsigned execCnt;          /* Number of calls to the sqlite3_exec callback */
  int timeoutHit;            /* True when reaching a timeout */
} FuzzCtx;

/* Verbosity level for the dbsqlfuzz test runner */
static int eVerbosity = 0;

/* True to activate PRAGMA vdbe_debug=on */
static int bVdbeDebug = 0;

/* Timeout for each fuzzing attempt, in milliseconds */
static int iTimeout = 10000;   /* Defaults to 10 seconds */

/* Maximum number of progress handler callbacks */
static unsigned int mxProgressCb = 2000;

/* Maximum string length in SQLite */
static int lengthLimit = 1000000;

/* Maximum byte-code program length in SQLite */
static int vdbeOpLimit = 25000;

/* Maximum size of the in-memory database */
static sqlite3_int64 maxDbSize = 104857600;

/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character:  0..9a..fA..F
*/
static unsigned int hexToInt(unsigned int h){
#ifdef SQLITE_EBCDIC
  h += 9*(1&~(h>>4));   /* EBCDIC */
#else
  h += 9*(1&(h>>6));    /* ASCII */
#endif
  return h & 0xf;
}

/*
** The first character of buffer zIn[0..nIn-1] is a '['.  This routine
** checked to see if the buffer holds "[NNNN]" or "[+NNNN]" and if it
** does it makes corresponding changes to the *pK value and *pI value
** and returns true.  If the input buffer does not match the patterns,
** no changes are made to either *pK or *pI and this routine returns false.
*/
static int isOffset(
  const unsigned char *zIn,  /* Text input */
  int nIn,                   /* Bytes of input */
  unsigned int *pK,          /* half-byte cursor to adjust */
  unsigned int *pI           /* Input index to adjust */
){
  int i;
  unsigned int k = 0;
  unsigned char c;
  for(i=1; i<nIn && (c = zIn[i])!=']'; i++){
    if( !isxdigit(c) ) return 0;
    k = k*16 + hexToInt(c);
  }
  if( i==nIn ) return 0;
  *pK = 2*k;
  *pI += i;
  return 1;
}

/*
** Decode the text starting at zIn into a binary database file.
** The maximum length of zIn is nIn bytes.  Compute the binary database
** file contain in space obtained from sqlite3_malloc().
**
** Return the number of bytes of zIn consumed.  Or return -1 if there
** is an error.  One potential error is that the recipe specifies a
** database file larger than MX_FILE_SZ bytes.
**
** Abort on an OOM.
*/
static int decodeDatabase(
  const unsigned char *zIn,      /* Input text to be decoded */
  int nIn,                       /* Bytes of input text */
  unsigned char **paDecode,      /* OUT: decoded database file */
  int *pnDecode                  /* OUT: Size of decoded database */
){
  unsigned char *a;              /* Database under construction */
  int mx = 0;                    /* Current size of the database */
  sqlite3_uint64 nAlloc = 4096;  /* Space allocated in a[] */
  unsigned int i;                /* Next byte of zIn[] to read */
  unsigned int j;                /* Temporary integer */
  unsigned int k;                /* half-byte cursor index for output */
  unsigned int n;                /* Number of bytes of input */
  unsigned char b = 0;
  if( nIn<4 ) return -1;
  n = (unsigned int)nIn;
  a = sqlite3_malloc( nAlloc );
  if( a==0 ){
    fprintf(stderr, "Out of memory!\n");
    exit(1);
  }
  memset(a, 0, nAlloc);
  for(i=k=0; i<n; i++){
    char c = zIn[i];
    if( isxdigit(c) ){
      k++;
      if( k & 1 ){
        b = hexToInt(c)*16;
      }else{
        b += hexToInt(c);
        j = k/2 - 1;
        if( j>=nAlloc ){
          sqlite3_uint64 newSize;
          if( nAlloc==MX_FILE_SZ || j>=MX_FILE_SZ ){
            if( eVerbosity ){
              fprintf(stderr, "Input database too big: max %d bytes\n",
                      MX_FILE_SZ);
            }
            sqlite3_free(a);
            return -1;
          }
          newSize = nAlloc*2;
          if( newSize<=j ){
            newSize = (j+4096)&~4095;
          }
          if( newSize>MX_FILE_SZ ){
            if( j>=MX_FILE_SZ ){
              sqlite3_free(a);
              return -1;
            }
            newSize = MX_FILE_SZ;
          }
          a = sqlite3_realloc( a, newSize );
          if( a==0 ){
            fprintf(stderr, "Out of memory!\n");
            exit(1);
          }
          assert( newSize > nAlloc );
          memset(a+nAlloc, 0, newSize - nAlloc);
          nAlloc = newSize;
        }
        if( j>=(unsigned)mx ){
          mx = (j + 4095)&~4095;
          if( mx>MX_FILE_SZ ) mx = MX_FILE_SZ;
        }
        assert( j<nAlloc );
        a[j] = b;
      }
    }else if( zIn[i]=='[' && i<n-3 && isOffset(zIn+i, nIn-i, &k, &i) ){
      continue;
   }else if( zIn[i]=='\n' && i<n-4 && memcmp(zIn+i,"\n--\n",4)==0 ){
      i += 4;
      break;
    }
  }
  *pnDecode = mx;
  *paDecode = a;
  return i;
}

/*
** Progress handler callback.
**
** The argument is the cutoff-time after which all processing should
** stop.  So return non-zero if the cut-off time is exceeded.
*/
static int progress_handler(void *pClientData) {
  FuzzCtx *p = (FuzzCtx*)pClientData;
  sqlite3_int64 iNow = timeOfDay();
  int rc = iNow>=p->iCutoffTime;
  sqlite3_int64 iDiff = iNow - p->iLastCb;
  if( iDiff > p->mxInterval ) p->mxInterval = iDiff;
  p->nCb++;
  if( rc==0 && p->mxCb>0 && p->mxCb<=p->nCb ) rc = 1;
  if( rc && !p->timeoutHit && eVerbosity>=2 ){
    printf("Timeout on progress callback %d\n", p->nCb);
    fflush(stdout);
    p->timeoutHit = 1;
  }
  return rc;
}

/*
** Disallow debugging pragmas such as "PRAGMA vdbe_debug" and
** "PRAGMA parser_trace" since they can dramatically increase the
** amount of output without actually testing anything useful.
**
** Also block ATTACH and DETACH
*/
static int block_troublesome_sql(
  void *Notused,
  int eCode,
  const char *zArg1,
  const char *zArg2,
  const char *zArg3,
  const char *zArg4
){
  (void)Notused;
  (void)zArg2;
  (void)zArg3;
  (void)zArg4;
  if( eCode==SQLITE_PRAGMA ){
    if( sqlite3_strnicmp("vdbe_", zArg1, 5)==0
     || sqlite3_stricmp("parser_trace", zArg1)==0
     || sqlite3_stricmp("temp_store_directory", zArg1)==0
    ){
      return SQLITE_DENY;
    }
  }else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH)
            && zArg1 && zArg1[0] ){
    return SQLITE_DENY;
  }
  return SQLITE_OK;
}

/*
** Run the SQL text
*/
static int runDbSql(sqlite3 *db, const char *zSql){
  int rc;
  sqlite3_stmt *pStmt;
  while( isspace(zSql[0]) ) zSql++;
  if( zSql[0]==0 ) return SQLITE_OK;
  if( eVerbosity>=4 ){
    printf("RUNNING-SQL: [%s]\n", zSql);
    fflush(stdout);
  }
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc==SQLITE_OK ){
    while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
      if( eVerbosity>=5 ){
        int j;
        for(j=0; j<sqlite3_column_count(pStmt); j++){
          if( j ) printf(",");
          switch( sqlite3_column_type(pStmt, j) ){
            case SQLITE_NULL: {
              printf("NULL");
              break;
            }
            case SQLITE_INTEGER:
            case SQLITE_FLOAT: {
              printf("%s", sqlite3_column_text(pStmt, j));
              break;
            }
            case SQLITE_BLOB: {
              int n = sqlite3_column_bytes(pStmt, j);
              int i;
              const unsigned char *a;
              a = (const unsigned char*)sqlite3_column_blob(pStmt, j);
              printf("x'");
              for(i=0; i<n; i++){
                printf("%02x", a[i]);
              }
              printf("'");
              break;
            }
            case SQLITE_TEXT: {
              int n = sqlite3_column_bytes(pStmt, j);
              int i;
              const unsigned char *a;
              a = (const unsigned char*)sqlite3_column_blob(pStmt, j);
              printf("'");
              for(i=0; i<n; i++){
                if( a[i]=='\'' ){
                  printf("''");
                }else{
                  putchar(a[i]);
                }
              }
              printf("'");
              break;
            }
          } /* End switch() */
        } /* End for() */
        printf("\n");
        fflush(stdout);
      } /* End if( eVerbosity>=5 ) */
    } /* End while( SQLITE_ROW */
    if( rc!=SQLITE_DONE && eVerbosity>=4 ){
      printf("SQL-ERROR: (%d) %s\n", rc, sqlite3_errmsg(db));
      fflush(stdout);
    }
  }else if( eVerbosity>=4 ){
    printf("SQL-ERROR (%d): %s\n", rc, sqlite3_errmsg(db));
    fflush(stdout);    
  } /* End if( SQLITE_OK ) */
  return sqlite3_finalize(pStmt);
}

/* Invoke this routine to run a single test case */
int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
  int rc;                    /* SQLite API return value */
  int iSql;                  /* Index in aData[] of start of SQL */
  unsigned char *aDb = 0;    /* Decoded database content */
  int nDb = 0;               /* Size of the decoded database */
  int i;                     /* Loop counter */
  int j;                     /* Start of current SQL statement */
  char *zSql = 0;            /* SQL text to run */
  int nSql;                  /* Bytes of SQL text */
  FuzzCtx cx;                /* Fuzzing context */

  if( nByte<10 ) return 0;
  if( sqlite3_initialize() ) return 0;
  if( sqlite3_memory_used()!=0 ){
    int nAlloc = 0;
    int nNotUsed = 0;
    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
    fprintf(stderr,"Memory leak in mutator: %lld bytes in %d allocations\n",
            sqlite3_memory_used(), nAlloc);
    exit(1);
  }
  memset(&cx, 0, sizeof(cx));
  iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
  if( iSql<0 ) return 0;
  nSql = nByte - iSql;
  if( eVerbosity>=3 ){
    printf(
      "****** %d-byte input, %d-byte database, %d-byte script "
      "******\n", (int)nByte, nDb, nSql);
    fflush(stdout);
  }
  rc = sqlite3_open(0, &cx.db);
  if( rc ) return 1;
  if( bVdbeDebug ){
    sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
  }

  /* Invoke the progress handler frequently to check to see if we
  ** are taking too long.  The progress handler will return true
  ** (which will block further processing) if more than iTimeout seconds have
  ** elapsed since the start of the test.
  */
  cx.iLastCb = timeOfDay();
  cx.iCutoffTime = cx.iLastCb + iTimeout;  /* Now + iTimeout seconds */
  cx.mxCb = mxProgressCb;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx);
#endif

  /* Set a limit on the maximum size of a prepared statement, and the
  ** maximum length of a string or blob */
  if( vdbeOpLimit>0 ){
    sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, vdbeOpLimit);
  }
  if( lengthLimit>0 ){
    sqlite3_limit(cx.db, SQLITE_LIMIT_LENGTH, lengthLimit);
  }

  if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){
    aDb[18] = aDb[19] = 1;
  }
  rc = sqlite3_deserialize(cx.db, "main", aDb, nDb, nDb,
          SQLITE_DESERIALIZE_RESIZEABLE |
          SQLITE_DESERIALIZE_FREEONCLOSE);
  if( rc ){
    fprintf(stderr, "sqlite3_deserialize() failed with %d\n", rc);
    goto testrun_finished;
  }
  if( maxDbSize>0 ){
    sqlite3_int64 x = maxDbSize;
    sqlite3_file_control(cx.db, "main", SQLITE_FCNTL_SIZE_LIMIT, &x);
  }

  /* For high debugging levels, turn on debug mode */
  if( eVerbosity>=5 ){
    sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON;", 0, 0, 0);
  }

  /* Block debug pragmas and ATTACH/DETACH.  But wait until after
  ** deserialize to do this because deserialize depends on ATTACH */
  sqlite3_set_authorizer(cx.db, block_troublesome_sql, 0);

  /* Consistent PRNG seed */
  sqlite3_randomness(0,0);

  zSql = sqlite3_malloc( nSql + 1 );
  if( zSql==0 ){
    fprintf(stderr, "Out of memory!\n");
  }else{
    memcpy(zSql, aData+iSql, nSql);
    zSql[nSql] = 0;
    for(i=j=0; zSql[i]; i++){
      if( zSql[i]==';' ){
        char cSaved = zSql[i+1];
        zSql[i+1] = 0;
        if( sqlite3_complete(zSql+j) ){
          rc = runDbSql(cx.db, zSql+j);
          j = i+1;
        }
        zSql[i+1] = cSaved;
        if( rc==SQLITE_INTERRUPT || progress_handler(&cx) ){
          goto testrun_finished;
        }
      }
    }
    if( j<i ){
      runDbSql(cx.db, zSql+j);
    }
  }
testrun_finished:
  sqlite3_free(zSql);
  rc = sqlite3_close(cx.db);
  if( rc!=SQLITE_OK ){
    fprintf(stdout, "sqlite3_close() returns %d\n", rc);
  }
  if( eVerbosity>=2 ){
    fprintf(stdout, "Peak memory usages: %f MB\n",
       sqlite3_memory_highwater(1) / 1000000.0);
  }
  if( sqlite3_memory_used()!=0 ){
    int nAlloc = 0;
    int nNotUsed = 0;
    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
    fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n",
            sqlite3_memory_used(), nAlloc);
    exit(1);
  }
  return 0;
}

/*
** END of the dbsqlfuzz code
***************************************************************************/

/* Look at a SQL text and try to determine if it begins with a database
** description, such as would be found in a dbsqlfuzz test case.  Return
** true if this does appear to be a dbsqlfuzz test case and false otherwise.
*/
static int isDbSql(unsigned char *a, int n){
  unsigned char buf[12];
  int i;
  if( n>4 && memcmp(a,"\n--\n",4)==0 ) return 1;
  while( n>0 && isspace(a[0]) ){ a++; n--; }
  for(i=0; n>0 && i<8; n--, a++){
    if( isxdigit(a[0]) ) buf[i++] = a[0];
  }
  if( i==8 && memcmp(buf,"53514c69",8)==0 ) return 1;
  return 0;
}


/* Methods for the VHandle object
*/
static int inmemClose(sqlite3_file *pFile){
  VHandle *p = (VHandle*)pFile;
  VFile *pVFile = p->pVFile;
  pVFile->nRef--;
790
791
792
793
794
795
796













797
798
799
800
801
802
803
      v *= aMult[i].iMult;
      break;
    }
  }
  if( v>0x7fffffff ) fatalError("parameter too large - max 2147483648");
  return (int)(isNeg? -v : v);
}














/*
** Print sketchy documentation for this utility program
*/
static void showHelp(void){
  printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
  printf(







>
>
>
>
>
>
>
>
>
>
>
>
>







1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
      v *= aMult[i].iMult;
      break;
    }
  }
  if( v>0x7fffffff ) fatalError("parameter too large - max 2147483648");
  return (int)(isNeg? -v : v);
}

/*
** Return the number of "v" characters in a string.  Return 0 if there
** are any characters in the string other than "v".
*/
static int numberOfVChar(const char *z){
  int N = 0;
  while( z[0] && z[0]=='v' ){
    z++;
    N++;
  }
  return z[0]==0 ? N : 0;
}

/*
** Print sketchy documentation for this utility program
*/
static void showHelp(void){
  printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
  printf(
864
865
866
867
868
869
870

871
872
873
874
875
876
877
  char *zExpSql = 0;           /* Write SQL to files in this directory */
  void *pHeap = 0;             /* Heap for use by SQLite */
  int ossFuzz = 0;             /* enable OSS-FUZZ testing */
  int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
  int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
  sqlite3_vfs *pDfltVfs;       /* The default VFS */
  int openFlags4Data;          /* Flags for sqlite3_open_v2() */


  sqlite3_initialize();
  iBegin = timeOfDay();
#ifdef __unix__
  signal(SIGALRM, timeoutHandler);
#endif
  g.zArgv0 = argv[0];







>







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  char *zExpSql = 0;           /* Write SQL to files in this directory */
  void *pHeap = 0;             /* Heap for use by SQLite */
  int ossFuzz = 0;             /* enable OSS-FUZZ testing */
  int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
  int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
  sqlite3_vfs *pDfltVfs;       /* The default VFS */
  int openFlags4Data;          /* Flags for sqlite3_open_v2() */
  int nV;                      /* How much to increase verbosity with -vvvv */

  sqlite3_initialize();
  iBegin = timeOfDay();
#ifdef __unix__
  signal(SIGALRM, timeoutHandler);
#endif
  g.zArgv0 = argv[0];
947
948
949
950
951
952
953

954
955
956
957
958
959
960
      if( strcmp(z,"prng-seed")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        g.uRandom = atoi(argv[++i]);
      }else
      if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
        quietFlag = 1;
        verboseFlag = 0;

      }else
      if( strcmp(z,"rebuild")==0 ){
        rebuildFlag = 1;
        openFlags4Data = SQLITE_OPEN_READWRITE;
      }else
      if( strcmp(z,"result-trace")==0 ){
        runFlags |= SQL_OUTPUT;







>







1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
      if( strcmp(z,"prng-seed")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        g.uRandom = atoi(argv[++i]);
      }else
      if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
        quietFlag = 1;
        verboseFlag = 0;
        eVerbosity = 0;
      }else
      if( strcmp(z,"rebuild")==0 ){
        rebuildFlag = 1;
        openFlags4Data = SQLITE_OPEN_READWRITE;
      }else
      if( strcmp(z,"result-trace")==0 ){
        runFlags |= SQL_OUTPUT;
969
970
971
972
973
974
975
976
977
978

979















980
981
982
983
984
985
986
      }else
      if( strcmp(z,"timeout-test")==0 ){
        timeoutTest = 1;
#ifndef __unix__
        fatalError("timeout is not available on non-unix systems");
#endif
      }else
      if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
        quietFlag = 0;
        verboseFlag++;

        if( verboseFlag>1 ) runFlags |= SQL_TRACE;















      }else
      {
        fatalError("unknown option: %s", argv[i]);
      }
    }else{
      nSrcDb++;
      azSrcDb = safe_realloc(azSrcDb, nSrcDb*sizeof(azSrcDb[0]));







|


>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
      }else
      if( strcmp(z,"timeout-test")==0 ){
        timeoutTest = 1;
#ifndef __unix__
        fatalError("timeout is not available on non-unix systems");
#endif
      }else
      if( strcmp(z,"verbose")==0 ){
        quietFlag = 0;
        verboseFlag++;
        eVerbosity++;
        if( verboseFlag>1 ) runFlags |= SQL_TRACE;
      }else
      if( (nV = numberOfVChar(z))>=1 ){
        quietFlag = 0;
        verboseFlag += nV;
        eVerbosity += nV;
        if( verboseFlag>1 ) runFlags |= SQL_TRACE;
      }else
      if( strcmp(z,"version")==0 ){
        int ii;
        const char *z;
        printf("SQLite %s %s\n", sqlite3_libversion(), sqlite3_sourceid());
        for(ii=0; (z = sqlite3_compileoption_get(ii))!=0; ii++){
          printf("%s\n", z);
        }
        return 0;
      }else
      {
        fatalError("unknown option: %s", argv[i]);
      }
    }else{
      nSrcDb++;
      azSrcDb = safe_realloc(azSrcDb, nSrcDb*sizeof(azSrcDb[0]));
1226
1227
1228
1229
1230
1231
1232




















1233
1234
1235
1236
1237
1238
1239
    /* Reset the in-memory virtual filesystem */
    formatVfs();
    
    /* Run a test using each SQL script against each database.
    */
    if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
    for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){




















      for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
        int openFlags;
        const char *zVfs = "inmem";
        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
                         pSql->id, pDb->id);
        if( verboseFlag ){
          printf("%s\n", g.zTestName);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
    /* Reset the in-memory virtual filesystem */
    formatVfs();
    
    /* Run a test using each SQL script against each database.
    */
    if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
    for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
      if( isDbSql(pSql->a, pSql->sz) ){
        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
        if( verboseFlag ){
          printf("%s\n", g.zTestName);
          fflush(stdout);
        }else if( !quietFlag ){
          static int prevAmt = -1;
          int idx = pSql->seq;
          int amt = idx*10/(g.nSql);
          if( amt!=prevAmt ){
            printf(" %d%%", amt*10);
            fflush(stdout);
            prevAmt = amt;
          }
        }
        runCombinedDbSqlInput(pSql->a, pSql->sz);
        nTest++;
        g.zTestName[0] = 0;
        continue;
      }
      for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
        int openFlags;
        const char *zVfs = "inmem";
        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
                         pSql->id, pDb->id);
        if( verboseFlag ){
          printf("%s\n", g.zTestName);

Added test/fuzzdata8.db.

cannot compute difference between binary files