Fossil SCM

Bring the built-in SQLite and the regexp implementation into alignment with upstream.

drh 2025-09-26 13:36 trunk
Commit 9642cde38468682b797d1138102c23bd3d25d259303f322e7502c9cd53956a94
+74 -50
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1512,31 +1512,31 @@
15121512
}
15131513
}
15141514
if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
15151515
return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
15161516
integer_overflow:
1517
- return isNeg ? 0x8000000000000000LL : 0x7fffffffffffffffLL;
1517
+ return isNeg ? (i64)0x8000000000000000LL : 0x7fffffffffffffffLL;
15181518
}
15191519
15201520
/*
15211521
** A variable length string to which one can append text.
15221522
*/
15231523
typedef struct ShellText ShellText;
15241524
struct ShellText {
1525
- char *z;
1526
- int n;
1527
- int nAlloc;
1525
+ char *zTxt; /* The text */
1526
+ i64 n; /* Number of bytes of zTxt[] actually used */
1527
+ i64 nAlloc; /* Number of bytes allocated for zTxt[] */
15281528
};
15291529
15301530
/*
15311531
** Initialize and destroy a ShellText object
15321532
*/
15331533
static void initText(ShellText *p){
15341534
memset(p, 0, sizeof(*p));
15351535
}
15361536
static void freeText(ShellText *p){
1537
- free(p->z);
1537
+ sqlite3_free(p->zTxt);
15381538
initText(p);
15391539
}
15401540
15411541
/* zIn is either a pointer to a NULL-terminated string in memory obtained
15421542
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
@@ -1557,30 +1557,30 @@
15571557
for(i=0; i<nAppend; i++){
15581558
if( zAppend[i]==quote ) len++;
15591559
}
15601560
}
15611561
1562
- if( p->z==0 || p->n+len>=p->nAlloc ){
1562
+ if( p->zTxt==0 || p->n+len>=p->nAlloc ){
15631563
p->nAlloc = p->nAlloc*2 + len + 20;
1564
- p->z = realloc(p->z, p->nAlloc);
1565
- shell_check_oom(p->z);
1564
+ p->zTxt = sqlite3_realloc64(p->zTxt, p->nAlloc);
1565
+ shell_check_oom(p->zTxt);
15661566
}
15671567
15681568
if( quote ){
1569
- char *zCsr = p->z+p->n;
1569
+ char *zCsr = p->zTxt+p->n;
15701570
*zCsr++ = quote;
15711571
for(i=0; i<nAppend; i++){
15721572
*zCsr++ = zAppend[i];
15731573
if( zAppend[i]==quote ) *zCsr++ = quote;
15741574
}
15751575
*zCsr++ = quote;
1576
- p->n = (int)(zCsr - p->z);
1576
+ p->n = (i64)(zCsr - p->zTxt);
15771577
*zCsr = '\0';
15781578
}else{
1579
- memcpy(p->z+p->n, zAppend, nAppend);
1579
+ memcpy(p->zTxt+p->n, zAppend, nAppend);
15801580
p->n += nAppend;
1581
- p->z[p->n] = '\0';
1581
+ p->zTxt[p->n] = '\0';
15821582
}
15831583
}
15841584
15851585
/*
15861586
** Attempt to determine if identifier zName needs to be quoted, either
@@ -1601,10 +1601,13 @@
16011601
}
16021602
16031603
/*
16041604
** Construct a fake object name and column list to describe the structure
16051605
** of the view, virtual table, or table valued function zSchema.zName.
1606
+**
1607
+** The returned string comes from sqlite3_mprintf() and should be freed
1608
+** by the caller using sqlite3_free().
16061609
*/
16071610
static char *shellFakeSchema(
16081611
sqlite3 *db, /* The database connection containing the vtab */
16091612
const char *zSchema, /* Schema of the database holding the vtab */
16101613
const char *zName /* The name of the virtual table */
@@ -1641,13 +1644,13 @@
16411644
}
16421645
appendText(&s, ")", 0);
16431646
sqlite3_finalize(pStmt);
16441647
if( nRow==0 ){
16451648
freeText(&s);
1646
- s.z = 0;
1649
+ s.zTxt = 0;
16471650
}
1648
- return s.z;
1651
+ return s.zTxt;
16491652
}
16501653
16511654
/*
16521655
** SQL function: strtod(X)
16531656
**
@@ -1746,11 +1749,11 @@
17461749
if( z==0 ){
17471750
z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
17481751
}else{
17491752
z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
17501753
}
1751
- free(zFake);
1754
+ sqlite3_free(zFake);
17521755
}
17531756
if( z ){
17541757
sqlite3_result_text(pCtx, z, -1, sqlite3_free);
17551758
return;
17561759
}
@@ -6993,11 +6996,11 @@
69936996
** The following regular expression syntax is supported:
69946997
**
69956998
** X* zero or more occurrences of X
69966999
** X+ one or more occurrences of X
69977000
** X? zero or one occurrences of X
6998
-** X{p,q} between p and q occurrences of X
7001
+** X{p,q} between p and q occurrences of X, 0 <= p,q <= 999
69997002
** (X) match X
70007003
** X|Y X or Y
70017004
** ^X X occurring at the beginning of the string
70027005
** X$ X occurring at the end of the string
70037006
** . Match any single character
@@ -7022,15 +7025,22 @@
70227025
** expression and M is the size of the input string. The matcher never
70237026
** exhibits exponential behavior. Note that the X{p,q} operator expands
70247027
** to p copies of X following by q-p copies of X? and that the size of the
70257028
** regular expression in the O(N*M) performance bound is computed after
70267029
** this expansion.
7030
+**
7031
+** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
7032
+** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999.
70277033
*/
70287034
#include <string.h>
70297035
#include <stdlib.h>
70307036
/* #include "sqlite3ext.h" */
70317037
SQLITE_EXTENSION_INIT1
7038
+
7039
+#ifndef SQLITE_MAX_REGEXP_REPEAT
7040
+# define SQLITE_MAX_REGEXP_REPEAT 999
7041
+#endif
70327042
70337043
/*
70347044
** The following #defines change the names of some functions implemented in
70357045
** this file to prevent name collisions with C-library functions of the
70367046
** same name.
@@ -7530,22 +7540,30 @@
75307540
case '^': {
75317541
re_append(p, RE_OP_ATSTART, 0);
75327542
break;
75337543
}
75347544
case '{': {
7535
- int m = 0, n = 0;
7536
- int sz, j;
7545
+ unsigned int m = 0, n = 0;
7546
+ unsigned int sz, j;
75377547
if( iPrev<0 ) return "'{m,n}' without operand";
7538
- while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
7548
+ while( (c=rePeek(p))>='0' && c<='9' ){
7549
+ m = m*10 + c - '0';
7550
+ if( m>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
7551
+ p->sIn.i++;
7552
+ }
75397553
n = m;
75407554
if( c==',' ){
75417555
p->sIn.i++;
75427556
n = 0;
7543
- while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
7557
+ while( (c=rePeek(p))>='0' && c<='9' ){
7558
+ n = n*10 + c-'0';
7559
+ if( n>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
7560
+ p->sIn.i++;
7561
+ }
75447562
}
75457563
if( c!='}' ) return "unmatched '{'";
7546
- if( n>0 && n<m ) return "n less than m in '{m,n}'";
7564
+ if( n<m ) return "n less than m in '{m,n}'";
75477565
p->sIn.i++;
75487566
sz = p->nState - iPrev;
75497567
if( m==0 ){
75507568
if( n==0 ) return "both m and n are zero in '{m,n}'";
75517569
re_insert(p, iPrev, RE_OP_FORK, sz+1);
@@ -22098,11 +22116,11 @@
2209822116
*/
2209922117
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
2210022118
int i;
2210122119
unsigned char *aBlob = (unsigned char*)pBlob;
2210222120
22103
- char *zStr = sqlite3_malloc(nBlob*2 + 1);
22121
+ char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1);
2210422122
shell_check_oom(zStr);
2210522123
2210622124
for(i=0; i<nBlob; i++){
2210722125
static const char aHex[] = {
2210822126
'0', '1', '2', '3', '4', '5', '6', '7',
@@ -23375,11 +23393,16 @@
2337523393
if( p->zDestTable ){
2337623394
sqlite3_free(p->zDestTable);
2337723395
p->zDestTable = 0;
2337823396
}
2337923397
if( zName==0 ) return;
23380
- p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
23398
+ if( quoteChar(zName) ){
23399
+ p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
23400
+ }else{
23401
+ p->zDestTable = sqlite3_mprintf("%s", zName);
23402
+ }
23403
+ shell_check_oom(p->zDestTable);
2338123404
}
2338223405
2338323406
/*
2338423407
** Maybe construct two lines of text that point out the position of a
2338523408
** syntax error. Return a pointer to the text, in memory obtained from
@@ -25182,17 +25205,17 @@
2518225205
appendText(&sSelect, " FROM ", 0);
2518325206
appendText(&sSelect, zTable, quoteChar(zTable));
2518425207
2518525208
savedDestTable = p->zDestTable;
2518625209
savedMode = p->mode;
25187
- p->zDestTable = sTable.z;
25210
+ p->zDestTable = sTable.zTxt;
2518825211
p->mode = p->cMode = MODE_Insert;
25189
- rc = shell_exec(p, sSelect.z, 0);
25212
+ rc = shell_exec(p, sSelect.zTxt, 0);
2519025213
if( (rc&0xff)==SQLITE_CORRUPT ){
2519125214
sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
2519225215
toggleSelectOrder(p->db);
25193
- shell_exec(p, sSelect.z, 0);
25216
+ shell_exec(p, sSelect.zTxt, 0);
2519425217
toggleSelectOrder(p->db);
2519525218
}
2519625219
p->zDestTable = savedDestTable;
2519725220
p->mode = savedMode;
2519825221
freeText(&sTable);
@@ -25802,14 +25825,14 @@
2580225825
** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
2580325826
*/
2580425827
static unsigned char *readHexDb(ShellState *p, int *pnData){
2580525828
unsigned char *a = 0;
2580625829
int nLine;
25807
- int n = 0;
25830
+ int n = 0; /* Size of db per first line of hex dump */
25831
+ i64 sz = 0; /* n rounded up to nearest page boundary */
2580825832
int pgsz = 0;
25809
- int iOffset = 0;
25810
- int j, k;
25833
+ i64 iOffset = 0;
2581125834
int rc;
2581225835
FILE *in;
2581325836
const char *zDbFilename = p->pAuxDb->zDbFilename;
2581425837
unsigned int x[16];
2581525838
char zLine[1000];
@@ -25829,20 +25852,21 @@
2582925852
nLine++;
2583025853
if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
2583125854
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
2583225855
if( rc!=2 ) goto readHexDb_error;
2583325856
if( n<0 ) goto readHexDb_error;
25834
- if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
25835
- n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
25836
- a = sqlite3_malloc( n ? n : 1 );
25837
- shell_check_oom(a);
25838
- memset(a, 0, n);
2583925857
if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
2584025858
sqlite3_fputs("invalid pagesize\n", stderr);
2584125859
goto readHexDb_error;
2584225860
}
25861
+ sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */
25862
+ a = sqlite3_malloc( sz ? sz : 1 );
25863
+ shell_check_oom(a);
25864
+ memset(a, 0, sz);
2584325865
for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
25866
+ int j = 0; /* Page number from "| page" line */
25867
+ int k = 0; /* Offset from "| page" line */
2584425868
rc = sscanf(zLine, "| page %d offset %d", &j, &k);
2584525869
if( rc==2 ){
2584625870
iOffset = k;
2584725871
continue;
2584825872
}
@@ -25851,18 +25875,18 @@
2585125875
}
2585225876
rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
2585325877
&j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
2585425878
&x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
2585525879
if( rc==17 ){
25856
- k = iOffset+j;
25857
- if( k+16<=n && k>=0 ){
25880
+ i64 iOff = iOffset+j;
25881
+ if( iOff+16<=sz && iOff>=0 ){
2585825882
int ii;
25859
- for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
25883
+ for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff;
2586025884
}
2586125885
}
2586225886
}
25863
- *pnData = n;
25887
+ *pnData = sz;
2586425888
if( in!=p->in ){
2586525889
fclose(in);
2586625890
}else{
2586725891
p->lineno = nLine;
2586825892
}
@@ -25925,11 +25949,11 @@
2592525949
p->pLog = pSavedLog;
2592625950
2592725951
if( zFake ){
2592825952
sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
2592925953
-1, sqlite3_free);
25930
- free(zFake);
25954
+ sqlite3_free(zFake);
2593125955
}
2593225956
}
2593325957
2593425958
/* Flags for open_db().
2593525959
**
@@ -31009,13 +31033,13 @@
3100931033
appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
3101031034
}
3101131035
appendText(&sSelect, "sql IS NOT NULL"
3101231036
" ORDER BY snum, rowid", 0);
3101331037
if( bDebug ){
31014
- sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z);
31038
+ sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt);
3101531039
}else{
31016
- rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
31040
+ rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg);
3101731041
}
3101831042
freeText(&sSelect);
3101931043
}
3102031044
if( zErrMsg ){
3102131045
shellEmitError(zErrMsg);
@@ -31335,26 +31359,26 @@
3133531359
sqlite3_fprintf(p->out, "%s\n", zSql);
3133631360
}else
3133731361
if( cli_strcmp(zOp,"run")==0 ){
3133831362
char *zErrMsg = 0;
3133931363
str.n = 0;
31340
- str.z[0] = 0;
31364
+ str.zTxt[0] = 0;
3134131365
rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
3134231366
nTest++;
3134331367
if( bVerbose ){
31344
- sqlite3_fprintf(p->out, "Result: %s\n", str.z);
31368
+ sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt);
3134531369
}
3134631370
if( rc || zErrMsg ){
3134731371
nErr++;
3134831372
rc = 1;
3134931373
sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
3135031374
sqlite3_free(zErrMsg);
31351
- }else if( cli_strcmp(zAns,str.z)!=0 ){
31375
+ }else if( cli_strcmp(zAns,str.zTxt)!=0 ){
3135231376
nErr++;
3135331377
rc = 1;
3135431378
sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
31355
- sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z);
31379
+ sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt);
3135631380
}
3135731381
}
3135831382
else{
3135931383
sqlite3_fprintf(stderr,
3136031384
"Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
@@ -31466,11 +31490,11 @@
3146631490
appendText(&sQuery, "SELECT * FROM ", 0);
3146731491
appendText(&sQuery, zTab, 0);
3146831492
appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
3146931493
}
3147031494
appendText(&sSql, zSep, 0);
31471
- appendText(&sSql, sQuery.z, '\'');
31495
+ appendText(&sSql, sQuery.zTxt, '\'');
3147231496
sQuery.n = 0;
3147331497
appendText(&sSql, ",", 0);
3147431498
appendText(&sSql, zTab, '\'');
3147531499
zSep = "),(";
3147631500
}
@@ -31478,17 +31502,17 @@
3147831502
if( bSeparate ){
3147931503
zSql = sqlite3_mprintf(
3148031504
"%s))"
3148131505
" SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
3148231506
" FROM [sha3sum$query]",
31483
- sSql.z, iSize);
31507
+ sSql.zTxt, iSize);
3148431508
}else{
3148531509
zSql = sqlite3_mprintf(
3148631510
"%s))"
3148731511
" SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
3148831512
" FROM [sha3sum$query]",
31489
- sSql.z, iSize);
31513
+ sSql.zTxt, iSize);
3149031514
}
3149131515
shell_check_oom(zSql);
3149231516
freeText(&sQuery);
3149331517
freeText(&sSql);
3149431518
if( bDebug ){
@@ -31684,11 +31708,11 @@
3168431708
goto meta_command_exit;
3168531709
}
3168631710
for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
3168731711
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3168831712
if( zDbName==0 ) continue;
31689
- if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
31713
+ if( s.zTxt && s.zTxt[0] ) appendText(&s, " UNION ALL ", 0);
3169031714
if( sqlite3_stricmp(zDbName, "main")==0 ){
3169131715
appendText(&s, "SELECT name FROM ", 0);
3169231716
}else{
3169331717
appendText(&s, "SELECT ", 0);
3169431718
appendText(&s, zDbName, '\'');
@@ -31706,11 +31730,11 @@
3170631730
}
3170731731
}
3170831732
rc = sqlite3_finalize(pStmt);
3170931733
if( rc==SQLITE_OK ){
3171031734
appendText(&s, " ORDER BY 1", 0);
31711
- rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
31735
+ rc = sqlite3_prepare_v2(p->db, s.zTxt, -1, &pStmt, 0);
3171231736
}
3171331737
freeText(&s);
3171431738
if( rc ) return shellDatabaseError(p->db);
3171531739
3171631740
/* Run the SQL statement prepared by the above block. Store the results
3171731741
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1512,31 +1512,31 @@
1512 }
1513 }
1514 if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
1515 return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
1516 integer_overflow:
1517 return isNeg ? 0x8000000000000000LL : 0x7fffffffffffffffLL;
1518 }
1519
1520 /*
1521 ** A variable length string to which one can append text.
1522 */
1523 typedef struct ShellText ShellText;
1524 struct ShellText {
1525 char *z;
1526 int n;
1527 int nAlloc;
1528 };
1529
1530 /*
1531 ** Initialize and destroy a ShellText object
1532 */
1533 static void initText(ShellText *p){
1534 memset(p, 0, sizeof(*p));
1535 }
1536 static void freeText(ShellText *p){
1537 free(p->z);
1538 initText(p);
1539 }
1540
1541 /* zIn is either a pointer to a NULL-terminated string in memory obtained
1542 ** from malloc(), or a NULL pointer. The string pointed to by zAppend is
@@ -1557,30 +1557,30 @@
1557 for(i=0; i<nAppend; i++){
1558 if( zAppend[i]==quote ) len++;
1559 }
1560 }
1561
1562 if( p->z==0 || p->n+len>=p->nAlloc ){
1563 p->nAlloc = p->nAlloc*2 + len + 20;
1564 p->z = realloc(p->z, p->nAlloc);
1565 shell_check_oom(p->z);
1566 }
1567
1568 if( quote ){
1569 char *zCsr = p->z+p->n;
1570 *zCsr++ = quote;
1571 for(i=0; i<nAppend; i++){
1572 *zCsr++ = zAppend[i];
1573 if( zAppend[i]==quote ) *zCsr++ = quote;
1574 }
1575 *zCsr++ = quote;
1576 p->n = (int)(zCsr - p->z);
1577 *zCsr = '\0';
1578 }else{
1579 memcpy(p->z+p->n, zAppend, nAppend);
1580 p->n += nAppend;
1581 p->z[p->n] = '\0';
1582 }
1583 }
1584
1585 /*
1586 ** Attempt to determine if identifier zName needs to be quoted, either
@@ -1601,10 +1601,13 @@
1601 }
1602
1603 /*
1604 ** Construct a fake object name and column list to describe the structure
1605 ** of the view, virtual table, or table valued function zSchema.zName.
 
 
 
1606 */
1607 static char *shellFakeSchema(
1608 sqlite3 *db, /* The database connection containing the vtab */
1609 const char *zSchema, /* Schema of the database holding the vtab */
1610 const char *zName /* The name of the virtual table */
@@ -1641,13 +1644,13 @@
1641 }
1642 appendText(&s, ")", 0);
1643 sqlite3_finalize(pStmt);
1644 if( nRow==0 ){
1645 freeText(&s);
1646 s.z = 0;
1647 }
1648 return s.z;
1649 }
1650
1651 /*
1652 ** SQL function: strtod(X)
1653 **
@@ -1746,11 +1749,11 @@
1746 if( z==0 ){
1747 z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
1748 }else{
1749 z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
1750 }
1751 free(zFake);
1752 }
1753 if( z ){
1754 sqlite3_result_text(pCtx, z, -1, sqlite3_free);
1755 return;
1756 }
@@ -6993,11 +6996,11 @@
6993 ** The following regular expression syntax is supported:
6994 **
6995 ** X* zero or more occurrences of X
6996 ** X+ one or more occurrences of X
6997 ** X? zero or one occurrences of X
6998 ** X{p,q} between p and q occurrences of X
6999 ** (X) match X
7000 ** X|Y X or Y
7001 ** ^X X occurring at the beginning of the string
7002 ** X$ X occurring at the end of the string
7003 ** . Match any single character
@@ -7022,15 +7025,22 @@
7022 ** expression and M is the size of the input string. The matcher never
7023 ** exhibits exponential behavior. Note that the X{p,q} operator expands
7024 ** to p copies of X following by q-p copies of X? and that the size of the
7025 ** regular expression in the O(N*M) performance bound is computed after
7026 ** this expansion.
 
 
 
7027 */
7028 #include <string.h>
7029 #include <stdlib.h>
7030 /* #include "sqlite3ext.h" */
7031 SQLITE_EXTENSION_INIT1
 
 
 
 
7032
7033 /*
7034 ** The following #defines change the names of some functions implemented in
7035 ** this file to prevent name collisions with C-library functions of the
7036 ** same name.
@@ -7530,22 +7540,30 @@
7530 case '^': {
7531 re_append(p, RE_OP_ATSTART, 0);
7532 break;
7533 }
7534 case '{': {
7535 int m = 0, n = 0;
7536 int sz, j;
7537 if( iPrev<0 ) return "'{m,n}' without operand";
7538 while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
 
 
 
 
7539 n = m;
7540 if( c==',' ){
7541 p->sIn.i++;
7542 n = 0;
7543 while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
 
 
 
 
7544 }
7545 if( c!='}' ) return "unmatched '{'";
7546 if( n>0 && n<m ) return "n less than m in '{m,n}'";
7547 p->sIn.i++;
7548 sz = p->nState - iPrev;
7549 if( m==0 ){
7550 if( n==0 ) return "both m and n are zero in '{m,n}'";
7551 re_insert(p, iPrev, RE_OP_FORK, sz+1);
@@ -22098,11 +22116,11 @@
22098 */
22099 static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
22100 int i;
22101 unsigned char *aBlob = (unsigned char*)pBlob;
22102
22103 char *zStr = sqlite3_malloc(nBlob*2 + 1);
22104 shell_check_oom(zStr);
22105
22106 for(i=0; i<nBlob; i++){
22107 static const char aHex[] = {
22108 '0', '1', '2', '3', '4', '5', '6', '7',
@@ -23375,11 +23393,16 @@
23375 if( p->zDestTable ){
23376 sqlite3_free(p->zDestTable);
23377 p->zDestTable = 0;
23378 }
23379 if( zName==0 ) return;
23380 p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
 
 
 
 
 
23381 }
23382
23383 /*
23384 ** Maybe construct two lines of text that point out the position of a
23385 ** syntax error. Return a pointer to the text, in memory obtained from
@@ -25182,17 +25205,17 @@
25182 appendText(&sSelect, " FROM ", 0);
25183 appendText(&sSelect, zTable, quoteChar(zTable));
25184
25185 savedDestTable = p->zDestTable;
25186 savedMode = p->mode;
25187 p->zDestTable = sTable.z;
25188 p->mode = p->cMode = MODE_Insert;
25189 rc = shell_exec(p, sSelect.z, 0);
25190 if( (rc&0xff)==SQLITE_CORRUPT ){
25191 sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
25192 toggleSelectOrder(p->db);
25193 shell_exec(p, sSelect.z, 0);
25194 toggleSelectOrder(p->db);
25195 }
25196 p->zDestTable = savedDestTable;
25197 p->mode = savedMode;
25198 freeText(&sTable);
@@ -25802,14 +25825,14 @@
25802 ** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
25803 */
25804 static unsigned char *readHexDb(ShellState *p, int *pnData){
25805 unsigned char *a = 0;
25806 int nLine;
25807 int n = 0;
 
25808 int pgsz = 0;
25809 int iOffset = 0;
25810 int j, k;
25811 int rc;
25812 FILE *in;
25813 const char *zDbFilename = p->pAuxDb->zDbFilename;
25814 unsigned int x[16];
25815 char zLine[1000];
@@ -25829,20 +25852,21 @@
25829 nLine++;
25830 if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
25831 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
25832 if( rc!=2 ) goto readHexDb_error;
25833 if( n<0 ) goto readHexDb_error;
25834 if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
25835 n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
25836 a = sqlite3_malloc( n ? n : 1 );
25837 shell_check_oom(a);
25838 memset(a, 0, n);
25839 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
25840 sqlite3_fputs("invalid pagesize\n", stderr);
25841 goto readHexDb_error;
25842 }
 
 
 
 
25843 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
 
 
25844 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
25845 if( rc==2 ){
25846 iOffset = k;
25847 continue;
25848 }
@@ -25851,18 +25875,18 @@
25851 }
25852 rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
25853 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
25854 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
25855 if( rc==17 ){
25856 k = iOffset+j;
25857 if( k+16<=n && k>=0 ){
25858 int ii;
25859 for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
25860 }
25861 }
25862 }
25863 *pnData = n;
25864 if( in!=p->in ){
25865 fclose(in);
25866 }else{
25867 p->lineno = nLine;
25868 }
@@ -25925,11 +25949,11 @@
25925 p->pLog = pSavedLog;
25926
25927 if( zFake ){
25928 sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
25929 -1, sqlite3_free);
25930 free(zFake);
25931 }
25932 }
25933
25934 /* Flags for open_db().
25935 **
@@ -31009,13 +31033,13 @@
31009 appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
31010 }
31011 appendText(&sSelect, "sql IS NOT NULL"
31012 " ORDER BY snum, rowid", 0);
31013 if( bDebug ){
31014 sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z);
31015 }else{
31016 rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
31017 }
31018 freeText(&sSelect);
31019 }
31020 if( zErrMsg ){
31021 shellEmitError(zErrMsg);
@@ -31335,26 +31359,26 @@
31335 sqlite3_fprintf(p->out, "%s\n", zSql);
31336 }else
31337 if( cli_strcmp(zOp,"run")==0 ){
31338 char *zErrMsg = 0;
31339 str.n = 0;
31340 str.z[0] = 0;
31341 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
31342 nTest++;
31343 if( bVerbose ){
31344 sqlite3_fprintf(p->out, "Result: %s\n", str.z);
31345 }
31346 if( rc || zErrMsg ){
31347 nErr++;
31348 rc = 1;
31349 sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
31350 sqlite3_free(zErrMsg);
31351 }else if( cli_strcmp(zAns,str.z)!=0 ){
31352 nErr++;
31353 rc = 1;
31354 sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
31355 sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z);
31356 }
31357 }
31358 else{
31359 sqlite3_fprintf(stderr,
31360 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
@@ -31466,11 +31490,11 @@
31466 appendText(&sQuery, "SELECT * FROM ", 0);
31467 appendText(&sQuery, zTab, 0);
31468 appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
31469 }
31470 appendText(&sSql, zSep, 0);
31471 appendText(&sSql, sQuery.z, '\'');
31472 sQuery.n = 0;
31473 appendText(&sSql, ",", 0);
31474 appendText(&sSql, zTab, '\'');
31475 zSep = "),(";
31476 }
@@ -31478,17 +31502,17 @@
31478 if( bSeparate ){
31479 zSql = sqlite3_mprintf(
31480 "%s))"
31481 " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
31482 " FROM [sha3sum$query]",
31483 sSql.z, iSize);
31484 }else{
31485 zSql = sqlite3_mprintf(
31486 "%s))"
31487 " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
31488 " FROM [sha3sum$query]",
31489 sSql.z, iSize);
31490 }
31491 shell_check_oom(zSql);
31492 freeText(&sQuery);
31493 freeText(&sSql);
31494 if( bDebug ){
@@ -31684,11 +31708,11 @@
31684 goto meta_command_exit;
31685 }
31686 for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
31687 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
31688 if( zDbName==0 ) continue;
31689 if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
31690 if( sqlite3_stricmp(zDbName, "main")==0 ){
31691 appendText(&s, "SELECT name FROM ", 0);
31692 }else{
31693 appendText(&s, "SELECT ", 0);
31694 appendText(&s, zDbName, '\'');
@@ -31706,11 +31730,11 @@
31706 }
31707 }
31708 rc = sqlite3_finalize(pStmt);
31709 if( rc==SQLITE_OK ){
31710 appendText(&s, " ORDER BY 1", 0);
31711 rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
31712 }
31713 freeText(&s);
31714 if( rc ) return shellDatabaseError(p->db);
31715
31716 /* Run the SQL statement prepared by the above block. Store the results
31717
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1512,31 +1512,31 @@
1512 }
1513 }
1514 if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
1515 return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
1516 integer_overflow:
1517 return isNeg ? (i64)0x8000000000000000LL : 0x7fffffffffffffffLL;
1518 }
1519
1520 /*
1521 ** A variable length string to which one can append text.
1522 */
1523 typedef struct ShellText ShellText;
1524 struct ShellText {
1525 char *zTxt; /* The text */
1526 i64 n; /* Number of bytes of zTxt[] actually used */
1527 i64 nAlloc; /* Number of bytes allocated for zTxt[] */
1528 };
1529
1530 /*
1531 ** Initialize and destroy a ShellText object
1532 */
1533 static void initText(ShellText *p){
1534 memset(p, 0, sizeof(*p));
1535 }
1536 static void freeText(ShellText *p){
1537 sqlite3_free(p->zTxt);
1538 initText(p);
1539 }
1540
1541 /* zIn is either a pointer to a NULL-terminated string in memory obtained
1542 ** from malloc(), or a NULL pointer. The string pointed to by zAppend is
@@ -1557,30 +1557,30 @@
1557 for(i=0; i<nAppend; i++){
1558 if( zAppend[i]==quote ) len++;
1559 }
1560 }
1561
1562 if( p->zTxt==0 || p->n+len>=p->nAlloc ){
1563 p->nAlloc = p->nAlloc*2 + len + 20;
1564 p->zTxt = sqlite3_realloc64(p->zTxt, p->nAlloc);
1565 shell_check_oom(p->zTxt);
1566 }
1567
1568 if( quote ){
1569 char *zCsr = p->zTxt+p->n;
1570 *zCsr++ = quote;
1571 for(i=0; i<nAppend; i++){
1572 *zCsr++ = zAppend[i];
1573 if( zAppend[i]==quote ) *zCsr++ = quote;
1574 }
1575 *zCsr++ = quote;
1576 p->n = (i64)(zCsr - p->zTxt);
1577 *zCsr = '\0';
1578 }else{
1579 memcpy(p->zTxt+p->n, zAppend, nAppend);
1580 p->n += nAppend;
1581 p->zTxt[p->n] = '\0';
1582 }
1583 }
1584
1585 /*
1586 ** Attempt to determine if identifier zName needs to be quoted, either
@@ -1601,10 +1601,13 @@
1601 }
1602
1603 /*
1604 ** Construct a fake object name and column list to describe the structure
1605 ** of the view, virtual table, or table valued function zSchema.zName.
1606 **
1607 ** The returned string comes from sqlite3_mprintf() and should be freed
1608 ** by the caller using sqlite3_free().
1609 */
1610 static char *shellFakeSchema(
1611 sqlite3 *db, /* The database connection containing the vtab */
1612 const char *zSchema, /* Schema of the database holding the vtab */
1613 const char *zName /* The name of the virtual table */
@@ -1641,13 +1644,13 @@
1644 }
1645 appendText(&s, ")", 0);
1646 sqlite3_finalize(pStmt);
1647 if( nRow==0 ){
1648 freeText(&s);
1649 s.zTxt = 0;
1650 }
1651 return s.zTxt;
1652 }
1653
1654 /*
1655 ** SQL function: strtod(X)
1656 **
@@ -1746,11 +1749,11 @@
1749 if( z==0 ){
1750 z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
1751 }else{
1752 z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
1753 }
1754 sqlite3_free(zFake);
1755 }
1756 if( z ){
1757 sqlite3_result_text(pCtx, z, -1, sqlite3_free);
1758 return;
1759 }
@@ -6993,11 +6996,11 @@
6996 ** The following regular expression syntax is supported:
6997 **
6998 ** X* zero or more occurrences of X
6999 ** X+ one or more occurrences of X
7000 ** X? zero or one occurrences of X
7001 ** X{p,q} between p and q occurrences of X, 0 <= p,q <= 999
7002 ** (X) match X
7003 ** X|Y X or Y
7004 ** ^X X occurring at the beginning of the string
7005 ** X$ X occurring at the end of the string
7006 ** . Match any single character
@@ -7022,15 +7025,22 @@
7025 ** expression and M is the size of the input string. The matcher never
7026 ** exhibits exponential behavior. Note that the X{p,q} operator expands
7027 ** to p copies of X following by q-p copies of X? and that the size of the
7028 ** regular expression in the O(N*M) performance bound is computed after
7029 ** this expansion.
7030 **
7031 ** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
7032 ** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999.
7033 */
7034 #include <string.h>
7035 #include <stdlib.h>
7036 /* #include "sqlite3ext.h" */
7037 SQLITE_EXTENSION_INIT1
7038
7039 #ifndef SQLITE_MAX_REGEXP_REPEAT
7040 # define SQLITE_MAX_REGEXP_REPEAT 999
7041 #endif
7042
7043 /*
7044 ** The following #defines change the names of some functions implemented in
7045 ** this file to prevent name collisions with C-library functions of the
7046 ** same name.
@@ -7530,22 +7540,30 @@
7540 case '^': {
7541 re_append(p, RE_OP_ATSTART, 0);
7542 break;
7543 }
7544 case '{': {
7545 unsigned int m = 0, n = 0;
7546 unsigned int sz, j;
7547 if( iPrev<0 ) return "'{m,n}' without operand";
7548 while( (c=rePeek(p))>='0' && c<='9' ){
7549 m = m*10 + c - '0';
7550 if( m>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
7551 p->sIn.i++;
7552 }
7553 n = m;
7554 if( c==',' ){
7555 p->sIn.i++;
7556 n = 0;
7557 while( (c=rePeek(p))>='0' && c<='9' ){
7558 n = n*10 + c-'0';
7559 if( n>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
7560 p->sIn.i++;
7561 }
7562 }
7563 if( c!='}' ) return "unmatched '{'";
7564 if( n<m ) return "n less than m in '{m,n}'";
7565 p->sIn.i++;
7566 sz = p->nState - iPrev;
7567 if( m==0 ){
7568 if( n==0 ) return "both m and n are zero in '{m,n}'";
7569 re_insert(p, iPrev, RE_OP_FORK, sz+1);
@@ -22098,11 +22116,11 @@
22116 */
22117 static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
22118 int i;
22119 unsigned char *aBlob = (unsigned char*)pBlob;
22120
22121 char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1);
22122 shell_check_oom(zStr);
22123
22124 for(i=0; i<nBlob; i++){
22125 static const char aHex[] = {
22126 '0', '1', '2', '3', '4', '5', '6', '7',
@@ -23375,11 +23393,16 @@
23393 if( p->zDestTable ){
23394 sqlite3_free(p->zDestTable);
23395 p->zDestTable = 0;
23396 }
23397 if( zName==0 ) return;
23398 if( quoteChar(zName) ){
23399 p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
23400 }else{
23401 p->zDestTable = sqlite3_mprintf("%s", zName);
23402 }
23403 shell_check_oom(p->zDestTable);
23404 }
23405
23406 /*
23407 ** Maybe construct two lines of text that point out the position of a
23408 ** syntax error. Return a pointer to the text, in memory obtained from
@@ -25182,17 +25205,17 @@
25205 appendText(&sSelect, " FROM ", 0);
25206 appendText(&sSelect, zTable, quoteChar(zTable));
25207
25208 savedDestTable = p->zDestTable;
25209 savedMode = p->mode;
25210 p->zDestTable = sTable.zTxt;
25211 p->mode = p->cMode = MODE_Insert;
25212 rc = shell_exec(p, sSelect.zTxt, 0);
25213 if( (rc&0xff)==SQLITE_CORRUPT ){
25214 sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
25215 toggleSelectOrder(p->db);
25216 shell_exec(p, sSelect.zTxt, 0);
25217 toggleSelectOrder(p->db);
25218 }
25219 p->zDestTable = savedDestTable;
25220 p->mode = savedMode;
25221 freeText(&sTable);
@@ -25802,14 +25825,14 @@
25825 ** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
25826 */
25827 static unsigned char *readHexDb(ShellState *p, int *pnData){
25828 unsigned char *a = 0;
25829 int nLine;
25830 int n = 0; /* Size of db per first line of hex dump */
25831 i64 sz = 0; /* n rounded up to nearest page boundary */
25832 int pgsz = 0;
25833 i64 iOffset = 0;
 
25834 int rc;
25835 FILE *in;
25836 const char *zDbFilename = p->pAuxDb->zDbFilename;
25837 unsigned int x[16];
25838 char zLine[1000];
@@ -25829,20 +25852,21 @@
25852 nLine++;
25853 if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
25854 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
25855 if( rc!=2 ) goto readHexDb_error;
25856 if( n<0 ) goto readHexDb_error;
 
 
 
 
 
25857 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
25858 sqlite3_fputs("invalid pagesize\n", stderr);
25859 goto readHexDb_error;
25860 }
25861 sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */
25862 a = sqlite3_malloc( sz ? sz : 1 );
25863 shell_check_oom(a);
25864 memset(a, 0, sz);
25865 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
25866 int j = 0; /* Page number from "| page" line */
25867 int k = 0; /* Offset from "| page" line */
25868 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
25869 if( rc==2 ){
25870 iOffset = k;
25871 continue;
25872 }
@@ -25851,18 +25875,18 @@
25875 }
25876 rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
25877 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
25878 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
25879 if( rc==17 ){
25880 i64 iOff = iOffset+j;
25881 if( iOff+16<=sz && iOff>=0 ){
25882 int ii;
25883 for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff;
25884 }
25885 }
25886 }
25887 *pnData = sz;
25888 if( in!=p->in ){
25889 fclose(in);
25890 }else{
25891 p->lineno = nLine;
25892 }
@@ -25925,11 +25949,11 @@
25949 p->pLog = pSavedLog;
25950
25951 if( zFake ){
25952 sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
25953 -1, sqlite3_free);
25954 sqlite3_free(zFake);
25955 }
25956 }
25957
25958 /* Flags for open_db().
25959 **
@@ -31009,13 +31033,13 @@
31033 appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
31034 }
31035 appendText(&sSelect, "sql IS NOT NULL"
31036 " ORDER BY snum, rowid", 0);
31037 if( bDebug ){
31038 sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt);
31039 }else{
31040 rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg);
31041 }
31042 freeText(&sSelect);
31043 }
31044 if( zErrMsg ){
31045 shellEmitError(zErrMsg);
@@ -31335,26 +31359,26 @@
31359 sqlite3_fprintf(p->out, "%s\n", zSql);
31360 }else
31361 if( cli_strcmp(zOp,"run")==0 ){
31362 char *zErrMsg = 0;
31363 str.n = 0;
31364 str.zTxt[0] = 0;
31365 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
31366 nTest++;
31367 if( bVerbose ){
31368 sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt);
31369 }
31370 if( rc || zErrMsg ){
31371 nErr++;
31372 rc = 1;
31373 sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
31374 sqlite3_free(zErrMsg);
31375 }else if( cli_strcmp(zAns,str.zTxt)!=0 ){
31376 nErr++;
31377 rc = 1;
31378 sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
31379 sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt);
31380 }
31381 }
31382 else{
31383 sqlite3_fprintf(stderr,
31384 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
@@ -31466,11 +31490,11 @@
31490 appendText(&sQuery, "SELECT * FROM ", 0);
31491 appendText(&sQuery, zTab, 0);
31492 appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
31493 }
31494 appendText(&sSql, zSep, 0);
31495 appendText(&sSql, sQuery.zTxt, '\'');
31496 sQuery.n = 0;
31497 appendText(&sSql, ",", 0);
31498 appendText(&sSql, zTab, '\'');
31499 zSep = "),(";
31500 }
@@ -31478,17 +31502,17 @@
31502 if( bSeparate ){
31503 zSql = sqlite3_mprintf(
31504 "%s))"
31505 " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
31506 " FROM [sha3sum$query]",
31507 sSql.zTxt, iSize);
31508 }else{
31509 zSql = sqlite3_mprintf(
31510 "%s))"
31511 " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
31512 " FROM [sha3sum$query]",
31513 sSql.zTxt, iSize);
31514 }
31515 shell_check_oom(zSql);
31516 freeText(&sQuery);
31517 freeText(&sSql);
31518 if( bDebug ){
@@ -31684,11 +31708,11 @@
31708 goto meta_command_exit;
31709 }
31710 for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
31711 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
31712 if( zDbName==0 ) continue;
31713 if( s.zTxt && s.zTxt[0] ) appendText(&s, " UNION ALL ", 0);
31714 if( sqlite3_stricmp(zDbName, "main")==0 ){
31715 appendText(&s, "SELECT name FROM ", 0);
31716 }else{
31717 appendText(&s, "SELECT ", 0);
31718 appendText(&s, zDbName, '\'');
@@ -31706,11 +31730,11 @@
31730 }
31731 }
31732 rc = sqlite3_finalize(pStmt);
31733 if( rc==SQLITE_OK ){
31734 appendText(&s, " ORDER BY 1", 0);
31735 rc = sqlite3_prepare_v2(p->db, s.zTxt, -1, &pStmt, 0);
31736 }
31737 freeText(&s);
31738 if( rc ) return shellDatabaseError(p->db);
31739
31740 /* Run the SQL statement prepared by the above block. Store the results
31741
+55 -71
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 821cc0e421bc14a68ebaee507e38a900e0c8 with changes in files:
21
+** 911c745f88c0ee8569e67bbcbbab034264f8 with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468
** [sqlite_version()] and [sqlite_source_id()].
469469
*/
470470
#define SQLITE_VERSION "3.51.0"
471471
#define SQLITE_VERSION_NUMBER 3051000
472
-#define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
472
+#define SQLITE_SOURCE_ID "2025-09-26 13:14:20 911c745f88c0ee8569e67bbcbbab034264f8c981b505aadac3ce7289486a1a68"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
475
+#define SQLITE_SCM_DATETIME "2025-09-26T13:14:20.156Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -21707,11 +21707,11 @@
2170721707
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
2170821708
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
2170921709
SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void);
2171021710
SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
2171121711
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
21712
-SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3*);
21712
+SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3*,const char*);
2171321713
#endif
2171421714
SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
2171521715
SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
2171621716
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
2171721717
SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p);
@@ -124262,10 +124262,15 @@
124262124262
if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
124263124263
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
124264124264
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
124265124265
pMod = sqlite3PragmaVtabRegister(db, zName);
124266124266
}
124267
+#ifndef SQLITE_OMIT_JSON
124268
+ if( pMod==0 && sqlite3_strnicmp(zName, "json", 4)==0 ){
124269
+ pMod = sqlite3JsonVtabRegister(db, zName);
124270
+ }
124271
+#endif
124267124272
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
124268124273
testcase( pMod->pEpoTab==0 );
124269124274
return pMod->pEpoTab;
124270124275
}
124271124276
}
@@ -183862,13 +183867,10 @@
183862183867
#endif
183863183868
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
183864183869
sqlite3DbstatRegister,
183865183870
#endif
183866183871
sqlite3TestExtInit,
183867
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
183868
- sqlite3JsonTableFunctions,
183869
-#endif
183870183872
#ifdef SQLITE_ENABLE_STMTVTAB
183871183873
sqlite3StmtVtabInit,
183872183874
#endif
183873183875
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
183874183876
sqlite3VdbeBytecodeVtabInit,
@@ -211323,11 +211325,11 @@
211323211325
switch( (u8)zIn[1] ){
211324211326
case '\'':
211325211327
jsonAppendChar(pOut, '\'');
211326211328
break;
211327211329
case 'v':
211328
- jsonAppendRawNZ(pOut, "\\u0009", 6);
211330
+ jsonAppendRawNZ(pOut, "\\u000b", 6);
211329211331
break;
211330211332
case 'x':
211331211333
if( sz2<4 ){
211332211334
pOut->eErr |= JSTRING_MALFORMED;
211333211335
sz2 = 2;
@@ -212173,23 +212175,31 @@
212173212175
/*
212174212176
** Return the value of the BLOB node at index i.
212175212177
**
212176212178
** If the value is a primitive, return it as an SQL value.
212177212179
** If the value is an array or object, return it as either
212178
-** JSON text or the BLOB encoding, depending on the JSON_B flag
212179
-** on the userdata.
212180
+** JSON text or the BLOB encoding, depending on the eMode flag
212181
+** as follows:
212182
+**
212183
+** eMode==0 JSONB if the JSON_B flag is set in userdata or
212184
+** text if the JSON_B flag is omitted from userdata.
212185
+**
212186
+** eMode==1 Text
212187
+**
212188
+** eMode==2 JSONB
212180212189
*/
212181212190
static void jsonReturnFromBlob(
212182212191
JsonParse *pParse, /* Complete JSON parse tree */
212183212192
u32 i, /* Index of the node */
212184212193
sqlite3_context *pCtx, /* Return value for this function */
212185
- int textOnly /* return text JSON. Disregard user-data */
212194
+ int eMode /* Format of return: text of JSONB */
212186212195
){
212187212196
u32 n, sz;
212188212197
int rc;
212189212198
sqlite3 *db = sqlite3_context_db_handle(pCtx);
212190212199
212200
+ assert( eMode>=0 && eMode<=2 );
212191212201
n = jsonbPayloadSize(pParse, i, &sz);
212192212202
if( n==0 ){
212193212203
sqlite3_result_error(pCtx, "malformed JSON", -1);
212194212204
return;
212195212205
}
@@ -212304,12 +212314,18 @@
212304212314
sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
212305212315
break;
212306212316
}
212307212317
case JSONB_ARRAY:
212308212318
case JSONB_OBJECT: {
212309
- int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx));
212310
- if( flags & JSON_BLOB ){
212319
+ if( eMode==0 ){
212320
+ if( (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)) & JSON_BLOB)!=0 ){
212321
+ eMode = 2;
212322
+ }else{
212323
+ eMode = 1;
212324
+ }
212325
+ }
212326
+ if( eMode==2 ){
212311212327
sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
212312212328
}else{
212313212329
jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
212314212330
}
212315212331
break;
@@ -213952,10 +213968,11 @@
213952213968
u32 i; /* Index in sParse.aBlob[] of current row */
213953213969
u32 iEnd; /* EOF when i equals or exceeds this value */
213954213970
u32 nRoot; /* Size of the root path in bytes */
213955213971
u8 eType; /* Type of the container for element i */
213956213972
u8 bRecursive; /* True for json_tree(). False for json_each() */
213973
+ u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */
213957213974
u32 nParent; /* Current nesting depth */
213958213975
u32 nParentAlloc; /* Space allocated for aParent[] */
213959213976
JsonParent *aParent; /* Parent elements of i */
213960213977
sqlite3 *db; /* Database connection */
213961213978
JsonString path; /* Current path */
@@ -213963,10 +213980,12 @@
213963213980
};
213964213981
typedef struct JsonEachConnection JsonEachConnection;
213965213982
struct JsonEachConnection {
213966213983
sqlite3_vtab base; /* Base class - must be first */
213967213984
sqlite3 *db; /* Database connection */
213985
+ u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */
213986
+ u8 bRecursive; /* True for json_tree(). False for json_each() */
213968213987
};
213969213988
213970213989
213971213990
/* Constructor for the json_each virtual table */
213972213991
static int jsonEachConnect(
@@ -214005,10 +214024,12 @@
214005214024
pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
214006214025
*ppVtab = (sqlite3_vtab*)pNew;
214007214026
if( pNew==0 ) return SQLITE_NOMEM;
214008214027
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
214009214028
pNew->db = db;
214029
+ pNew->eMode = argv[0][4]=='b' ? 2 : 1;
214030
+ pNew->bRecursive = argv[0][4+pNew->eMode]=='t';
214010214031
}
214011214032
return rc;
214012214033
}
214013214034
214014214035
/* destructor for json_each virtual table */
@@ -214016,34 +214037,26 @@
214016214037
JsonEachConnection *p = (JsonEachConnection*)pVtab;
214017214038
sqlite3DbFree(p->db, pVtab);
214018214039
return SQLITE_OK;
214019214040
}
214020214041
214021
-/* constructor for a JsonEachCursor object for json_each(). */
214022
-static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
214042
+/* constructor for a JsonEachCursor object for json_each()/json_tree(). */
214043
+static int jsonEachOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
214023214044
JsonEachConnection *pVtab = (JsonEachConnection*)p;
214024214045
JsonEachCursor *pCur;
214025214046
214026214047
UNUSED_PARAMETER(p);
214027214048
pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
214028214049
if( pCur==0 ) return SQLITE_NOMEM;
214029214050
pCur->db = pVtab->db;
214051
+ pCur->eMode = pVtab->eMode;
214052
+ pCur->bRecursive = pVtab->bRecursive;
214030214053
jsonStringZero(&pCur->path);
214031214054
*ppCursor = &pCur->base;
214032214055
return SQLITE_OK;
214033214056
}
214034214057
214035
-/* constructor for a JsonEachCursor object for json_tree(). */
214036
-static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
214037
- int rc = jsonEachOpenEach(p, ppCursor);
214038
- if( rc==SQLITE_OK ){
214039
- JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
214040
- pCur->bRecursive = 1;
214041
- }
214042
- return rc;
214043
-}
214044
-
214045214058
/* Reset a JsonEachCursor back to its original state. Free any memory
214046214059
** held. */
214047214060
static void jsonEachCursorReset(JsonEachCursor *p){
214048214061
jsonParseReset(&p->sParse);
214049214062
jsonStringReset(&p->path);
@@ -214244,11 +214257,11 @@
214244214257
}
214245214258
break;
214246214259
}
214247214260
case JEACH_VALUE: {
214248214261
u32 i = jsonSkipLabel(p);
214249
- jsonReturnFromBlob(&p->sParse, i, ctx, 1);
214262
+ jsonReturnFromBlob(&p->sParse, i, ctx, p->eMode);
214250214263
if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
214251214264
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
214252214265
}
214253214266
break;
214254214267
}
@@ -214488,40 +214501,11 @@
214488214501
0, /* xCreate */
214489214502
jsonEachConnect, /* xConnect */
214490214503
jsonEachBestIndex, /* xBestIndex */
214491214504
jsonEachDisconnect, /* xDisconnect */
214492214505
0, /* xDestroy */
214493
- jsonEachOpenEach, /* xOpen - open a cursor */
214494
- jsonEachClose, /* xClose - close a cursor */
214495
- jsonEachFilter, /* xFilter - configure scan constraints */
214496
- jsonEachNext, /* xNext - advance a cursor */
214497
- jsonEachEof, /* xEof - check for end of scan */
214498
- jsonEachColumn, /* xColumn - read data */
214499
- jsonEachRowid, /* xRowid - read data */
214500
- 0, /* xUpdate */
214501
- 0, /* xBegin */
214502
- 0, /* xSync */
214503
- 0, /* xCommit */
214504
- 0, /* xRollback */
214505
- 0, /* xFindMethod */
214506
- 0, /* xRename */
214507
- 0, /* xSavepoint */
214508
- 0, /* xRelease */
214509
- 0, /* xRollbackTo */
214510
- 0, /* xShadowName */
214511
- 0 /* xIntegrity */
214512
-};
214513
-
214514
-/* The methods of the json_tree virtual table. */
214515
-static sqlite3_module jsonTreeModule = {
214516
- 0, /* iVersion */
214517
- 0, /* xCreate */
214518
- jsonEachConnect, /* xConnect */
214519
- jsonEachBestIndex, /* xBestIndex */
214520
- jsonEachDisconnect, /* xDisconnect */
214521
- 0, /* xDestroy */
214522
- jsonEachOpenTree, /* xOpen - open a cursor */
214506
+ jsonEachOpen, /* xOpen - open a cursor */
214523214507
jsonEachClose, /* xClose - close a cursor */
214524214508
jsonEachFilter, /* xFilter - configure scan constraints */
214525214509
jsonEachNext, /* xNext - advance a cursor */
214526214510
jsonEachEof, /* xEof - check for end of scan */
214527214511
jsonEachColumn, /* xColumn - read data */
@@ -214606,26 +214590,25 @@
214606214590
#endif
214607214591
}
214608214592
214609214593
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
214610214594
/*
214611
-** Register the JSON table-valued functions
214595
+** Register the JSON table-valued function named zName and return a
214596
+** pointer to its Module object. Return NULL if something goes wrong.
214612214597
*/
214613
-SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){
214614
- int rc = SQLITE_OK;
214615
- static const struct {
214616
- const char *zName;
214617
- sqlite3_module *pModule;
214618
- } aMod[] = {
214619
- { "json_each", &jsonEachModule },
214620
- { "json_tree", &jsonTreeModule },
214621
- };
214598
+SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3 *db, const char *zName){
214622214599
unsigned int i;
214623
- for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
214624
- rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
214600
+ static const char *azModule[] = {
214601
+ "json_each", "json_tree", "jsonb_each", "jsonb_tree"
214602
+ };
214603
+ assert( sqlite3HashFind(&db->aModule, zName)==0 );
214604
+ for(i=0; i<sizeof(azModule)/sizeof(azModule[0]); i++){
214605
+ if( sqlite3StrICmp(azModule[i],zName)==0 ){
214606
+ return sqlite3VtabCreateModule(db, azModule[i], &jsonEachModule, 0, 0);
214607
+ }
214625214608
}
214626
- return rc;
214609
+ return 0;
214627214610
}
214628214611
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
214629214612
214630214613
/************** End of json.c ************************************************/
214631214614
/************** Begin file rtree.c *******************************************/
@@ -234701,10 +234684,11 @@
234701234684
}
234702234685
}
234703234686
234704234687
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
234705234688
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
234689
+ assert( ppRebase!=0 && pnRebase!=0 );
234706234690
*ppRebase = (void*)sApply.rebase.aBuf;
234707234691
*pnRebase = sApply.rebase.nBuf;
234708234692
sApply.rebase.aBuf = 0;
234709234693
}
234710234694
sessionUpdateFree(&sApply);
@@ -252414,11 +252398,11 @@
252414252398
u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
252415252399
} uFts;
252416252400
fts5StructureInvalidate(p);
252417252401
fts5IndexDiscardData(p);
252418252402
pTmp = &uFts.sFts;
252419
- memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
252403
+ memset(uFts.tmpSpace, 0, sizeof(uFts.tmpSpace));
252420252404
if( p->pConfig->bContentlessDelete ){
252421252405
pTmp->nOriginCntr = 1;
252422252406
}
252423252407
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
252424252408
fts5StructureWrite(p, pTmp);
@@ -258722,11 +258706,11 @@
258722258706
int nArg, /* Number of args */
258723258707
sqlite3_value **apUnused /* Function arguments */
258724258708
){
258725258709
assert( nArg==0 );
258726258710
UNUSED_PARAM2(nArg, apUnused);
258727
- sqlite3_result_text(pCtx, "fts5: 2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232", -1, SQLITE_TRANSIENT);
258711
+ sqlite3_result_text(pCtx, "fts5: 2025-09-26 11:47:13 d022ee167b90a7c32049a93d476e869270018017f60551185024409730d77640", -1, SQLITE_TRANSIENT);
258728258712
}
258729258713
258730258714
/*
258731258715
** Implementation of fts5_locale(LOCALE, TEXT) function.
258732258716
**
258733258717
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 821cc0e421bc14a68ebaee507e38a900e0c8 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.51.0"
471 #define SQLITE_VERSION_NUMBER 3051000
472 #define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -21707,11 +21707,11 @@
21707 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
21708 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
21709 SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void);
21710 SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
21711 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
21712 SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3*);
21713 #endif
21714 SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
21715 SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
21716 SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
21717 SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p);
@@ -124262,10 +124262,15 @@
124262 if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
124263 Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
124264 if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
124265 pMod = sqlite3PragmaVtabRegister(db, zName);
124266 }
 
 
 
 
 
124267 if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
124268 testcase( pMod->pEpoTab==0 );
124269 return pMod->pEpoTab;
124270 }
124271 }
@@ -183862,13 +183867,10 @@
183862 #endif
183863 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
183864 sqlite3DbstatRegister,
183865 #endif
183866 sqlite3TestExtInit,
183867 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
183868 sqlite3JsonTableFunctions,
183869 #endif
183870 #ifdef SQLITE_ENABLE_STMTVTAB
183871 sqlite3StmtVtabInit,
183872 #endif
183873 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
183874 sqlite3VdbeBytecodeVtabInit,
@@ -211323,11 +211325,11 @@
211323 switch( (u8)zIn[1] ){
211324 case '\'':
211325 jsonAppendChar(pOut, '\'');
211326 break;
211327 case 'v':
211328 jsonAppendRawNZ(pOut, "\\u0009", 6);
211329 break;
211330 case 'x':
211331 if( sz2<4 ){
211332 pOut->eErr |= JSTRING_MALFORMED;
211333 sz2 = 2;
@@ -212173,23 +212175,31 @@
212173 /*
212174 ** Return the value of the BLOB node at index i.
212175 **
212176 ** If the value is a primitive, return it as an SQL value.
212177 ** If the value is an array or object, return it as either
212178 ** JSON text or the BLOB encoding, depending on the JSON_B flag
212179 ** on the userdata.
 
 
 
 
 
 
 
212180 */
212181 static void jsonReturnFromBlob(
212182 JsonParse *pParse, /* Complete JSON parse tree */
212183 u32 i, /* Index of the node */
212184 sqlite3_context *pCtx, /* Return value for this function */
212185 int textOnly /* return text JSON. Disregard user-data */
212186 ){
212187 u32 n, sz;
212188 int rc;
212189 sqlite3 *db = sqlite3_context_db_handle(pCtx);
212190
 
212191 n = jsonbPayloadSize(pParse, i, &sz);
212192 if( n==0 ){
212193 sqlite3_result_error(pCtx, "malformed JSON", -1);
212194 return;
212195 }
@@ -212304,12 +212314,18 @@
212304 sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
212305 break;
212306 }
212307 case JSONB_ARRAY:
212308 case JSONB_OBJECT: {
212309 int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx));
212310 if( flags & JSON_BLOB ){
 
 
 
 
 
 
212311 sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
212312 }else{
212313 jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
212314 }
212315 break;
@@ -213952,10 +213968,11 @@
213952 u32 i; /* Index in sParse.aBlob[] of current row */
213953 u32 iEnd; /* EOF when i equals or exceeds this value */
213954 u32 nRoot; /* Size of the root path in bytes */
213955 u8 eType; /* Type of the container for element i */
213956 u8 bRecursive; /* True for json_tree(). False for json_each() */
 
