155377b47Sdrh /*
255377b47Sdrh ** This is a test interface for the ossfuzz.c module. The ossfuzz.c module
355377b47Sdrh ** is an adaptor for OSS-FUZZ. (https://github.com/google/oss-fuzz)
455377b47Sdrh **
555377b47Sdrh ** This program links against ossfuzz.c. It reads files named on the
655377b47Sdrh ** command line and passes them one by one into ossfuzz.c.
755377b47Sdrh */
855377b47Sdrh #include <stddef.h>
9*ac8ba26eSmistachkin #if !defined(_MSC_VER)
1055377b47Sdrh # include <stdint.h>
11*ac8ba26eSmistachkin #endif
1255377b47Sdrh #include <stdio.h>
1355377b47Sdrh #include <stdlib.h>
14f53524b4Sdrh #include <string.h>
1555377b47Sdrh #include "sqlite3.h"
1655377b47Sdrh
17*ac8ba26eSmistachkin #if defined(_MSC_VER)
18*ac8ba26eSmistachkin typedef unsigned char uint8_t;
19*ac8ba26eSmistachkin #endif
20*ac8ba26eSmistachkin
2155377b47Sdrh /*
2255377b47Sdrh ** The entry point in ossfuzz.c that this routine will be calling
2355377b47Sdrh */
2455377b47Sdrh int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
2555377b47Sdrh
26f53524b4Sdrh /* Must match equivalent #defines in ossfuzz.c */
27f53524b4Sdrh #define FUZZ_SQL_TRACE 0x0001 /* Set an sqlite3_trace() callback */
28f53524b4Sdrh #define FUZZ_SHOW_MAX_DELAY 0x0002 /* Show maximum progress callback delay */
29f53524b4Sdrh #define FUZZ_SHOW_ERRORS 0x0004 /* Show SQL errors */
30f53524b4Sdrh extern void ossfuzz_set_debug_flags(unsigned);
31f53524b4Sdrh
32f53524b4Sdrh
3355377b47Sdrh
3455377b47Sdrh /*
3555377b47Sdrh ** Read files named on the command-line and invoke the fuzzer for
3655377b47Sdrh ** each one.
3755377b47Sdrh */
main(int argc,char ** argv)3855377b47Sdrh int main(int argc, char **argv){
3955377b47Sdrh FILE *in;
4055377b47Sdrh int i;
4155377b47Sdrh int nErr = 0;
4255377b47Sdrh uint8_t *zBuf = 0;
4355377b47Sdrh size_t sz;
44f53524b4Sdrh unsigned mDebug = 0;
4555377b47Sdrh
4655377b47Sdrh for(i=1; i<argc; i++){
4755377b47Sdrh const char *zFilename = argv[i];
48f53524b4Sdrh if( zFilename[0]=='-' ){
49f53524b4Sdrh if( zFilename[1]=='-' ) zFilename++;
50f53524b4Sdrh if( strcmp(zFilename, "-show-errors")==0 ){
51f53524b4Sdrh mDebug |= FUZZ_SHOW_ERRORS;
52f53524b4Sdrh ossfuzz_set_debug_flags(mDebug);
53f53524b4Sdrh }else
54f53524b4Sdrh if( strcmp(zFilename, "-show-max-delay")==0 ){
55f53524b4Sdrh mDebug |= FUZZ_SHOW_MAX_DELAY;
56f53524b4Sdrh ossfuzz_set_debug_flags(mDebug);
57f53524b4Sdrh }else
58f53524b4Sdrh if( strcmp(zFilename, "-sql-trace")==0 ){
59f53524b4Sdrh mDebug |= FUZZ_SQL_TRACE;
60f53524b4Sdrh ossfuzz_set_debug_flags(mDebug);
61f53524b4Sdrh }else
62f53524b4Sdrh {
63f53524b4Sdrh printf("unknown option \"%s\"\n", argv[i]);
64f53524b4Sdrh printf("should be one of: --show-errors --show-max-delay"
65f53524b4Sdrh " --sql-trace\n");
66f53524b4Sdrh exit(1);
67f53524b4Sdrh }
68f53524b4Sdrh continue;
69f53524b4Sdrh }
7055377b47Sdrh in = fopen(zFilename, "rb");
7155377b47Sdrh if( in==0 ){
7255377b47Sdrh fprintf(stderr, "cannot open \"%s\"\n", zFilename);
7355377b47Sdrh nErr++;
7455377b47Sdrh continue;
7555377b47Sdrh }
7655377b47Sdrh fseek(in, 0, SEEK_END);
7755377b47Sdrh sz = ftell(in);
7855377b47Sdrh rewind(in);
7955377b47Sdrh zBuf = realloc(zBuf, sz);
8055377b47Sdrh if( zBuf==0 ){
8155377b47Sdrh fprintf(stderr, "cannot malloc() for %d bytes\n", (int)sz);
8255377b47Sdrh exit(1);
8355377b47Sdrh }
8455377b47Sdrh if( fread(zBuf, sz, 1, in)!=1 ){
8555377b47Sdrh fprintf(stderr, "cannot read %d bytes from \"%s\"\n",
8655377b47Sdrh (int)sz, zFilename);
8755377b47Sdrh nErr++;
8855377b47Sdrh }else{
8955377b47Sdrh printf("%s... ", zFilename);
90f53524b4Sdrh if( mDebug ) printf("\n");
9155377b47Sdrh fflush(stdout);
9255377b47Sdrh (void)LLVMFuzzerTestOneInput(zBuf, sz);
93f53524b4Sdrh if( mDebug ) printf("%s: ", zFilename);
9455377b47Sdrh printf("ok\n");
9555377b47Sdrh }
9655377b47Sdrh fclose(in);
9755377b47Sdrh }
9855377b47Sdrh free(zBuf);
9955377b47Sdrh return nErr;
10055377b47Sdrh }
101