xref: /sqlite-3.40.0/test/ossfuzz.c (revision 87f500ce)
1 /*
2 ** This module interfaces SQLite to the Google OSS-Fuzz, fuzzer as a service.
3 ** (https://github.com/google/oss-fuzz)
4 */
5 #include <stddef.h>
6 #include <stdint.h>
7 #include "sqlite3.h"
8 
9 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
10 /*
11 ** Progress handler callback
12 */
13 static int progress_handler(void *pReturn) {
14   return *(int*)pReturn;
15 }
16 #endif
17 
18 /*
19 ** Callback for sqlite3_exec().
20 */
21 static int exec_handler(void *pCnt, int argc, char **argv, char **namev){
22   int i;
23   if( argv ){
24     for(i=0; i<argc; i++) sqlite3_free(sqlite3_mprintf("%s", argv[i]));
25   }
26   return ((*(int*)pCnt)--)<=0;
27 }
28 
29 /*
30 ** Main entry point.  The fuzzer invokes this function with each
31 ** fuzzed input.
32 */
33 int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
34   int progressArg = 0;     /* 1 causes progress handler abort */
35   int execCnt = 0;         /* Abort row callback when count reaches zero */
36   char *zErrMsg = 0;       /* Error message returned by sqlite_exec() */
37   sqlite3 *db;             /* The database connection */
38   uint8_t uSelector;       /* First byte of input data[] */
39   int rc;                  /* Return code from various interfaces */
40   char *zSql;              /* Zero-terminated copy of data[] */
41 
42   if( size<3 ) return 0;   /* Early out if unsufficient data */
43 
44   /* Extract the selector byte from the beginning of the input.  But only
45   ** do this if the second byte is a \n.  If the second byte is not \n,
46   ** then use a default selector */
47   if( data[1]=='\n' ){
48     uSelector = data[0];  data += 2; size -= 2;
49   }else{
50     uSelector = 0xfd;
51   }
52 
53   /* Open the database connection.  Only use an in-memory database. */
54   rc = sqlite3_open_v2("fuzz.db", &db,
55            SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0);
56   if( rc ) return 0;
57 
58 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
59   /* Bit 0 of the selector enables progress callbacks.  Bit 1 is the
60   ** return code from progress callbacks */
61   if( uSelector & 1 ){
62     sqlite3_progress_handler(db, 4, progress_handler, (void*)&progressArg);
63   }
64 #endif
65   uSelector >>= 1;
66   progressArg = uSelector & 1;  uSelector >>= 1;
67 
68   /* Bit 2 of the selector enables foreign key constraints */
69   sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);
70   uSelector >>= 1;
71 
72   /* Remaining bits of the selector determine a limit on the number of
73   ** output rows */
74   execCnt = uSelector + 1;
75 
76   /* Run the SQL.  The sqlite_exec() interface expects a zero-terminated
77   ** string, so make a copy. */
78   zSql = sqlite3_mprintf("%.*s", (int)size, data);
79   sqlite3_exec(db, zSql, exec_handler, (void*)&execCnt, &zErrMsg);
80 
81   /* Cleanup and return */
82   sqlite3_free(zErrMsg);
83   sqlite3_free(zSql);
84   sqlite3_close(db);
85   return 0;
86 }
87