213957 u32 nParent; /* Current nesting depth */
213958 u32 nParentAlloc; /* Space allocated for aParent[] */
213959 JsonParent *aParent; /* Parent elements of i */
213960 sqlite3 *db; /* Database connection */
213961 JsonString path; /* Current path */
@@ -213963,10 +213980,12 @@
213963 };
213964 typedef struct JsonEachConnection JsonEachConnection;
213965 struct JsonEachConnection {
213966 sqlite3_vtab base; /* Base class - must be first */
213967 sqlite3 *db; /* Database connection */
 
 
213968 };
213969
213970
213971 /* Constructor for the json_each virtual table */
213972 static int jsonEachConnect(
@@ -214005,10 +214024,12 @@
214005 pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
214006 *ppVtab = (sqlite3_vtab*)pNew;
214007 if( pNew==0 ) return SQLITE_NOMEM;
214008 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
214009 pNew->db = db;
 
 
214010 }
214011 return rc;
214012 }
214013
214014 /* destructor for json_each virtual table */
@@ -214016,34 +214037,26 @@
214016 JsonEachConnection *p = (JsonEachConnection*)pVtab;
214017 sqlite3DbFree(p->db, pVtab);
214018 return SQLITE_OK;
214019 }
214020
214021 /* constructor for a JsonEachCursor object for json_each(). */
214022 static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
214023 JsonEachConnection *pVtab = (JsonEachConnection*)p;
214024 JsonEachCursor *pCur;
214025
214026 UNUSED_PARAMETER(p);
214027 pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
214028 if( pCur==0 ) return SQLITE_NOMEM;
214029 pCur->db = pVtab->db;
 
 
214030 jsonStringZero(&pCur->path);
214031 *ppCursor = &pCur->base;
214032 return SQLITE_OK;
214033 }
214034
214035 /* constructor for a JsonEachCursor object for json_tree(). */
214036 static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
214037 int rc = jsonEachOpenEach(p, ppCursor);
214038 if( rc==SQLITE_OK ){
214039 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
214040 pCur->bRecursive = 1;
214041 }
214042 return rc;
214043 }
214044
214045 /* Reset a JsonEachCursor back to its original state. Free any memory
214046 ** held. */
214047 static void jsonEachCursorReset(JsonEachCursor *p){
214048 jsonParseReset(&p->sParse);
214049 jsonStringReset(&p->path);
@@ -214244,11 +214257,11 @@
214244 }
214245 break;
214246 }
214247 case JEACH_VALUE: {
214248 u32 i = jsonSkipLabel(p);
214249 jsonReturnFromBlob(&p->sParse, i, ctx, 1);
214250 if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
214251 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
214252 }
214253 break;
214254 }
@@ -214488,40 +214501,11 @@
214488 0, /* xCreate */
214489 jsonEachConnect, /* xConnect */
214490 jsonEachBestIndex, /* xBestIndex */
214491 jsonEachDisconnect, /* xDisconnect */
214492 0, /* xDestroy */
214493 jsonEachOpenEach, /* xOpen - open a cursor */
214494 jsonEachClose, /* xClose - close a cursor */
214495 jsonEachFilter, /* xFilter - configure scan constraints */
214496 jsonEachNext, /* xNext - advance a cursor */
214497 jsonEachEof, /* xEof - check for end of scan */
214498 jsonEachColumn, /* xColumn - read data */
214499 jsonEachRowid, /* xRowid - read data */
214500 0, /* xUpdate */
214501 0, /* xBegin */
214502 0, /* xSync */
214503 0, /* xCommit */
214504 0, /* xRollback */
214505 0, /* xFindMethod */
214506 0, /* xRename */
214507 0, /* xSavepoint */
214508 0, /* xRelease */
214509 0, /* xRollbackTo */
214510 0, /* xShadowName */
214511 0 /* xIntegrity */
214512 };
214513
214514 /* The methods of the json_tree virtual table. */
214515 static sqlite3_module jsonTreeModule = {
214516 0, /* iVersion */
214517 0, /* xCreate */
214518 jsonEachConnect, /* xConnect */
214519 jsonEachBestIndex, /* xBestIndex */
214520 jsonEachDisconnect, /* xDisconnect */
214521 0, /* xDestroy */
214522 jsonEachOpenTree, /* xOpen - open a cursor */
214523 jsonEachClose, /* xClose - close a cursor */
214524 jsonEachFilter, /* xFilter - configure scan constraints */
214525 jsonEachNext, /* xNext - advance a cursor */
214526 jsonEachEof, /* xEof - check for end of scan */
214527 jsonEachColumn, /* xColumn - read data */
@@ -214606,26 +214590,25 @@
214606 #endif
214607 }
214608
214609 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
214610 /*
214611 ** Register the JSON table-valued functions
 
214612 */
214613 SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){
214614 int rc = SQLITE_OK;
214615 static const struct {
214616 const char *zName;
214617 sqlite3_module *pModule;
214618 } aMod[] = {
214619 { "json_each", &jsonEachModule },
214620 { "json_tree", &jsonTreeModule },
214621 };
214622 unsigned int i;
214623 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
214624 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
 
 
 
 
 
 
214625 }
214626 return rc;
214627 }
214628 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
214629
214630 /************** End of json.c ************************************************/
214631 /************** Begin file rtree.c *******************************************/
@@ -234701,10 +234684,11 @@
234701 }
234702 }
234703
234704 assert( sApply.bRebase || sApply.rebase.nBuf==0 );
234705 if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
 
