SQLite

Changes On Branch cli-fuzz
Login

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

Changes In Branch cli-fuzz Excluding Merge-Ins

This is equivalent to a diff from b81976c520 to d85f14c713

2024-11-11
17:03
Update this branch with latest changes and build system updates from trunk. (check-in: 52bd7953f1 user: dan tags: begin-concurrent)
17:02
Use Win32 APIs to read/write the console in Windows unless the SQLITE_USE_STDIO_FOR_CONSOLE option is defined. This is an attempt to get the build working on MinGW. (check-in: abfe488ed6 user: drh tags: trunk)
13:17
Add an -fsanitize=fuzzer compatibility mode to the CLI. (Leaf check-in: d85f14c713 user: drh tags: cli-fuzz)
09:53
Doc update to account for [05073350087b]. (check-in: b81976c520 user: stephan tags: trunk)
09:37
Rename proj-define-if-opt-truthy to the more accurate, and less verbose, proj-define-for-opt. (check-in: 0507335008 user: stephan tags: trunk)

Changes to main.mk.
1902
1903
1904
1905
1906
1907
1908










1909
1910
1911
1912
1913
1914
1915
threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
	$(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3)
xbin: threadtest5

sqlite3$(T.exe):	shell.c sqlite3.c
	$(T.link) -o $@ \
		shell.c sqlite3.c \










		$(CFLAGS.readline) $(SHELL_OPT) \
		$(LDFLAGS.libsqlite3) $(LDFLAGS.readline)

#
# Build sqlite3$(T.exe) by default except in wasi-sdk builds.  Yes, the
# semantics of 0 and 1 are confusingly swapped here.
#







>
>
>
>
>
>
>
>
>
>







1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
	$(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3)
xbin: threadtest5

sqlite3$(T.exe):	shell.c sqlite3.c
	$(T.link) -o $@ \
		shell.c sqlite3.c \
		$(CFLAGS.readline) $(SHELL_OPT) \
		$(LDFLAGS.libsqlite3) $(LDFLAGS.readline)

# The following only works if CC=clang.  Suggested command line:
#
#    make clean sqlite3_fuzzer CC=clang
#
sqlite3_fuzzer$(T.exe):	shell.c sqlite3.c
	$(T.link) -DSQLITE_SHELL_FUZZER -fsanitize=fuzzer -o $@ \
		shell.c sqlite3.c \
		$(CFLAGS.readline) $(SHELL_OPT) \
		$(LDFLAGS.libsqlite3) $(LDFLAGS.readline)

#
# Build sqlite3$(T.exe) by default except in wasi-sdk builds.  Yes, the
# semantics of 0 and 1 are confusingly swapped here.
#
Changes to src/shell.c.in.
242
243
244
245
246
247
248











249
250
251
252
253
254
255
/* Deselect most features from the console I/O package for Fiddle. */
# define SQLITE_CIO_NO_REDIRECT
# define SQLITE_CIO_NO_CLASSIFY
# define SQLITE_CIO_NO_TRANSLATE
# define SQLITE_CIO_NO_SETMODE
# define SQLITE_CIO_NO_FLUSH
#endif












#define eputz(z) sqlite3_fputs(z,stderr)
#define sputz(fp,z) sqlite3_fputs(z,fp)

/* True if the timer is enabled */
static int enableTimer = 0;








>
>
>
>
>
>
>
>
>
>
>







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* Deselect most features from the console I/O package for Fiddle. */
# define SQLITE_CIO_NO_REDIRECT
# define SQLITE_CIO_NO_CLASSIFY
# define SQLITE_CIO_NO_TRANSLATE
# define SQLITE_CIO_NO_SETMODE
# define SQLITE_CIO_NO_FLUSH
#endif

