SQLite

Check-in [d343f7d6]
Login

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

Overview
Comment:Improvements to the ossfuzz.c fuzz-testing module so that it works with -DSQLITE_OMIT_PROGRESS_CALLBACK and with -DSQLITE_OMIT_INIT.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d343f7d6b05865c282eb73a0e39dc396f2927982af45b3d045de03ef73715693
User & Date: drh 2018-11-21 14:27:34
Context
2018-11-22
19:10
Fix a problem reading from temp databases in SQLITE_DIRECT_OVERFLOW_READ builds. (check-in: 81629ba9 user: dan tags: trunk)
2018-11-21
14:27
Improvements to the ossfuzz.c fuzz-testing module so that it works with -DSQLITE_OMIT_PROGRESS_CALLBACK and with -DSQLITE_OMIT_INIT. (check-in: d343f7d6 user: drh tags: trunk)
2018-11-20
18:09
Fix problems in pragma.c causing some PRAGMA statements to test the wrong schema-cookie before proceeding, or to try to open cursors on the wrong database ("PRAGMA foreign_key_check" only). (check-in: 6982f52f user: dan tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to test/fuzzcheck.c.

401
402
403
404
405
406
407

408


409
410
411
412
413
414
415
}


/* 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->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
    clockVfs->xCurrentTimeInt64(clockVfs, &t);
  }else{
    double r;
    clockVfs->xCurrentTime(clockVfs, &r);
    t = (sqlite3_int64)(r*86400000.0);
  }







>
|
>
>







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
}


/* 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);
  }
862
863
864
865
866
867
868

869
870
871
872
873
874
875
  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() */


  iBegin = timeOfDay();
#ifdef __unix__
  signal(SIGALRM, timeoutHandler);
#endif
  g.zArgv0 = argv[0];
  openFlags4Data = SQLITE_OPEN_READONLY;
  zFailCode = getenv("TEST_FAILURE");







>







865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
  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];
  openFlags4Data = SQLITE_OPEN_READONLY;
  zFailCode = getenv("TEST_FAILURE");

Changes to test/ossfuzz.c.

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

/* Return the current real-world time in milliseconds since the
** Julian epoch (-4714-11-24).
*/
static sqlite3_int64 timeOfDay(void){
  static sqlite3_vfs *clockVfs = 0;
  sqlite3_int64 t;

  if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);


  if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
    clockVfs->xCurrentTimeInt64(clockVfs, &t);
  }else{
    double r;
    clockVfs->xCurrentTime(clockVfs, &r);
    t = (sqlite3_int64)(r*86400000.0);
  }
  return t;
}

/* 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 */

} FuzzCtx;

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** 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++;
  return rc;
}
#endif

/*
** 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.
*/
static int block_debug_pragmas(







>
|
>
>



















>


<















<







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
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86

/* Return the current real-world time in milliseconds since the
** Julian epoch (-4714-11-24).
*/
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>=2 && clockVfs->xCurrentTimeInt64!=0 ){
    clockVfs->xCurrentTimeInt64(clockVfs, &t);
  }else{
    double r;
    clockVfs->xCurrentTime(clockVfs, &r);
    t = (sqlite3_int64)(r*86400000.0);
  }
  return t;
}

/* 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 execCnt;          /* Number of calls to the sqlite3_exec callback */
} FuzzCtx;


/*
** 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++;
  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.
*/
static int block_debug_pragmas(
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  }
  return SQLITE_OK;
}

/*
** Callback for sqlite3_exec().
*/
static int exec_handler(void *pCnt, int argc, char **argv, char **namev){

  int i;
  if( argv ){
    for(i=0; i<argc; i++) sqlite3_free(sqlite3_mprintf("%s", argv[i]));
  }
  return ((*(int*)pCnt)--)<=0;
}

/*
** Main entry point.  The fuzzer invokes this function with each
** fuzzed input.
*/
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  int execCnt = 0;         /* Abort row callback when count reaches zero */
  char *zErrMsg = 0;       /* Error message returned by sqlite_exec() */
  uint8_t uSelector;       /* First byte of input data[] */
  int rc;                  /* Return code from various interfaces */
  char *zSql;              /* Zero-terminated copy of data[] */
  FuzzCtx cx;              /* Fuzzing context */

  memset(&cx, 0, sizeof(cx));
  if( size<3 ) return 0;   /* Early out if unsufficient data */

  /* Extract the selector byte from the beginning of the input.  But only
  ** do this if the second byte is a \n.  If the second byte is not \n,
  ** then use a default selector */
  if( data[1]=='\n' ){
    uSelector = data[0];  data += 2; size -= 2;
  }else{
    uSelector = 0xfd;
  }

  /* Open the database connection.  Only use an in-memory database. */

  rc = sqlite3_open_v2("fuzz.db", &cx.db,
           SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0);
  if( rc ) return 0;

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  /* 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 10 seconds have
  ** elapsed since the start of the test.
  */
  cx.iLastCb = timeOfDay();
  cx.iCutoffTime = cx.iLastCb + 10000;  /* Now + 10 seconds */

  sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx);
