-C Ensure\sthat\sthe\s"leaf-size"\sfield\sof\san\sfts5\srecord\sis\sonly\sread\sfrom\srecords\sthat\sare\sactually\sleaves\sand\sare\slarge\senough\sto\scontain\sit.\sBug\s[bugs:/info/2026-07-09T20:15:55Z\s|\s2026-07-09T20:15:55Z].
-D 2026-07-09T20:56:29.034
+C New\scompile-time\soption\sSQLITE_MAX_SCHEMA\sand\sruntime\slimit\soption\nSQLITE_LIMIT_SCHEMA\sthat\sput\san\supper\sbound\son\sthe\snumber\sof\sobjects\nin\sa\sdatabase\sschema.\s\sCurrent\sdefault\sis\s10\smillion.
+D 2026-07-10T15:06:05.593
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/json.c e4af4d799e4e7630c633b3b356d65e92d1781e42343ab77b8ef747c932762012
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 5cd4cd7ec6e1a46416806899086363fbf95eecd3bfb9a388b436c9a77243c902
-F src/main.c 55a7d6d35bae30545e147ab0aa8dc156066abcd4aa8e97aaa5fc6f70b4961f77
+F src/main.c b0a4b497d0bf4414bdcd5dda81c49851fca7b6781e9e485ac4c360b291f6dbb8
F src/malloc.c 422f7e0498e1c9ef967f06283b6f2c0b16db6b905d8e06f6dbc8baaa3e4e6c5a
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
F src/pcache.h 092b758d2c5e4dabb30eae46d8dfad77c0f70b16bf3ff1943f7a232b0fe0d4ba
F src/pcache1.c d7ee0f95992501a65379f620b3de1430b64e52e397769938668a9fd9dd1c8145
F src/pragma.c 789ef67117b74b5be0a2db6681f7f0c55e6913791b9da309aefd280de2c8a74d
-F src/prepare.c 4e6c56f92b2cba5b8efe44bae275e11436074504d1a25af56210f8fdd1d311b9
+F src/prepare.c 8954bb69defe377cd6a926f8c61d8215ea4f1974838d3ec6f22681a2c0a2939f
F src/printf.c b480176bd0aaed9d64e804cfa3ca27fc585f65a73e7c7ca2fe9b9016db2cf6d5
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 54395ee97eb710e695202d4112cf2b1c1c7767a57afcea745df71abb1c917768
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c f553420eaf5c72a49cef786621eea79dd8c4411671839fb05250bb49ca74a0a0
-F src/shell.c.in fc4ef494ecb839c78189e5951e066791b7b88113f5d36177b21e30b04c33eae7
-F src/sqlite.h.in d9ec41feb4cd804e68b174328b43beb3f1f71bba13e1c7a439efb826d301cccc
+F src/shell.c.in fe97e39eb81ba39d0407e3284e76a7629fc39e37526b74720b20cd2dad0f2e55
+F src/sqlite.h.in fc48797193d2a3364767924d181ee9670f57a8b58603ba849b4ab27011d36a85
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 0efd4723bad9124ea1f581d9f1ea0254ac1c6f3e5fb29e4f3dcf36c72485a456
-F src/sqliteInt.h 92563b8edc673513b82d87bf6a8d7aeb554b2c7b7d5e30992fbca04010db79ac
-F src/sqliteLimit.h c70656b67ab5b96741a8f1c812bdd80c81f2b1c1e443d0cc3ea8c33bb1f1a092
+F src/sqliteInt.h e1f1523f35284f1e6e8dc24cd00cb2d71f607b3e3eb507291c7bf7b4a0f62cc6
+F src/sqliteLimit.h 7617f2ee673dab382046beba4552283f442cf1a181bb169ac38eb908135dd8da
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c fac4e166b90c1e8c4cac76c1339dfb9d94646debda2cdf8026120a7e19a822ff
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
-F src/test1.c df2df0a74c9aa81cbbad9d7d8277e49ac255334cba97da9ee22501beac274201
+F src/test1.c 782ec14545feebb8189845225c7b2d194e15f09b0a279f7d846dc04810f3b478
F src/test2.c 2b9ab96bba63a1c369d5769390475259ad210f144a877805f2e32e563f9e93c1
F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
F src/test_bestindex.c d75fad21369d80910238032bcf8d9ca1f2bffda13c1ceec63bfbb7f704448b15
F src/test_blob.c 77b994e17f2c87055f44fd96c9a206c5a7155bae2cda2769af60c2f3582f962c
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
-F src/test_config.c e02566c2c4ee2916324ce17123a798b47663cead2de546cfbd71d8cddb46bb26
+F src/test_config.c ac3e4e5e3f5d23a3b604f64b98920a18411f9aa38d58ccd1f5be21103237b2e5
F src/test_delete.c d0e8f6dc55cfc98a7c27c057fb88d512260564bf0b611482656c68b8f7f401ed
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
F test/crash8.test 3a0c39c079b441a9b1da22e3edb58817f9dd330c4c3a7f9dd1f9f7c8368ea352
F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
-F test/createtab.test 85cdfdae5c3de331cd888d6c66e1aba575b47c2e3c3cc4a1d6f54140699f5165
+F test/createtab.test 4983b8ee20788404c440444cbe16760162806676e799d97c45d8415245b456ff
F test/cse.test 00b3aea44b16828833c94fbe92475fd6977583fcb064ae0bc590986812b38d0c
F test/csv01.test 96bc1634961682363a7b4ad5c0e38450e6e9743b38ac626422e1b56cbdc06cd8
F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c4773
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
F test/spellfix4.test 7c56a09de68b95051ef0627fe235e514efbba2aa816dc2a9c5c670d98877e632
F test/sqldiff1.test 1b7ab4f312442c5cc6b3a5f299fa8ca051416d1dd173cb1126fd51bf64f2c3fb
-F test/sqllimits1.test 408131e4975d61868711c83f101a56d4602313cc5cae88d3eee81c1da364fd89
+F test/sqllimits1.test aa8b02192c0ce71bd64ad2e475f5584739119143f11283ce6764339636fdc9f5
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
F test/starschema1.test f5388cd32527ab18d3f98f9e3402ec780f6a186e04e0d9c8531d7568ee734e11
F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c 63412f9790e5e8538fbde0b4f6db154aaaf80f7a10a01e3c94d14b773a8dd5a6
F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669
-F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
+F tool/max-limits.c ee1113c815a1a30b5f8f8f139076f7dab369c14630bb9d9630b9b5666622355e
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
F tool/mkamalzip.tcl 8aa5ebe7973c8b8774062d34e15fea9815c4cc2ceea3a9b184695f005910876a
F tool/mkautoconfamal.sh 06fbe090b81c24e592c1f22b404334f805ba74d482a9260f2ac81e6f3d3386d8
F tool/mkccode.tcl c42a8f8cf78f92e83795d5447460dbce7aaf78a3bbf9082f1507dc71a3665f3c x
F tool/mkcombo.tcl 2a5189b219c4a495e1ff7fc980bd568d3cfb82ae9d50c84e77f7a161e96fc132
-F tool/mkctimec.tcl 68f3ee9e2e6a06524b25d79b5b61a883053466080a39da59e0a0697f0c4d9a3b x
+F tool/mkctimec.tcl 85ce722e10f81368bc42fb194fe6af450f7f0ef9199b706cbc02b5b484ce3d4a x
F tool/mkfptab.c 24ea40113f96584caca3f6dd06b4ad5adffa0f39023910cb83fa7ef2ffa9b0ba
F tool/mkkeywordhash.c 82d5af1d0e677900739fba59155cddac172d8c712c2d91ab73d6e6bcb30060f0
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 805f3acd2b0e81c8274680cbc4cdd6b7b9246df8075ed9caba9e2780729a2740
-R 5be2523d6c3a388b70da09abeb3ec96a
-U dan
-Z 99f0e0d83d4051cee1aaca6f9271c8c5
+P fe52900694e045231e91047fbfd82577c7fa347d7352bd048867a9e95299a0d0
+R 54e660cf10d754b4c7ad7545a1946b03
+U drh
+Z 43294851f89ab63f1857d3510a40d29b
# Remove this line to create a well-formed Fossil manifest.
-fe52900694e045231e91047fbfd82577c7fa347d7352bd048867a9e95299a0d0
+4ff362a4c2897e2b438d3d8fc88a012264526fa617f058be5a2d596c42d2e8a4
SQLITE_MAX_TRIGGER_DEPTH,
SQLITE_MAX_WORKER_THREADS,
SQLITE_MAX_PARSER_DEPTH,
+ SQLITE_MAX_SCHEMA,
};
/*
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
- assert( SQLITE_LIMIT_PARSER_DEPTH==(SQLITE_N_LIMIT-1) );
+ assert( aHardLimit[SQLITE_LIMIT_SCHEMA]==SQLITE_MAX_SCHEMA );
+ assert( SQLITE_LIMIT_SCHEMA==(SQLITE_N_LIMIT-1) );
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
}
assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pSchema!=0 );
if( argv[3]==0 ){
corruptSchema(pData, argv, 0);
}else if( argv[4]
}
}
}
+ if( pData->pzErrMsg[0]==0 ){
+ Schema *pX = db->aDb[iDb].pSchema;
+ if( pX->tblHash.count + pX->idxHash.count + pX->trigHash.count
+ > (u32)db->aLimit[SQLITE_LIMIT_SCHEMA]
+ ){
+ *pData->pzErrMsg = sqlite3MPrintf(db, "too many schema objects");
+ pData->rc = SQLITE_ERROR;
+ return 1;
+ }
+ }
return 0;
}
{ "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
+ { "schema", SQLITE_LIMIT_SCHEMA },
};
int i, n2;
open_db(p, 0);
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
** <dd>The maximum number of auxiliary worker threads that a single
** [prepared statement] may start.</dd>)^
+**
+** [[SQLITE_LIMIT_SCHEMA]] ^(<dt>SQLITE_LIMIT_SCHEMA</dt>
+** <dd>The maximum number of objects (tables, indexes, triggers, and views)
+** defined by the database schema.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
#define SQLITE_LIMIT_PARSER_DEPTH 12
+#define SQLITE_LIMIT_SCHEMA 13
/*
** CAPI3REF: Prepare Flags
** The number of different kinds of things that can be limited
** using the sqlite3_limit() interface.
*/
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_PARSER_DEPTH+1)
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_SCHEMA+1)
/*
** Lookaside malloc is a set of fixed-size buffers that can be used
#ifndef SQLITE_MAX_TRIGGER_DEPTH
# define SQLITE_MAX_TRIGGER_DEPTH 1000
#endif
+
+/*
+** Maximum number of objects defined by a single database schema.
+** Objects include:
+**
+** * tables (including the sqlite_schema table)
+** * virtual tables
+** * named indexes
+** * indexes created automatically by UNIQUE and PRIMARY KEY constraints
+** * triggers
+** * views
+**
+** The total of all of the above is the number of objects in the schema,
+** and that number may not exceed this value.
+**
+** The maximum number of objects is restricted to forestall theoretical
+** signed integer overflow attacks using databases with billions of
+** schema objects. Such attacks are "theoretical" because memory and
+** disk space constraints would be reached long before billions of schema
+** objects could be created. Even so, it seems good to have a well defined
+** upper limit on the complexity of the schema, for defense in depth.
+** No real-world application should ever get anywhere close to hitting
+** this limit.
+*/
+#ifndef SQLITE_MAX_SCHEMA
+# define SQLITE_MAX_SCHEMA 10000000
+#endif
{ "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER },
{ "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "SQLITE_LIMIT_WORKER_THREADS", SQLITE_LIMIT_WORKER_THREADS },
+ { "SQLITE_LIMIT_SCHEMA", SQLITE_LIMIT_SCHEMA },
/* Out of range test cases */
{ "SQLITE_LIMIT_TOOSMALL", -1, },
- { "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_PARSER_DEPTH+1 },
+ { "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_SCHEMA+1 },
};
int i, id = 0;
int val;
LINKVAR( MAX_ATTACHED );
LINKVAR( MAX_DEFAULT_PAGE_SIZE );
LINKVAR( MAX_WORKER_THREADS );
+ LINKVAR( MAX_SCHEMA );
{
static const int cv_TEMP_STORE = SQLITE_TEMP_STORE;
set sql "CREATE TABLE t1(x,UNIQUE(x[string repeat ,x 100000]))"
catchsql $sql
} {1 {too many columns in index}}
+
+# Test cases for SQLITE_LIMIT_SCHEMA
+#
+reset_db
+sqlite3_limit db SQLITE_LIMIT_SCHEMA 5
+do_execsql_test createtab-4.0 {
+ CREATE TABLE t1(a,b,c UNIQUE);
+ CREATE INDEX x1 ON t1(a);
+ CREATE VIEW v1 AS SELECT a+b AS x FROM t1;
+} {}
+do_catchsql_test createtab-4.1 {
+ CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT true; END;
+} {1 {too many schema objects}}
finish_test
# Verify that the default per-connection limits are the same as
# the compile-time hard limits.
#
+# NB: These magic $SQLITE_MAX_xxx variables are set by LINKVAR()
+# macros in the src/test_config.c source file.
+#
sqlite3 db2 :memory:
do_test sqllimits1-1.1 {
sqlite3_limit db SQLITE_LIMIT_LENGTH -1
sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS 99999
sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS -1
} $SQLITE_MAX_WORKER_THREADS
+do_test sqllimits1-1.13 {
+ sqlite3_limit db SQLITE_LIMIT_SCHEMA 999999999
+ sqlite3_limit db SQLITE_LIMIT_SCHEMA -1
+} $SQLITE_MAX_SCHEMA
# Limit parameters out of range.
#
sqlite3_limit db SQLITE_LIMIT_VARIABLE_NUMBER -1
} [expr {$SQLITE_MAX_VARIABLE_NUMBER/2}]
}
+if {$SQLITE_MAX_SCHEMA>=2} {
+ do_test sqllimits1-2.11.1 {
+ sqlite3_limit db SQLITE_LIMIT_SCHEMA \
+ [expr {$::SQLITE_MAX_SCHEMA/2}]
+ } $SQLITE_MAX_SCHEMA
+ do_test sqllimits1-2.11.2 {
+ sqlite3_limit db SQLITE_LIMIT_SCHEMA -1
+ } [expr {$SQLITE_MAX_SCHEMA/2}]
+}
# In a separate database connection, verify that the limits are unchanged.
#
{ SQLITE_LIMIT_VARIABLE_NUMBER, "SQLITE_MAX_VARIABLE_NUMBER" },
{ SQLITE_LIMIT_TRIGGER_DEPTH, "SQLITE_MAX_TRIGGER_DEPTH" },
{ SQLITE_LIMIT_WORKER_THREADS, "SQLITE_MAX_WORKER_THREADS" },
+ { SQLITE_LIMIT_PARSER_DEPTH, "SQLITE_MAX_PARSER_DEPTH" },
+ { SQLITE_LIMIT_SCHEMA, "SQLITE_MAX_SCHEMA" },
};
static int maxLimit(sqlite3 *db, int eCode){
SQLITE_MAX_MMAP_SIZE_
SQLITE_MAX_PAGE_COUNT
SQLITE_MAX_PAGE_SIZE
+ SQLITE_MAX_SCHEMA
SQLITE_MAX_SCHEMA_RETRY
SQLITE_MAX_SQL_LENGTH
SQLITE_MAX_TRIGGER_DEPTH