#ifdef SQLITE_SHELL_FUZZER
/* When running with -fsanitize=fuzzer, an "exit()" is really a longjmp
** back to the end of the LLVMFuzzerTestOneInput() routine. */
# include <setjmp.h>
static jmp_buf shellSetJmpEnv;
static void shell_exit(int rc){ longjmp(shellSetJmpEnv, rc); }
#else
/* For normal builds, exit() is an exit() */
static void shell_exit(int rc){ exit(rc); }
#endif

#define eputz(z) sqlite3_fputs(z,stderr)
#define sputz(fp,z) sqlite3_fputs(z,fp)

/* True if the timer is enabled */
static int enableTimer = 0;

484
485
486
487
488
489
490

491
492
493
494
495
496
497

498
499
500
501
502
503
504
static char *shell_strncpy(char *dest, const char *src, size_t n){
  size_t i;
  for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
  dest[i] = 0;
  return dest;
}


/*
** strcpy() workalike to squelch an unwarranted link-time warning
** from OpenBSD.
*/
static void shell_strcpy(char *dest, const char *src){
  while( (*(dest++) = *(src++))!=0 ){}
}


/*
** Optionally disable dynamic continuation prompt.
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
** or open parentheses level if non-zero, or continuation prompt as set.
** This facility interacts with the scanner and process_input() where the
** below 5 macros are used.







>







>







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
static char *shell_strncpy(char *dest, const char *src, size_t n){
  size_t i;
  for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
  dest[i] = 0;
  return dest;
}

#ifndef SQLITE_SHELL_FUZZER
/*
** strcpy() workalike to squelch an unwarranted link-time warning
** from OpenBSD.
*/
static void shell_strcpy(char *dest, const char *src){
  while( (*(dest++) = *(src++))!=0 ){}
}
#endif

/*
** Optionally disable dynamic continuation prompt.
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
** or open parentheses level if non-zero, or continuation prompt as set.
** This facility interacts with the scanner and process_input() where the
** below 5 macros are used.
547
548
549
550
551
552
553

554
555
556
557
558
559
560
    p->acAwait[0] = 0;
  }else{
    p->acAwait[0] = c;
    p->zScannerAwaits = p->acAwait;
  }
}


/* Upon demand, derive the continuation prompt to display. */
static char *dynamicContinuePrompt(void){
  if( continuePrompt[0]==0
      || (dynPrompt.zScannerAwaits==0 && dynPrompt.inParenLevel == 0) ){
    return continuePrompt;
  }else{
    if( dynPrompt.zScannerAwaits ){







>







560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
    p->acAwait[0] = 0;
  }else{
    p->acAwait[0] = c;
    p->zScannerAwaits = p->acAwait;
  }
}

#ifndef SQLITE_SHELL_FUZZER
/* Upon demand, derive the continuation prompt to display. */
static char *dynamicContinuePrompt(void){
  if( continuePrompt[0]==0
      || (dynPrompt.zScannerAwaits==0 && dynPrompt.inParenLevel == 0) ){
    return continuePrompt;
  }else{
    if( dynPrompt.zScannerAwaits ){
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590
591
592
593
594
595
      }
      shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
                    PROMPT_LEN_MAX-4);
    }
  }
  return dynPrompt.dynamicPrompt;
}

#endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */

/* Indicate out-of-memory and exit. */
static void shell_out_of_memory(void){
  eputz("Error: out of memory\n");
  exit(1);
}

/* Check a pointer to see if it is NULL.  If it is NULL, exit with an
** out-of-memory error.
*/
static void shell_check_oom(const void *p){
  if( p==0 ) shell_out_of_memory();







>





|







590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
      }
      shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
                    PROMPT_LEN_MAX-4);
    }
  }
  return dynPrompt.dynamicPrompt;
}
#endif /* !defined(SQLITE_SHELL_FUZZER) */
#endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */

/* Indicate out-of-memory and exit. */
static void shell_out_of_memory(void){
  eputz("Error: out of memory\n");
  shell_exit(1);
}