#endif

  /* Set a limit on the maximum size of a prepared statement */
  sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, 25000);

  /* Bit 1 of the selector enables foreign key constraints */
  sqlite3_db_config(cx.db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);
  uSelector >>= 1;

  /* Do not allow debugging pragma statements that might cause excess output */
  sqlite3_set_authorizer(cx.db, block_debug_pragmas, 0);

  /* Remaining bits of the selector determine a limit on the number of
  ** output rows */
  execCnt = uSelector + 1;

  /* Run the SQL.  The sqlite_exec() interface expects a zero-terminated
  ** string, so make a copy. */
  zSql = sqlite3_mprintf("%.*s", (int)size, data);
#ifndef SQLITE_OMIT_COMPLETE
  sqlite3_complete(zSql);
#endif
  sqlite3_exec(cx.db, zSql, exec_handler, (void*)&execCnt, &zErrMsg);

  /* Show any errors */
  if( (mDebug & FUZZ_SHOW_ERRORS)!=0 && zErrMsg ){
    printf("Error: %s\n", zErrMsg);
  }

  /* Cleanup and return */







|
>




|







<



















>




<







>















|







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  }
  return SQLITE_OK;
}

/*
** Callback for sqlite3_exec().
*/
static int exec_handler(void *pClientData, int argc, char **argv, char **namev){
  FuzzCtx *p = (FuzzCtx*)pClientData;
  int i;
  if( argv ){
    for(i=0; i<argc; i++) sqlite3_free(sqlite3_mprintf("%s", argv[i]));
  }
  return (p->execCnt--)<=0 || progress_handler(pClientData);
}

/*
** Main entry point.  The fuzzer invokes this function with each
** fuzzed input.
*/
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {

  char *zErrMsg = 0;       /* Error message returned by sqlite_exec() */
  uint8_t uSelector;       /* First byte of input data[] */
  int rc;                  /* Return code from various interfaces */
  char *zSql;              /* Zero-terminated copy of data[] */
  FuzzCtx cx;              /* Fuzzing context */

  memset(&cx, 0, sizeof(cx));
  if( size<3 ) return 0;   /* Early out if unsufficient data */

  /* Extract the selector byte from the beginning of the input.  But only
  ** do this if the second byte is a \n.  If the second byte is not \n,
  ** then use a default selector */
  if( data[1]=='\n' ){
    uSelector = data[0];  data += 2; size -= 2;
  }else{
    uSelector = 0xfd;
  }

  /* Open the database connection.  Only use an in-memory database. */
  if( sqlite3_initialize() ) return 0;
  rc = sqlite3_open_v2("fuzz.db", &cx.db,
           SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0);
  if( rc ) return 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 10 seconds have
  ** elapsed since the start of the test.
  */
  cx.iLastCb = timeOfDay();
  cx.iCutoffTime = cx.iLastCb + 10000;  /* Now + 10 seconds */
#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 */
  sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, 25000);

  /* Bit 1 of the selector enables foreign key constraints */
  sqlite3_db_config(cx.db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);
  uSelector >>= 1;

  /* Do not allow debugging pragma statements that might cause excess output */
  sqlite3_set_authorizer(cx.db, block_debug_pragmas, 0);

  /* Remaining bits of the selector determine a limit on the number of
  ** output rows */
  cx.execCnt = uSelector + 1;

  /* Run the SQL.  The sqlite_exec() interface expects a zero-terminated
  ** string, so make a copy. */
  zSql = sqlite3_mprintf("%.*s", (int)size, data);
#ifndef SQLITE_OMIT_COMPLETE
  sqlite3_complete(zSql);
#endif
  sqlite3_exec(cx.db, zSql, exec_handler, (void*)&cx, &zErrMsg);

  /* Show any errors */
  if( (mDebug & FUZZ_SHOW_ERRORS)!=0 && zErrMsg ){
    printf("Error: %s\n", zErrMsg);
  }

  /* Cleanup and return */