234706 *ppRebase = (void*)sApply.rebase.aBuf;
234707 *pnRebase = sApply.rebase.nBuf;
234708 sApply.rebase.aBuf = 0;
234709 }
234710 sessionUpdateFree(&sApply);
@@ -252414,11 +252398,11 @@
252414 u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
252415 } uFts;
252416 fts5StructureInvalidate(p);
252417 fts5IndexDiscardData(p);
252418 pTmp = &uFts.sFts;
252419 memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
252420 if( p->pConfig->bContentlessDelete ){
252421 pTmp->nOriginCntr = 1;
252422 }
252423 fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
252424 fts5StructureWrite(p, pTmp);
@@ -258722,11 +258706,11 @@
258722 int nArg, /* Number of args */
258723 sqlite3_value **apUnused /* Function arguments */
258724 ){
258725 assert( nArg==0 );
258726 UNUSED_PARAM2(nArg, apUnused);
258727 sqlite3_result_text(pCtx, "fts5: 2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232", -1, SQLITE_TRANSIENT);
258728 }
258729
258730 /*
258731 ** Implementation of fts5_locale(LOCALE, TEXT) function.
258732 **
258733
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 911c745f88c0ee8569e67bbcbbab034264f8 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.51.0"
471 #define SQLITE_VERSION_NUMBER 3051000
472 #define SQLITE_SOURCE_ID "2025-09-26 13:14:20 911c745f88c0ee8569e67bbcbbab034264f8c981b505aadac3ce7289486a1a68"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-09-26T13:14:20.156Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -21707,11 +21707,11 @@
21707 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
21708 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
21709 SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void);
21710 SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
21711 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
21712 SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3*,const char*);
21713 #endif
21714 SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
21715 SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
21716 SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
21717 SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p);
@@ -124262,10 +124262,15 @@
124262 if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
124263 Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
124264 if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
124265 pMod = sqlite3PragmaVtabRegister(db, zName);
124266 }
124267 #ifndef SQLITE_OMIT_JSON
124268 if( pMod==0 && sqlite3_strnicmp(zName, "json", 4)==0 ){
124269 pMod = sqlite3JsonVtabRegister(db, zName);
124270 }
124271 #endif
124272 if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
124273 testcase( pMod->pEpoTab==0 );
124274 return pMod->pEpoTab;
124275 }
124276 }
@@ -183862,13 +183867,10 @@
183867 #endif
183868 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
183869 sqlite3DbstatRegister,
183870 #endif
183871 sqlite3TestExtInit,
 
 
 
183872 #ifdef SQLITE_ENABLE_STMTVTAB
183873 sqlite3StmtVtabInit,
183874 #endif
183875 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
183876 sqlite3VdbeBytecodeVtabInit,
@@ -211323,11 +211325,11 @@
211325 switch( (u8)zIn[1] ){
211326 case '\'':
211327 jsonAppendChar(pOut, '\'');
211328 break;
211329 case 'v':
211330 jsonAppendRawNZ(pOut, "\\u000b", 6);
211331 break;
211332 case 'x':
211333 if( sz2<4 ){
211334 pOut->eErr |= JSTRING_MALFORMED;
211335 sz2 = 2;
@@ -212173,23 +212175,31 @@
212175 /*
212176 ** Return the value of the BLOB node at index i.
212177 **
212178 ** If the value is a primitive, return it as an SQL value.
212179 ** If the value is an array or object, return it as either
212180 ** JSON text or the BLOB encoding, depending on the eMode flag
212181 ** as follows:
212182 **
212183 ** eMode==0 JSONB if the JSON_B flag is set in userdata or
212184 ** text if the JSON_B flag is omitted from userdata.
212185 **
212186 ** eMode==1 Text
212187 **
212188 ** eMode==2 JSONB
212189 */
212190 static void jsonReturnFromBlob(
212191 JsonParse *pParse, /* Complete JSON parse tree */
212192 u32 i, /* Index of the node */
212193 sqlite3_context *pCtx, /* Return value for this function */
212194 int eMode /* Format of return: text of JSONB */
212195 ){
212196 u32 n, sz;
212197 int rc;
212198 sqlite3 *db = sqlite3_context_db_handle(pCtx);
212199
212200 assert( eMode>=0 && eMode<=2 );
212201 n = jsonbPayloadSize(pParse, i, &sz);
212202 if( n==0 ){
212203 sqlite3_result_error(pCtx, "malformed JSON", -1);
212204 return;
212205 }
@@ -212304,12 +212314,18 @@
212314 sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
212315 break;
212316 }
212317 case JSONB_ARRAY:
212318 case JSONB_OBJECT: {
212319 if( eMode==0 ){
212320 if( (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)) & JSON_BLOB)!=0 ){
212321 eMode = 2;
212322 }else{
212323 eMode = 1;
212324 }
212325 }
212326 if( eMode==2 ){
212327 sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
212328 }else{
212329 jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
212330 }
212331 break;
@@ -213952,10 +213968,11 @@
213968 u32 i; /* Index in sParse.aBlob[] of current row */
213969 u32 iEnd; /* EOF when i equals or exceeds this value */
213970 u32 nRoot; /* Size of the root path in bytes */
213971 u8 eType; /* Type of the container for element i */
213972 u8 bRecursive; /* True for json_tree(). False for json_each() */
213973 u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */
213974 u32 nParent; /* Current nesting depth */
213975 u32 nParentAlloc; /* Space allocated for aParent[] */
213976 JsonParent *aParent; /* Parent elements of i */
213977 sqlite3 *db; /* Database connection */
213978 JsonString path; /* Current path */
@@ -213963,10 +213980,12 @@
213980 };
213981 typedef struct JsonEachConnection JsonEachConnection;
213982 struct JsonEachConnection {
213983 sqlite3_vtab base; /* Base class - must be first */
213984 sqlite3 *db; /* Database connection */
213985 u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */
213986 u8 bRecursive; /* True for json_tree(). False for json_each() */
213987 };
213988
213989
213990 /* Constructor for the json_each virtual table */
213991 static int jsonEachConnect(
@@ -214005,10 +214024,12 @@
214024 pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
214025 *ppVtab = (sqlite3_vtab*)pNew;
214026 if( pNew==0 ) return SQLITE_NOMEM;
214027 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
214028 pNew->db = db;
214029 pNew->eMode = argv[0][4]=='b' ? 2 : 1;
214030 pNew->bRecursive = argv[0][4+pNew->eMode]=='t';
214031 }
214032 return rc;
214033 }
214034
214035 /* destructor for json_each virtual table */
@@ -214016,34 +214037,26 @@
214037 JsonEachConnection *p = (JsonEachConnection*)pVtab;
214038 sqlite3DbFree(p->db, pVtab);
214039 return SQLITE_OK;
214040 }
214041
214042 /* constructor for a JsonEachCursor object for json_each()/json_tree(). */
214043 static int jsonEachOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
214044 JsonEachConnection *pVtab = (JsonEachConnection*)p;
214045 JsonEachCursor *pCur;
214046
214047 UNUSED_PARAMETER(p);
214048 pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
214049 if( pCur==0 ) return SQLITE_NOMEM;
214050 pCur->db = pVtab->db;
214051 pCur->eMode = pVtab->eMode;
214052 pCur->bRecursive = pVtab->bRecursive;
214053 jsonStringZero(&pCur->path);
214054 *ppCursor = &pCur->base;
214055 return SQLITE_OK;
214056 }
214057
 
 
 
 
 
 
 
 
 
 
214058 /* Reset a JsonEachCursor back to its original state. Free any memory
214059 ** held. */
214060 static void jsonEachCursorReset(JsonEachCursor *p){
214061 jsonParseReset(&p->sParse);
214062 jsonStringReset(&p->path);
@@ -214244,11 +214257,11 @@
214257 }
214258 break;
214259 }
214260 case JEACH_VALUE: {
214261 u32 i = jsonSkipLabel(p);
214262 jsonReturnFromBlob(&p->sParse, i, ctx, p->eMode);
214263 if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
214264 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
214265 }
214266 break;
214267 }
@@ -214488,40 +214501,11 @@
214501 0, /* xCreate */
214502 jsonEachConnect, /* xConnect */
214503 jsonEachBestIndex, /* xBestIndex */
214504 jsonEachDisconnect, /* xDisconnect */
214505 0, /* xDestroy */
214506 jsonEachOpen, /* xOpen - open a cursor */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214507 jsonEachClose, /* xClose - close a cursor */
214508 jsonEachFilter, /* xFilter - configure scan constraints */
214509 jsonEachNext, /* xNext - advance a cursor */
214510 jsonEachEof, /* xEof - check for end of scan */
214511 jsonEachColumn, /* xColumn - read data */
@@ -214606,26 +214590,25 @@
214590 #endif
214591 }
214592
214593 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
214594 /*
214595 ** Register the JSON table-valued function named zName and return a
214596 ** pointer to its Module object. Return NULL if something goes wrong.
214597 */
214598 SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3 *db, const char *zName){
 
 
 
 
 
 
 
 
214599 unsigned int i;
214600 static const char *azModule[] = {
214601 "json_each", "json_tree", "jsonb_each", "jsonb_tree"
214602 };
214603 assert( sqlite3HashFind(&db->aModule, zName)==0 );
214604 for(i=0; i<sizeof(azModule)/sizeof(azModule[0]); i++){
214605 if( sqlite3StrICmp(azModule[i],zName)==0 ){
214606 return sqlite3VtabCreateModule(db, azModule[i], &jsonEachModule, 0, 0);
214607 }
214608 }
214609 return 0;
214610 }
214611 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
214612
214613 /************** End of json.c ************************************************/
214614 /************** Begin file rtree.c *******************************************/
@@ -234701,10 +234684,11 @@
234684 }
234685 }
234686
234687 assert( sApply.bRebase || sApply.rebase.nBuf==0 );
234688 if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
234689 assert( ppRebase!=0 && pnRebase!=0 );
234690 *ppRebase = (void*)sApply.rebase.aBuf;
234691 *pnRebase = sApply.rebase.nBuf;
234692 sApply.rebase.aBuf = 0;
234693 }
234694 sessionUpdateFree(&sApply);
@@ -252414,11 +252398,11 @@
252398 u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
252399 } uFts;
252400 fts5StructureInvalidate(p);
252401 fts5IndexDiscardData(p);
252402 pTmp = &uFts.sFts;
252403 memset(uFts.tmpSpace, 0, sizeof(uFts.tmpSpace));
252404 if( p->pConfig->bContentlessDelete ){
252405 pTmp->nOriginCntr = 1;
252406 }
252407 fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
252408 fts5StructureWrite(p, pTmp);
@@ -258722,11 +258706,11 @@
258706 int nArg, /* Number of args */
258707 sqlite3_value **apUnused /* Function arguments */
258708 ){
258709 assert( nArg==0 );
258710 UNUSED_PARAM2(nArg, apUnused);
258711 sqlite3_result_text(pCtx, "fts5: 2025-09-26 11:47:13 d022ee167b90a7c32049a93d476e869270018017f60551185024409730d77640", -1, SQLITE_TRANSIENT);
258712 }
258713
258714 /*
258715 ** Implementation of fts5_locale(LOCALE, TEXT) function.
258716 **
258717
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.51.0"
150150
#define SQLITE_VERSION_NUMBER 3051000
151
-#define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
151
+#define SQLITE_SOURCE_ID "2025-09-26 13:14:20 911c745f88c0ee8569e67bbcbbab034264f8c981b505aadac3ce7289486a1a68"
152152
#define SQLITE_SCM_BRANCH "trunk"
153153
#define SQLITE_SCM_TAGS ""
154
-#define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
154
+#define SQLITE_SCM_DATETIME "2025-09-26T13:14:20.156Z"
155155
156156
/*
157157
** CAPI3REF: Run-Time Library Version Numbers
158158
** KEYWORDS: sqlite3_version sqlite3_sourceid
159159
**
160160
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-09-24T19:10:58.215Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
160
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-09-26 13:14:20 911c745f88c0ee8569e67bbcbbab034264f8c981b505aadac3ce7289486a1a68"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-09-26T13:14:20.156Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
160
+47 -19
--- src/regexp.c
+++ src/regexp.c
@@ -24,11 +24,11 @@
2424
** The following regular expression syntax is supported:
2525
**
2626
** X* zero or more occurrences of X
2727
** X+ one or more occurrences of X
2828
** X? zero or one occurrences of X
29
-** X{p,q} between p and q occurrences of X
29
+** X{p,q} between p and q occurrences of X, 0 <= p,q <= 999
3030
** (X) match X
3131
** X|Y X or Y
3232
** ^X X occurring at the beginning of the string
3333
** X$ X occurring at the end of the string
3434
** . Match any single character
@@ -53,16 +53,24 @@
5353
** expression and M is the size of the input string. The matcher never
5454
** exhibits exponential behavior. Note that the X{p,q} operator expands
5555
** to p copies of X following by q-p copies of X? and that the size of the
5656
** regular expression in the O(N*M) performance bound is computed after
5757
** this expansion.
58
+**
59
+** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
60
+** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999.
5861
*/
5962
#include "config.h"
6063
#include "regexp.h"
64
+
65
+#ifndef SQLITE_MAX_REGEXP_REPEAT
66
+# define SQLITE_MAX_REGEXP_REPEAT 999
67
+#endif
6168
6269
/* The end-of-input character */
6370
#define RE_EOF 0 /* End of input */
71
+#define RE_START 0xfffffff /* Start of input - larger than an UTF-8 */
6472
6573
/* The NFA is implemented as sequence of opcodes taken from the following
6674
** set. Each opcode has a single integer argument.
6775
*/
6876
#define RE_OP_MATCH 1 /* Match the one character in the argument */
@@ -80,10 +88,11 @@
8088
#define RE_OP_DIGIT 13 /* digit: [0-9] */
8189
#define RE_OP_NOTDIGIT 14 /* Not a digit */
8290
#define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */
8391
#define RE_OP_NOTSPACE 16 /* Not a digit */
8492
#define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */
93
+#define RE_OP_ATSTART 18 /* Currently at the start of the string */
8594
8695
/* Each opcode is a "state" in the NFA */
8796
typedef unsigned short ReStateNumber;
8897
8998
/* Because this is an NFA and not a DFA, multiple states can be active at
@@ -185,11 +194,11 @@
185194
ReStateSet aStateSet[2], *pThis, *pNext;
186195
ReStateNumber aSpace[100];
187196
ReStateNumber *pToFree;
188197
unsigned int i = 0;
189198
unsigned int iSwap = 0;
190
- int c = RE_EOF+1;
199
+ int c = RE_START;
191200
int cPrev = 0;
192201
int rc = 0;
193202
ReInput in;
194203
195204
in.z = zIn;
@@ -204,10 +213,11 @@
204213
strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
205214
){
206215
in.i++;
207216
}
208217
if( in.i+pRe->nInit>in.mx ) return 0;
218
+ c = RE_START-1;
209219
}
210220
211221
if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
212222
pToFree = 0;
213223
aStateSet[0].aState = aSpace;
@@ -231,10 +241,14 @@
231241
int x = pThis->aState[i];
232242
switch( pRe->aOp[x] ){
233243
case RE_OP_MATCH: {
234244
if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
235245
break;
246
+ }
247
+ case RE_OP_ATSTART: {
248
+ if( cPrev==RE_START ) re_add_state(pThis, x+1);
249
+ break;
236250
}
237251
case RE_OP_ANY: {
238252
if( c!=0 ) re_add_state(pNext, x+1);
239253
break;
240254
}
@@ -313,11 +327,13 @@
313327
}
314328
}
315329
}
316330
}
317331
for(i=0; i<pNext->nState; i++){
318
- if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
332
+ int x = pNext->aState[i];
333
+ while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x];
334
+ if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; }
319335
}
320336
re_match_end:
321337
fossil_free(pToFree);
322338
return rc;
323339
}
@@ -468,11 +484,10 @@
468484
const char *zErr;
469485
while( (c = p->xNextChar(&p->sIn))!=0 ){
470486
iStart = p->nState;
471487
switch( c ){
472488
case '|':
473
- case '$':
474489
case ')': {
475490
p->sIn.i--;
476491
return 0;
477492
}
478493
case '(': {
@@ -504,29 +519,46 @@
504519
}
505520
case '?': {
506521
if( iPrev<0 ) return "'?' without operand";
507522
re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
508523
break;
524
+ }
525
+ case '$': {
526
+ re_append(p, RE_OP_MATCH, RE_EOF);
527
+ break;
528
+ }
529
+ case '^': {
530
+ re_append(p, RE_OP_ATSTART, 0);
531
+ break;
509532
}
510533
case '{': {
511
- int m = 0, n = 0;
512
- int sz, j;
534
+ unsigned int m = 0, n = 0;
535
+ unsigned int sz, j;
513536
if( iPrev<0 ) return "'{m,n}' without operand";
514
- while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
537
+ while( (c=rePeek(p))>='0' && c<='9' ){
538
+ m = m*10 + c - '0';
539
+ if( m>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
540
+ p->sIn.i++;
541
+ }
515542
n = m;
516543
if( c==',' ){
517544
p->sIn.i++;
518545
n = 0;
519
- while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
546
+ while( (c=rePeek(p))>='0' && c<='9' ){
547
+ n = n*10 + c-'0';
548
+ if( n>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
549
+ p->sIn.i++;
550
+ }
520551
}
521552
if( c!='}' ) return "unmatched '{'";
522553
if( n>0 && n<m ) return "n less than m in '{m,n}'";
523554
p->sIn.i++;
524555
sz = p->nState - iPrev;
525556
if( m==0 ){
526557
if( n==0 ) return "both m and n are zero in '{m,n}'";
527558
re_insert(p, iPrev, RE_OP_FORK, sz+1);
559
+ iPrev++;
528560
n--;
529561
}else{
530562
for(j=1; j<m; j++) re_copy(p, iPrev, sz);
531563
}
532564
for(j=m; j<n; j++){
@@ -537,11 +569,11 @@
537569
re_append(p, RE_OP_FORK, -sz);
538570
}
539571
break;
540572
}
541573
case '[': {
542
- int iFirst = p->nState;
574
+ unsigned int iFirst = p->nState;
543575
if( rePeek(p)=='^' ){
544576
re_append(p, RE_OP_CC_EXC, 0);
545577
p->sIn.i++;
546578
}else{
547579
re_append(p, RE_OP_CC_INC, 0);
@@ -561,11 +593,11 @@
561593
re_append(p, RE_OP_CC_VALUE, c);
562594
}
563595
if( rePeek(p)==']' ){ p->sIn.i++; break; }
564596
}
565597
if( c==0 ) return "unclosed '['";
566
- p->aArg[iFirst] = p->nState - iFirst;
598
+ if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst;
567599
break;
568600
}
569601
case '\\': {
570602
int specialOp = 0;
571603
switch( rePeek(p) ){
@@ -641,15 +673,11 @@
641673
zErr = re_subcompile_re(pRe);
642674
if( zErr ){
643675
re_free(pRe);
644676
return zErr;
645677
}
646
- if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
647
- re_append(pRe, RE_OP_MATCH, RE_EOF);
648
- re_append(pRe, RE_OP_ACCEPT, 0);
649
- *ppRe = pRe;
650
- }else if( pRe->sIn.i>=pRe->sIn.mx ){
678
+ if( pRe->sIn.i>=pRe->sIn.mx ){
651679
re_append(pRe, RE_OP_ACCEPT, 0);
652680
*ppRe = pRe;
653681
}else{
654682
re_free(pRe);
655683
return "unrecognized character";
@@ -658,23 +686,23 @@
658686
/* The following is a performance optimization. If the regex begins with
659687
** ".*" (if the input regex lacks an initial "^") and afterwards there are
660688
** one or more matching characters, enter those matching characters into
661689
** zInit[]. The re_match() routine can then search ahead in the input
662690
** string looking for the initial match without having to run the whole
663
- ** regex engine over the string. Do not worry able trying to match
691
+ ** regex engine over the string. Do not worry about trying to match
664692
** unicode characters beyond plane 0 - those are very rare and this is
665693
** just an optimization. */
666694
if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
667695
for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
668696
unsigned x = pRe->aArg[i];
669
- if( x<=127 ){
697
+ if( x<=0x7f ){
670698
pRe->zInit[j++] = (unsigned char)x;
671
- }else if( x<=0xfff ){
699
+ }else if( x<=0x7ff ){
672700
pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
673701
pRe->zInit[j++] = 0x80 | (x&0x3f);
674702
}else if( x<=0xffff ){
675
- pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
703
+ pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
676704
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
677705
pRe->zInit[j++] = 0x80 | (x&0x3f);
678706
}else{
679707
break;
680708
}
681709
--- src/regexp.c
+++ src/regexp.c
@@ -24,11 +24,11 @@
24 ** The following regular expression syntax is supported:
25 **
26 ** X* zero or more occurrences of X
27 ** X+ one or more occurrences of X
28 ** X? zero or one occurrences of X
29 ** X{p,q} between p and q occurrences of X
30 ** (X) match X
31 ** X|Y X or Y
32 ** ^X X occurring at the beginning of the string
33 ** X$ X occurring at the end of the string
34 ** . Match any single character
@@ -53,16 +53,24 @@
53 ** expression and M is the size of the input string. The matcher never
54 ** exhibits exponential behavior. Note that the X{p,q} operator expands
55 ** to p copies of X following by q-p copies of X? and that the size of the
56 ** regular expression in the O(N*M) performance bound is computed after
57 ** this expansion.
 
 
 
58 */
59 #include "config.h"
60 #include "regexp.h"
 
 
 
 
61
62 /* The end-of-input character */
63 #define RE_EOF 0 /* End of input */
 
64
65 /* The NFA is implemented as sequence of opcodes taken from the following
66 ** set. Each opcode has a single integer argument.
67 */
68 #define RE_OP_MATCH 1 /* Match the one character in the argument */
@@ -80,10 +88,11 @@
80 #define RE_OP_DIGIT 13 /* digit: [0-9] */
81 #define RE_OP_NOTDIGIT 14 /* Not a digit */
82 #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */
83 #define RE_OP_NOTSPACE 16 /* Not a digit */
84 #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */
 
85
86 /* Each opcode is a "state" in the NFA */
87 typedef unsigned short ReStateNumber;
88
89 /* Because this is an NFA and not a DFA, multiple states can be active at
@@ -185,11 +194,11 @@
185 ReStateSet aStateSet[2], *pThis, *pNext;
186 ReStateNumber aSpace[100];
187 ReStateNumber *pToFree;
188 unsigned int i = 0;
189 unsigned int iSwap = 0;
190 int c = RE_EOF+1;
191 int cPrev = 0;
192 int rc = 0;
193 ReInput in;
194
195 in.z = zIn;
@@ -204,10 +213,11 @@
204 strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
205 ){
206 in.i++;
207 }
208 if( in.i+pRe->nInit>in.mx ) return 0;
 
209 }
210
211 if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
212 pToFree = 0;
213 aStateSet[0].aState = aSpace;
@@ -231,10 +241,14 @@
231 int x = pThis->aState[i];
232 switch( pRe->aOp[x] ){
233 case RE_OP_MATCH: {
234 if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
235 break;
 
 
 
 
236 }
237 case RE_OP_ANY: {
238 if( c!=0 ) re_add_state(pNext, x+1);
239 break;
240 }
@@ -313,11 +327,13 @@
313 }
314 }
315 }
316 }
317 for(i=0; i<pNext->nState; i++){
318 if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
 
 
319 }
320 re_match_end:
321 fossil_free(pToFree);
322 return rc;
323 }
@@ -468,11 +484,10 @@
468 const char *zErr;
469 while( (c = p->xNextChar(&p->sIn))!=0 ){
470 iStart = p->nState;
471 switch( c ){
472 case '|':
473 case '$':
474 case ')': {
475 p->sIn.i--;
476 return 0;
477 }
478 case '(': {
@@ -504,29 +519,46 @@
504 }
505 case '?': {
506 if( iPrev<0 ) return "'?' without operand";
507 re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
508 break;
 
 
 
 
 
 
 
 
509 }
510 case '{': {
511 int m = 0, n = 0;
512 int sz, j;
513 if( iPrev<0 ) return "'{m,n}' without operand";
514 while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
 
 
 
 
515 n = m;
516 if( c==',' ){
517 p->sIn.i++;
518 n = 0;
519 while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
 
 
 
 
520 }
521 if( c!='}' ) return "unmatched '{'";
522 if( n>0 && n<m ) return "n less than m in '{m,n}'";
523 p->sIn.i++;
524 sz = p->nState - iPrev;
525 if( m==0 ){
526 if( n==0 ) return "both m and n are zero in '{m,n}'";
527 re_insert(p, iPrev, RE_OP_FORK, sz+1);
 
528 n--;
529 }else{
530 for(j=1; j<m; j++) re_copy(p, iPrev, sz);
531 }
532 for(j=m; j<n; j++){
@@ -537,11 +569,11 @@
537 re_append(p, RE_OP_FORK, -sz);
538 }
539 break;
540 }
541 case '[': {
542 int iFirst = p->nState;
543 if( rePeek(p)=='^' ){
544 re_append(p, RE_OP_CC_EXC, 0);
545 p->sIn.i++;
546 }else{
547 re_append(p, RE_OP_CC_INC, 0);
@@ -561,11 +593,11 @@
561 re_append(p, RE_OP_CC_VALUE, c);
562 }
563 if( rePeek(p)==']' ){ p->sIn.i++; break; }
564 }
565 if( c==0 ) return "unclosed '['";
566 p->aArg[iFirst] = p->nState - iFirst;
567 break;
568 }
569 case '\\': {
570 int specialOp = 0;
571 switch( rePeek(p) ){
@@ -641,15 +673,11 @@
641 zErr = re_subcompile_re(pRe);
642 if( zErr ){
643 re_free(pRe);
644 return zErr;
645 }
646 if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
647 re_append(pRe, RE_OP_MATCH, RE_EOF);
648 re_append(pRe, RE_OP_ACCEPT, 0);
649 *ppRe = pRe;
650 }else if( pRe->sIn.i>=pRe->sIn.mx ){
651 re_append(pRe, RE_OP_ACCEPT, 0);
652 *ppRe = pRe;
653 }else{
654 re_free(pRe);
655 return "unrecognized character";
@@ -658,23 +686,23 @@
658 /* The following is a performance optimization. If the regex begins with
659 ** ".*" (if the input regex lacks an initial "^") and afterwards there are
660 ** one or more matching characters, enter those matching characters into
661 ** zInit[]. The re_match() routine can then search ahead in the input
662 ** string looking for the initial match without having to run the whole
663 ** regex engine over the string. Do not worry able trying to match
664 ** unicode characters beyond plane 0 - those are very rare and this is
665 ** just an optimization. */
666 if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
667 for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
668 unsigned x = pRe->aArg[i];
669 if( x<=127 ){
670 pRe->zInit[j++] = (unsigned char)x;
671 }else if( x<=0xfff ){
672 pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
673 pRe->zInit[j++] = 0x80 | (x&0x3f);
674 }else if( x<=0xffff ){
675 pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
676 pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
677 pRe->zInit[j++] = 0x80 | (x&0x3f);
678 }else{
679 break;
680 }
681
--- src/regexp.c
+++ src/regexp.c
@@ -24,11 +24,11 @@
24 ** The following regular expression syntax is supported:
25 **
26 ** X* zero or more occurrences of X
27 ** X+ one or more occurrences of X
28 ** X? zero or one occurrences of X
29 ** X{p,q} between p and q occurrences of X, 0 <= p,q <= 999
30 ** (X) match X
31 ** X|Y X or Y
32 ** ^X X occurring at the beginning of the string
33 ** X$ X occurring at the end of the string
34 ** . Match any single character
@@ -53,16 +53,24 @@
53 ** expression and M is the size of the input string. The matcher never
54 ** exhibits exponential behavior. Note that the X{p,q} operator expands
55 ** to p copies of X following by q-p copies of X? and that the size of the
56 ** regular expression in the O(N*M) performance bound is computed after
57 ** this expansion.
58 **
59 ** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
60 ** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999.
61 */
62 #include "config.h"
63 #include "regexp.h"
64
65 #ifndef SQLITE_MAX_REGEXP_REPEAT
66 # define SQLITE_MAX_REGEXP_REPEAT 999
67 #endif
68
69 /* The end-of-input character */
70 #define RE_EOF 0 /* End of input */
71 #define RE_START 0xfffffff /* Start of input - larger than an UTF-8 */
72
73 /* The NFA is implemented as sequence of opcodes taken from the following
74 ** set. Each opcode has a single integer argument.
75 */
76 #define RE_OP_MATCH 1 /* Match the one character in the argument */
@@ -80,10 +88,11 @@
88 #define RE_OP_DIGIT 13 /* digit: [0-9] */
89 #define RE_OP_NOTDIGIT 14 /* Not a digit */
90 #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */
91 #define RE_OP_NOTSPACE 16 /* Not a digit */
92 #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */
93 #define RE_OP_ATSTART 18 /* Currently at the start of the string */
94
95 /* Each opcode is a "state" in the NFA */
96 typedef unsigned short ReStateNumber;
97
98 /* Because this is an NFA and not a DFA, multiple states can be active at
@@ -185,11 +194,11 @@
194 ReStateSet aStateSet[2], *pThis, *pNext;
195 ReStateNumber aSpace[100];
196 ReStateNumber *pToFree;
197 unsigned int i = 0;
198 unsigned int iSwap = 0;
199 int c = RE_START;
200 int cPrev = 0;
201 int rc = 0;
202 ReInput in;
203
204 in.z = zIn;
@@ -204,10 +213,11 @@
213 strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
214 ){
215 in.i++;
216 }
217 if( in.i+pRe->nInit>in.mx ) return 0;
218 c = RE_START-1;
219 }
220
221 if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
222 pToFree = 0;
223 aStateSet[0].aState = aSpace;
@@ -231,10 +241,14 @@
241 int x = pThis->aState[i];
242 switch( pRe->aOp[x] ){
243 case RE_OP_MATCH: {
244 if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
245 break;
246 }
247 case RE_OP_ATSTART: {
248 if( cPrev==RE_START ) re_add_state(pThis, x+1);
249 break;
250 }
251 case RE_OP_ANY: {
252 if( c!=0 ) re_add_state(pNext, x+1);
253 break;
254 }
@@ -313,11 +327,13 @@
327 }
328 }
329 }
330 }
331 for(i=0; i<pNext->nState; i++){
332 int x = pNext->aState[i];
333 while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x];
334 if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; }
335 }
336 re_match_end:
337 fossil_free(pToFree);
338 return rc;
339 }
@@ -468,11 +484,10 @@
484 const char *zErr;
485 while( (c = p->xNextChar(&p->sIn))!=0 ){
486 iStart = p->nState;
487 switch( c ){
488 case '|':
 
489 case ')': {
490 p->sIn.i--;
491 return 0;
492 }
493 case '(': {
@@ -504,29 +519,46 @@
519 }
520 case '?': {
521 if( iPrev<0 ) return "'?' without operand";
522 re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
523 break;
524 }
525 case '$': {
526 re_append(p, RE_OP_MATCH, RE_EOF);
527 break;
528 }
529 case '^': {
530 re_append(p, RE_OP_ATSTART, 0);
531 break;
532 }
533 case '{': {
534 unsigned int m = 0, n = 0;
535 unsigned int sz, j;
536 if( iPrev<0 ) return "'{m,n}' without operand";
537 while( (c=rePeek(p))>='0' && c<='9' ){
538 m = m*10 + c - '0';
539 if( m>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
540 p->sIn.i++;
541 }
542 n = m;
543 if( c==',' ){
544 p->sIn.i++;
545 n = 0;
546 while( (c=rePeek(p))>='0' && c<='9' ){
547 n = n*10 + c-'0';
548 if( n>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
549 p->sIn.i++;
550 }
551 }
552 if( c!='}' ) return "unmatched '{'";
553 if( n>0 && n<m ) return "n less than m in '{m,n}'";
554 p->sIn.i++;
555 sz = p->nState - iPrev;
556 if( m==0 ){
557 if( n==0 ) return "both m and n are zero in '{m,n}'";
558 re_insert(p, iPrev, RE_OP_FORK, sz+1);
559 iPrev++;
560 n--;
561 }else{
562 for(j=1; j<m; j++) re_copy(p, iPrev, sz);
563 }
564 for(j=m; j<n; j++){
@@ -537,11 +569,11 @@
569 re_append(p, RE_OP_FORK, -sz);
570 }
571 break;
572 }
573 case '[': {
574 unsigned int iFirst = p->nState;
575 if( rePeek(p)=='^' ){
576 re_append(p, RE_OP_CC_EXC, 0);
577 p->sIn.i++;
578 }else{
579 re_append(p, RE_OP_CC_INC, 0);
@@ -561,11 +593,11 @@
593 re_append(p, RE_OP_CC_VALUE, c);
594 }
595 if( rePeek(p)==']' ){ p->sIn.i++; break; }
596 }
597 if( c==0 ) return "unclosed '['";
598 if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst;
599 break;
600 }
601 case '\\': {
602 int specialOp = 0;
603 switch( rePeek(p) ){
@@ -641,15 +673,11 @@
673 zErr = re_subcompile_re(pRe);
674 if( zErr ){
675 re_free(pRe);
676 return zErr;
677 }
678 if( pRe->sIn.i>=pRe->sIn.mx ){
 
 
 
 
679 re_append(pRe, RE_OP_ACCEPT, 0);
680 *ppRe = pRe;
681 }else{
682 re_free(pRe);
683 return "unrecognized character";
@@ -658,23 +686,23 @@
686 /* The following is a performance optimization. If the regex begins with
687 ** ".*" (if the input regex lacks an initial "^") and afterwards there are
688 ** one or more matching characters, enter those matching characters into
689 ** zInit[]. The re_match() routine can then search ahead in the input
690 ** string looking for the initial match without having to run the whole
691 ** regex engine over the string. Do not worry about trying to match
692 ** unicode characters beyond plane 0 - those are very rare and this is
693 ** just an optimization. */
694 if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
695 for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
696 unsigned x = pRe->aArg[i];
697 if( x<=0x7f ){
698 pRe->zInit[j++] = (unsigned char)x;
699 }else if( x<=0x7ff ){
700 pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
701 pRe->zInit[j++] = 0x80 | (x&0x3f);
702 }else if( x<=0xffff ){
703 pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
704 pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
705 pRe->zInit[j++] = 0x80 | (x&0x3f);
706 }else{
707 break;
708 }
709
--- www/grep.md
+++ www/grep.md
@@ -99,10 +99,15 @@
9999
There are several restrictions in Fossil `grep` relative to a fully
100100
POSIX compatible regular expression engine. Among them are:
101101
102102
* There is currently no support for POSIX character classes such as
103103
`[:lower:]`.
104
+
105
+* The values of `p` and `q` in the "`{p,q}`" syntax can be no greater
106
+ than 999. This is because the NFA that is used for regular expression
107
+ matching is proportional in size to the largest p or q value, and hence
108
+ allowing arbitrarily large values could result in a DoS attack.
104109
105110
* Fossil `grep` does not currently attempt to take your operating
106111
system's locale settings into account when doing this match. Since
107112
Fossil has no way to mark a given file as having a particular
108113
encoding, Fossil `grep` assumes the input files are in UTF-8 format.
109114
--- www/grep.md
+++ www/grep.md
@@ -99,10 +99,15 @@
99 There are several restrictions in Fossil `grep` relative to a fully
100 POSIX compatible regular expression engine. Among them are:
101
102 * There is currently no support for POSIX character classes such as
103 `[:lower:]`.
 
 
 
 
 
104
105 * Fossil `grep` does not currently attempt to take your operating
106 system's locale settings into account when doing this match. Since
107 Fossil has no way to mark a given file as having a particular
108 encoding, Fossil `grep` assumes the input files are in UTF-8 format.
109
--- www/grep.md
+++ www/grep.md
@@ -99,10 +99,15 @@
99 There are several restrictions in Fossil `grep` relative to a fully
100 POSIX compatible regular expression engine. Among them are:
101
102 * There is currently no support for POSIX character classes such as
103 `[:lower:]`.
104
105 * The values of `p` and `q` in the "`{p,q}`" syntax can be no greater
106 than 999. This is because the NFA that is used for regular expression
107 matching is proportional in size to the largest p or q value, and hence
108 allowing arbitrarily large values could result in a DoS attack.
109
110 * Fossil `grep` does not currently attempt to take your operating
111 system's locale settings into account when doing this match. Since
112 Fossil has no way to mark a given file as having a particular
113 encoding, Fossil `grep` assumes the input files are in UTF-8 format.
114

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button