/* Check a pointer to see if it is NULL.  If it is NULL, exit with an
** out-of-memory error.
*/
static void shell_check_oom(const void *p){
  if( p==0 ) shell_out_of_memory();
905
906
907
908
909
910
911

912
913
914
915
916
917
918
  }else{
    return 0;
  }
#endif
#undef STAT_CHR_SRC
}


/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** If zLine is not NULL then it is a malloced buffer returned from







>







920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  }else{
    return 0;
  }
#endif
#undef STAT_CHR_SRC
}

#ifndef SQLITE_SHELL_FUZZER
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** If zLine is not NULL then it is a malloced buffer returned from
942
943
944
945
946
947
948

949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
      if( n>0 && zLine[n-1]=='\r' ) n--;
      zLine[n] = 0;
      break;
    }
  }
  return zLine;
}


/*
** Retrieve a single line of input text.
**
** If in==0 then read from standard input and prompt before each line.
** If isContinuation is true, then a continuation prompt is appropriate.
** If isContinuation is zero, then the main prompt should be used.
**
** If zPrior is not NULL then it is a buffer from a prior call to this
** routine that can be reused.
**
** The result is stored in space obtained from malloc() and must either
** be freed by the caller or else passed back into this routine via the
** zPrior argument for reuse.
*/
#ifndef SQLITE_SHELL_FIDDLE
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  char *zPrompt;
  char *zResult;
  if( in!=0 ){
    zResult = local_getline(zPrior, in);
  }else{
    zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt;







>















|







958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
      if( n>0 && zLine[n-1]=='\r' ) n--;
      zLine[n] = 0;
      break;
    }
  }
  return zLine;
}
#endif /* !defined(SQLITE_SHELL_FUZZER) */

/*
** Retrieve a single line of input text.
**
** If in==0 then read from standard input and prompt before each line.
** If isContinuation is true, then a continuation prompt is appropriate.
** If isContinuation is zero, then the main prompt should be used.
**
** If zPrior is not NULL then it is a buffer from a prior call to this
** routine that can be reused.
**
** The result is stored in space obtained from malloc() and must either
** be freed by the caller or else passed back into this routine via the
** zPrior argument for reuse.
*/
#if !defined(SQLITE_SHELL_FIDDLE) && !defined(SQLITE_SHELL_FUZZER)
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  char *zPrompt;
  char *zResult;
  if( in!=0 ){
    zResult = local_getline(zPrior, in);
  }else{
    zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt;
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
  if( p->bSafeMode ){
    va_list ap;
    char *zMsg;
    va_start(ap, zErrMsg);
    zMsg = sqlite3_vmprintf(zErrMsg, ap);
    va_end(ap);
    sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg);
    exit(1);
  }
}

/*
** SQL function:   edit(VALUE)
**                 edit(VALUE,EDITOR)
**







|







1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
  if( p->bSafeMode ){
    va_list ap;
    char *zMsg;
    va_start(ap, zErrMsg);
    zMsg = sqlite3_vmprintf(zErrMsg, ap);
    va_end(ap);
    sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg);
    shell_exit(1);
  }
}

/*
** SQL function:   edit(VALUE)
**                 edit(VALUE,EDITOR)
**
2239
2240
2241
2242
2243
2244
2245

2246
2247
2248
2249
2250
2251
2252
2253

2254
2255
2256
2257
2258
2259
2260
    }
  }
  if( bSep ){
    sqlite3_fputs(p->colSeparator, p->out);
  }
}


/*
** This routine runs when the user presses Ctrl-C
*/
static void interrupt_handler(int NotUsed){
  UNUSED_PARAMETER(NotUsed);
  if( ++seenInterrupt>1 ) exit(1);
  if( globalDb ) sqlite3_interrupt(globalDb);
}


#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
/*
** This routine runs for console events (e.g. Ctrl-C) on Win32
*/
static BOOL WINAPI ConsoleCtrlHandler(
  DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */







>





|


>







2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
    }
  }
  if( bSep ){
    sqlite3_fputs(p->colSeparator, p->out);
  }
}

#ifndef SQLITE_SHELL_FUZZER
/*
** This routine runs when the user presses Ctrl-C
*/
static void interrupt_handler(int NotUsed){
  UNUSED_PARAMETER(NotUsed);
  if( ++seenInterrupt>1 ) shell_exit(1);
  if( globalDb ) sqlite3_interrupt(globalDb);
}
#endif /* !defined(SQLITE_SHELL_FUZZER) */

#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
/*
** This routine runs for console events (e.g. Ctrl-C) on Win32
*/
static BOOL WINAPI ConsoleCtrlHandler(
  DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
        break;
      }
    }
    if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
      sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
            zDbFilename, sqlite3_errmsg(p->db));
      if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
        exit(1);
      }
      sqlite3_close(p->db);
      sqlite3_open(":memory:", &p->db);
      if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
        sqlite3_fputs("Also: unable to open substitute in-memory database.\n",
                      stderr);
        exit(1);
      }else{
        sqlite3_fprintf(stderr,
              "Notice: using substitute in-memory database instead of \"%s\"\n",
              zDbFilename);
      }
    }
    globalDb = p->db;







|






|







5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
        break;
      }
    }
    if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
      sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
            zDbFilename, sqlite3_errmsg(p->db));
      if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
        shell_exit(1);
      }
      sqlite3_close(p->db);
      sqlite3_open(":memory:", &p->db);
      if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
        sqlite3_fputs("Also: unable to open substitute in-memory database.\n",
                      stderr);
        shell_exit(1);
      }else{
        sqlite3_fprintf(stderr,
              "Notice: using substitute in-memory database instead of \"%s\"\n",
              zDbFilename);
      }
    }
    globalDb = p->db;
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
      eputz("Usage: .eqp off|on|trace|trigger|full\n");
      rc = 1;
    }
  }else

#ifndef SQLITE_SHELL_FIDDLE
  if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){
    if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
    rc = 2;
  }else
#endif

  /* The ".explain" command is automatic now.  It is largely pointless.  It
  ** retained purely for backwards compatibility */
  if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){







|







8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
      eputz("Usage: .eqp off|on|trace|trigger|full\n");
      rc = 1;
    }
  }else

#ifndef SQLITE_SHELL_FIDDLE
  if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){
    if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) shell_exit(rc);
    rc = 2;
  }else
#endif

  /* The ".explain" command is automatic now.  It is largely pointless.  It
  ** retained purely for backwards compatibility */
  if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
  if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
    if( nArg!=2 ){
      eputz("Usage: .nonce NONCE\n");
      rc = 1;
    }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
      sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n",
            p->lineno, azArg[1]);
      exit(1);
    }else{
      p->bSafeMode = 0;
      return 0;  /* Return immediately to bypass the safe mode reset
                 ** at the end of this procedure */
    }
  }else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */







|







9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
  if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
    if( nArg!=2 ){
      eputz("Usage: .nonce NONCE\n");
      rc = 1;
    }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
      sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n",
            p->lineno, azArg[1]);
      shell_exit(1);
    }else{
      p->bSafeMode = 0;
      return 0;  /* Return immediately to bypass the safe mode reset
                 ** at the end of this procedure */
    }
  }else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
12169
12170
12171
12172
12173
12174
12175













































12176
12177
12178
12179
12180
12181
12182
  shell_check_oom(zLine);
  memcpy(zLine, zBegin, nZ);
  zLine[nZ] = 0;
  return zLine;
}
#endif /* SQLITE_SHELL_FIDDLE */














































/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**







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







12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
  shell_check_oom(zLine);
  memcpy(zLine, zBegin, nZ);
  zLine[nZ] = 0;
  return zLine;
}
#endif /* SQLITE_SHELL_FIDDLE */

#ifdef SQLITE_SHELL_FUZZER
/*
** Global state variables used to store the fuzzer's input
*/
static const char *aFuzzData;  /* Fuzzer input */
static size_t nFuzz;           /* Bytes of content in aFuzzData */
static size_t nFuzzUsed;       /* Bytes read so far */

/*
** Alternate one_input_line() impl for when the CLI is being fuzzed.
** The input comes from the fuzzer.
*/
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  char *zLine = 0;
  size_t n;
  size_t nPrior;
  size_t nLine;

  UNUSED_PARAMETER(in);
  UNUSED_PARAMETER(isContinuation);
  if( nFuzz<=nFuzzUsed ) return 0;
  for(n=nFuzzUsed; n<nFuzz && aFuzzData[n]!='\n'; n++){}
  if( n<nFuzz ) n++;
  nPrior = zPrior ? strlen(zPrior) : 0;
  nLine = nPrior + n + 1;
  if( zPrior ){
    zLine = realloc(zPrior, nLine);
  }else{
    zLine = malloc(nLine);
  }
  if( zLine==0 ){
    free(zPrior);
    return 0;
  }
  if( zPrior ) memcpy(zLine, zPrior, nPrior);
  memcpy(zLine+nPrior, aFuzzData+nFuzz, n);
  nLine--;
  if( nLine>0 && zLine[nLine]=='\n' ) nLine--;
  if( nLine>0 && zLine[nLine]=='\r' ) nLine--;
  zLine[nLine] = 0;
  nFuzzUsed += n;
  return zLine;
}
#endif /* SQLITE_SHELL_FUZZER */

/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
    sqliterc = zBuf;
  }
  p->in = sqlite3_fopen(sqliterc,"rb");
  if( p->in ){
    if( stdin_is_interactive ){
      sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
    }
    if( process_input(p) && bail_on_error ) exit(1);
    fclose(p->in);
  }else if( sqliterc_override!=0 ){
    sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
    if( bail_on_error ) exit(1);
  }
  p->in = inSaved;
  p->lineno = savedLineno;
  sqlite3_free(zBuf);
}

/*







|



|







12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
    sqliterc = zBuf;
  }
  p->in = sqlite3_fopen(sqliterc,"rb");
  if( p->in ){
    if( stdin_is_interactive ){
      sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
    }
    if( process_input(p) && bail_on_error ) shell_exit(1);
    fclose(p->in);
  }else if( sqliterc_override!=0 ){
    sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
    if( bail_on_error ) shell_exit(1);
  }
  p->in = inSaved;
  p->lineno = savedLineno;
  sqlite3_free(zBuf);
}

/*
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
       "FILENAME is the name of an SQLite database. A new database is created\n"
       "if the file does not previously exist. Defaults to :memory:.\n", Argv0);
  if( showDetail ){
    sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions);
  }else{
    eputz("Use the -help option for additional information\n");
  }
  exit(0);
}

/*
** Internal check:  Verify that the SQLite is uninitialized.  Print a
** error message if it is initialized.
*/
static void verify_uninitialized(void){







|







12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
       "FILENAME is the name of an SQLite database. A new database is created\n"
       "if the file does not previously exist. Defaults to :memory:.\n", Argv0);
  if( showDetail ){
    sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions);
  }else{
    eputz("Use the -help option for additional information\n");
  }
  shell_exit(0);
}

/*
** Internal check:  Verify that the SQLite is uninitialized.  Print a
** error message if it is initialized.
*/
static void verify_uninitialized(void){
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611



12612
12613
12614
12615
12616
12617
12618
** Get the argument to an --option.  Throw an error and die if no argument
** is available.
*/
static char *cmdline_option_value(int argc, char **argv, int i){
  if( i==argc ){
    sqlite3_fprintf(stderr,
            "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]);
    exit(1);
  }
  return argv[i];
}

static void sayAbnormalExit(void){
  if( seenInterrupt ) eputz("Program interrupted.\n");
}

#ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) \
   && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
#    define SQLITE_SHELL_IS_UTF8          (0)
#  else
#    define SQLITE_SHELL_IS_UTF8          (1)
#  endif
#endif

#ifdef SQLITE_SHELL_FIDDLE
#  define main fiddle_main



#endif

#if SQLITE_SHELL_IS_UTF8
int SQLITE_CDECL main(int argc, char **argv){
#else
int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  char **argv;







|



















>
>
>







12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
** Get the argument to an --option.  Throw an error and die if no argument
** is available.
*/
static char *cmdline_option_value(int argc, char **argv, int i){
  if( i==argc ){
    sqlite3_fprintf(stderr,
            "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]);
    shell_exit(1);
  }
  return argv[i];
}

static void sayAbnormalExit(void){
  if( seenInterrupt ) eputz("Program interrupted.\n");
}

#ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) \
   && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
#    define SQLITE_SHELL_IS_UTF8          (0)
#  else
#    define SQLITE_SHELL_IS_UTF8          (1)
#  endif
#endif

#ifdef SQLITE_SHELL_FIDDLE
#  define main fiddle_main
#endif
#ifdef SQLITE_SHELL_FUZZER
#  define main fuzzer_main
#endif

#if SQLITE_SHELL_IS_UTF8
int SQLITE_CDECL main(int argc, char **argv){
#else
int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  char **argv;
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648



12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
  const char *zVfs = 0;           /* Value of -vfs command-line option */
#if !SQLITE_SHELL_IS_UTF8
  char **argvToFree = 0;
  int argcToFree = 0;
#endif
  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */

#ifdef SQLITE_SHELL_FIDDLE
  stdin_is_interactive = 0;
  stdout_is_console = 1;
  data.wasm.zDefaultDbName = "/fiddle.sqlite3";



#else
  stdin_is_interactive = isatty(0);
  stdout_is_console = isatty(1);
#endif
  atexit(sayAbnormalExit);
#ifdef SQLITE_DEBUG
  mem_main_enter = sqlite3_memory_used();
#endif
#if !defined(_WIN32_WCE)
  if( getenv("SQLITE_DEBUG_BREAK") ){
    if( isatty(0) && isatty(2) ){
      char zLine[100];
      sqlite3_fprintf(stderr,
            "attach debugger to process %d and press ENTER to continue...",
            GETPID());
      if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0
       && cli_strcmp(zLine,"stop")==0
      ){
        exit(1);
      }
    }else{
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
      __debugbreak();
#else
      DebugBreak();
#endif
#elif defined(SIGTRAP)
      raise(SIGTRAP);
#endif
    }
  }
#endif
  /* Register a valid signal handler early, before much else is done. */
#ifdef SIGINT
  signal(SIGINT, interrupt_handler);
#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
  if( !SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE) ){
    eputz("No ^C handler.\n");
  }
#endif

#if USE_SYSTEM_SQLITE+0!=1
  if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
    sqlite3_fprintf(stderr,
          "SQLite header and source version mismatch\n%s\n%s\n",
          sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
#endif
  main_init(&data);

  /* On Windows, we must translate command-line arguments into UTF-8.
  ** The SQLite memory allocator subsystem has to be enabled in order to
  ** do this.  But we want to run an sqlite3_shutdown() afterwards so that







|



>
>
>


















|















|












|







12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
  const char *zVfs = 0;           /* Value of -vfs command-line option */
#if !SQLITE_SHELL_IS_UTF8
  char **argvToFree = 0;
  int argcToFree = 0;
#endif
  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */

#if defined(SQLITE_SHELL_FIDDLE)
  stdin_is_interactive = 0;
  stdout_is_console = 1;
  data.wasm.zDefaultDbName = "/fiddle.sqlite3";
#elif defined(SQLITE_SHELL_FUZZER)
  stdin_is_interactive = 0;
  stdout_is_console = 0;
#else
  stdin_is_interactive = isatty(0);
  stdout_is_console = isatty(1);
#endif
  atexit(sayAbnormalExit);
#ifdef SQLITE_DEBUG
  mem_main_enter = sqlite3_memory_used();
#endif
#if !defined(_WIN32_WCE)
  if( getenv("SQLITE_DEBUG_BREAK") ){
    if( isatty(0) && isatty(2) ){
      char zLine[100];
      sqlite3_fprintf(stderr,
            "attach debugger to process %d and press ENTER to continue...",
            GETPID());
      if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0
       && cli_strcmp(zLine,"stop")==0
      ){
        shell_exit(1);
      }
    }else{
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
      __debugbreak();
#else
      DebugBreak();
#endif
#elif defined(SIGTRAP)
      raise(SIGTRAP);
#endif
    }
  }
#endif
  /* Register a valid signal handler early, before much else is done. */
#if defined(SIGINT) && !defined(SQLITE_SHELL_FUZZER)
  signal(SIGINT, interrupt_handler);
#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
  if( !SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE) ){
    eputz("No ^C handler.\n");
  }
#endif

#if USE_SYSTEM_SQLITE+0!=1
  if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
    sqlite3_fprintf(stderr,
          "SQLite header and source version mismatch\n%s\n%s\n",
          sqlite3_sourceid(), SQLITE_SOURCE_ID);
    shell_exit(1);
  }
#endif
  main_init(&data);

  /* On Windows, we must translate command-line arguments into UTF-8.
  ** The SQLite memory allocator subsystem has to be enabled in order to
  ** do this.  But we want to run an sqlite3_shutdown() afterwards so that
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927

  if( zVfs ){
    sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
    if( pVfs ){
      sqlite3_vfs_register(pVfs, 1);
    }else{
      sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs);
      exit(1);
    }
  }

  if( data.pAuxDb->zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
    data.pAuxDb->zDbFilename = ":memory:";
    warnInmemoryDb = argc==1;







|







12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997

  if( zVfs ){
    sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
    if( pVfs ){
      sqlite3_vfs_register(pVfs, 1);
    }else{
      sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs);
      shell_exit(1);
    }
  }

  if( data.pAuxDb->zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
    data.pAuxDb->zDbFilename = ":memory:";
    warnInmemoryDb = argc==1;
13266
13267
13268
13269
13270
13271
13272




























13273
13274
13275
13276
13277
13278
13279
#endif
#else /* SQLITE_SHELL_FIDDLE... */
  shell_main_exit:
#endif
  return rc;
}






























#ifdef SQLITE_SHELL_FIDDLE
/* Only for emcc experimentation purposes. */
int fiddle_experiment(int a,int b){
  return a + b;
}








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







13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
#endif
#else /* SQLITE_SHELL_FIDDLE... */
  shell_main_exit:
#endif
  return rc;
}

#ifdef SQLITE_SHELL_FUZZER
/* The fuzzer invokes this routine for each test case.  aData[] contains
** text that is presumed input to the shell.
*/
int LLVMFuzzerTestOneInput(const uint8_t *aData, size_t nByte){
  char *argv[4];
  enableTimer = 0;
  bail_on_error = 0;
  stdin_is_interactive = 0;
  stdout_is_console = 0;
  globalDb = 0;
  seenInterrupt = 0;
  Argv0 = 0;
  argv[0] = "fuzzing-sqlite3";
  argv[1] = ":memory:";
  argv[2] = "--safe";
  argv[3] = 0;
  aFuzzData = (const char*)aData;
  nFuzz = nByte;
  nFuzzUsed = 0;
  if( setjmp(shellSetJmpEnv)==0 ){
    (void)fuzzer_main(3, argv);
  }
  sqlite3_shutdown();
  return 0;
}
#endif /* SQLITE_SHELL_FUZZER */


#ifdef SQLITE_SHELL_FIDDLE
/* Only for emcc experimentation purposes. */
int fiddle_experiment(int a,int b){
  return a + b;
}