diff --git a/README.md b/README.md index 56a6937eca..0e60376bab 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,29 @@ If you pulled your SQLite source code from a secondary source and want to verify its integrity, there are hints on how to do that in the [Verifying Code Authenticity](#vauth) section below. -## Obtaining The Code +## Contacting The SQLite Developers + +The preferred way to ask questions or make comments about SQLite or to +report bugs against SQLite is to visit the +[SQLite Forum](https://sqlite.org/forum) at . +Anonymous postings are permitted. + +If you think you have found a bug that has security implications and +you do not want to report it on the public forum, you can send a private +email to drh at sqlite dot org. + +## Public Domain + +The SQLite source code is in the public domain. See + for details. + +Because SQLite is in the public domain, +we cannot accept pull requests, because +if we did accept a pull request, the changes in that pull request would +carry a copyright and the SQLite source code would no longer be fully in +the public domain. + +## Obtaining The SQLite Source Code If you do not want to use Fossil, you can download tarballs or ZIP archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows: @@ -290,16 +312,13 @@ Key files: is not part of the core SQLite library. But as most of the tests in this repository are written in Tcl, the Tcl language bindings are important. - * **test*.c** - Files in the src/ folder that begin with "test" go into + * **test\*.c** - Files in the src/ folder that begin with "test" go into building the "testfixture.exe" program. The testfixture.exe program is an enhanced Tcl shell. The testfixture.exe program runs scripts in the test/ folder to validate the core SQLite code. The testfixture program (and some other test programs too) is built and run when you type "make test". - * **ext/misc/json1.c** - This file implements the various JSON functions - that are built into SQLite. - There are many other source files. Each has a succinct header comment that describes its purpose and role within the larger system. @@ -334,7 +353,7 @@ hidden by also modifying the makefiles. ## Contacts -The main SQLite website is [http://www.sqlite.org/](http://www.sqlite.org/) +The main SQLite website is [http:/sqlite.org/](http://sqlite.org/) with geographically distributed backups at [http://www2.sqlite.org/](http://www2.sqlite.org) and [http://www3.sqlite.org/](http://www3.sqlite.org). diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 393f8a8717..32b483b349 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -4347,6 +4347,7 @@ static int fts3IncrmergeLoad( for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ NodeReader reader; + memset(&reader, 0, sizeof(reader)); pNode = &pWriter->aNodeWriter[i]; if( pNode->block.a){ diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index d1b0474aae..7b9d21e87f 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4840,7 +4840,9 @@ static void fts5DoSecureDelete( iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); } iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); - if( nPrefix2>nPrefix ){ + if( nPrefix2>pSeg->term.n ){ + p->rc = FTS5_CORRUPT; + }else if( nPrefix2>nPrefix ){ memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); iOff += (nPrefix2-nPrefix); } diff --git a/ext/fts5/test/fts5corrupt7.test b/ext/fts5/test/fts5corrupt7.test index 75995a7c03..ae7f9da7d9 100644 --- a/ext/fts5/test/fts5corrupt7.test +++ b/ext/fts5/test/fts5corrupt7.test @@ -96,4 +96,33 @@ set r 137438953475 db close } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + BEGIN; + INSERT INTO t1 VALUES('abc'); + INSERT INTO t1 VALUES('b d d d'); + COMMIT; + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); +} + +execsql_pp { + SELECT id, quote(block) FROM t1_data +} + +do_execsql_test 2.1 { + SELECT quote(block) FROM t1_data WHERE id > 10; +} {X'0000001A04306162630102020101620202020101640206030303040806'} + +do_execsql_test 2.2 { + UPDATE t1_data SET + block=X'0000001A04306162630102025501620202020101640206030303040806' + WHERE id>10 +} + +do_catchsql_test 2.3 { + DELETE FROM t1 WHERE rowid = 1 +} {1 {database disk image is malformed}} + finish_test diff --git a/manifest b/manifest index 1454e69a07..464fb3e240 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Clear\sMSVC\swarnings\sand\sfix\sa\stypedef\sissue\swith\sMSVC\sbuild. -D 2023-06-16T19:45:55.241 +C Sync\sw/trunk. +D 2023-06-17T01:56:55.752 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in b8d4701121db4ac004a3c01a1f837b820d6f92f1e6f6558d03e44561d38607ca F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc b94ec2cced361312f4fac2567182d137572a6b99625216528e16b3d842c24726 -F README.md 6f942c2e542d53202dc75b114b0617e9e02f8a6a777508fc23c3d8297951c478 +F README.md 8ff80689b9cb9f6e9b842edf31a3358ff53bc538c351799e03dd3e5455e637e5 F VERSION c6366dc72582d3144ce87b013cc35fe48d62f6d07d5be0c9716ea33c862144aa F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -79,7 +79,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154 F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226 F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 33d2d0db4dd4e7a7a7e9a7f790414293277f9e7682a2fd9d61c713bfc37cd8b6 +F ext/fts3/fts3_write.c d28d9ef383ef848a7b77df4b9964abcc90d67a2b584120c0ad465972dce416e6 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674 @@ -95,7 +95,7 @@ F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b7292 F ext/fts5/fts5_config.c 051056a9052f5d3a4d1c695f996fd364f920e341f136c60ab2c04aa7e267113f F ext/fts5/fts5_expr.c 58fb8ceddfb1cefcd54510f9f2f33c220ef9d1b3fa77462111f5ae2a825ab7b1 F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982 -F ext/fts5/fts5_index.c b7c9d81b123f4fd6e21c6435540a6fa9fbb9d519ae2125d0eb251169bf2a8c14 +F ext/fts5/fts5_index.c fe98ebd8835760b9c787d20f6b50d648a761afd8e3b55780e718ee34c694743b F ext/fts5/fts5_main.c b4dba04a36aaf9b8e8cef0100b6dbb422cc74753eacc11d6401cac7a87c0f38d F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082 F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae @@ -141,7 +141,7 @@ F ext/fts5/test/fts5corrupt3.test 7da9895dafa404efd20728f66ff4b94399788bdc042c36 F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 F ext/fts5/test/fts5corrupt5.test eb6ba5ca28ef7c4c6b01e850d388cdb3dacc8c4c2f383f79d0a98128257742b4 F ext/fts5/test/fts5corrupt6.test bf8eeae07825b088b9665d9d8e4accbd8dc9bf3cb85b6c64cf6c9e18ccc420a4 -F ext/fts5/test/fts5corrupt7.test f3e68673af2514e31dd67a2ed163f7f597252ab683dec155b8db0cdc0b668342 +F ext/fts5/test/fts5corrupt7.test 80ad7f683a8bda2404731bb77e8c3dbbb620c1f6cc583cca8239f6accd6338c0 F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7 F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4 F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 @@ -572,34 +572,34 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 -F src/alter.c f1c686e7325a7449c5a0ebc16207186f52e1b6673da699392caa1de39f219511 -F src/analyze.c a1f3061af16c99f73aed0362160176c31a6452de1b02ada1d68f6839f2a37df0 +F src/alter.c 3ff8c2fca0c0636d43459154bb40d79c882df1b34df77f89c4ec47ab2e2389f5 +F src/analyze.c d4cc28738c29e009640ec20ebb6936ba6fcefff0d11aa93398d9bb9a5ead6c1f F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645 F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 -F src/btree.c 030e6b7b6c3d6241a23a7e62200653cfabdfc08782f9d0d781c29a372efb8d64 +F src/btree.c 481666a3dd26b1cb16a9e9baaa3f6b17cab52a1d7a5836e5dcf5b45b85d4a51d F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc F src/btreeInt.h 3b4eff7155c0cea6971dc51f62e3529934a15a6640ec607dd42a767e379cb3a9 F src/build.c cb54df6fd018a18e940a251c5e31780ffba8bc6c7a01e670b96a489adcbfb3b4 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 6e9549239d08957ffeff481bb131d071c969833b230d1dbfb836cf9dab1501b8 +F src/date.c 36dfd2525c5544dbb246084e93839b839366e2204e7fb4a1a68a50f4344d32bc F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef -F src/delete.c 1b00589aa4f2c50beba39f9da5166fc2161234580ea8c0d087b6d5c2c7a17c21 -F src/expr.c b7dabf7f5ab42ed0b70437e9725aea25700eaff8a268cc42d682b1d67bb797f8 +F src/delete.c 092d745aa08969204a351711193e7f34de449ea57755eacbd11f1c316e9f7673 +F src/expr.c 36f6a47c8a2c20ec3c267a60fc598857876edd60af0cb40caf7b69b651fd73bf F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83 +F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36 F src/func.c 6303e1ccb80dbd0d9b52f902a01d3b105981486fdfd66f9e1ddfd74aaf3032fc F src/global.c bd0892ade7289f6e20bff44c07d06371f2ff9b53cea359e7854b9b72f65adc30 F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c a38bbb944a4f2771d70140db9c5d57e36c37e28d5a366497b4f93272a6d2567e +F src/insert.c 58dac6cdb9a0b614ef22ddb6207d6cc480cf0de96b9f326efb51070017d40293 F src/json.c 14c474fb1249a46eb44e878e2361f36abfe686b134039b0d1883d93d61505b4a F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465 @@ -626,11 +626,11 @@ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 F src/os_unix.c 95b407307deb902a3bd9a5d5666c7838709cccb337baeee6ef0a53f512d3673e -F src/os_win.c 79ff2345aafe92be324e8d9062050c6c5ae714c2db6b4b5334d7d28e70ea81e6 +F src/os_win.c 7038223a1cda0a47e2ab4db47f63bf1833fe53ba0542f0f283a062ea13894103 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 0dfe6a9c76ca8ad8eb91a3867dd20ba1f5c854bc5e9cd9cde62112bdee1822be +F src/pager.c 5ddf3a74c633a008ea6b2f5b3186167e88e2c8ca8a252ecab06ab3f1eb48e60f F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y 396bdbaa15c3a9b2e7ea693e2db19cab6c7bd4bdb64573b471f7ef0bdbbb5584 +F src/parse.y 8828f9e15f04d469eab9c0f2aed504e534b1c97c68836bed6f07afab29c2ac0b F src/pcache.c 4cd4a0043167da9ba7e19b4d179a0e6354e7fe32c16f781ecf9bf0a5ff63b40b F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 @@ -643,13 +643,13 @@ F src/resmanage.c b85f77821ea0280c73a6afc1dc3b6884ba3a402515c6bf27ba1567408e4f12 F src/resmanage.h eb63130e49d7b696a33c6d39d1c437a050bbef42b4f6f4405a15fc563c7dd61e F src/resolve.c c1457b920aeb33ed106bf478fad31b7473a8950a755ea898980c428928f3a514 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 1ddfe4450101c3d4890ecb2d6b97ab80b78764d5a3e7022b171721df1620c419 +F src/select.c 383b9dba12493c365ee2036bcadd73013b7c0f7d2afcda0c378317c335d60ac2 F src/shell.c.in b0cbd5996efa136f5b49f02d9076564866e2486b0c9625df1189111d5bbe4573 F src/shext_linkage.h 4a686427844d5d2b71f2095cb032280fb262490795f0710487ebbedb3732f1cb F src/sqlite.h.in 3076d78836b6dac53b3ab0875fc8fd15bca8077aad4d33c85336e05af6aef8c7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h 924ddd5bd9dad8a499005c2c02a492c67dbe784feafbd78fdd70d712cf839499 +F src/sqliteInt.h 51409a4f9456865fe7b15a9c0563bcf193d52f8a1c4f7a951ee988160ed2654f F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -711,18 +711,18 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b F src/treeview.c 1d52fbc4e97161e65858d36e3424ea6e3fc045dd8a679c82b4b9593dc30de3bd F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0 -F src/update.c 9fa127b8f13d39440996fdfa2323eeb1b565aba7b09ef820114ad2e77c25bdf1 +F src/update.c cff5ce391a6ffb2125ed7b5d44f3ce1f16af87ad8b9cee1c62bad1ee87d496ed F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 6f9d2f278dcc8d41c618980cd3cfe88e1bafc0626209b917c6773d8202d29ef6 F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 -F src/vdbe.c c3b6d8d60f2bb89ae771326f48945b8549f68c8f9a573e026b77b444f3d7d32e +F src/vdbe.c 6c0de640ef3be08cf2992d588a7501aee0f1003027bc952a6916a35f6e33b4cf F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0 F src/vdbeInt.h 7bd49eef8f89c1a271fbf12d80a206bf56c876814c5fc6bee340f4e1907095ae F src/vdbeapi.c de9703f8705afc393cc2864669ce28cf9516983c8331d59aa2b978de01634365 -F src/vdbeaux.c 5a0950d8ebdfc948a016c2bc790e9c45f03c0f8db30cf8f2be011fe5e8a28899 +F src/vdbeaux.c 85627cd1d2fb6e069567128001b55824a170efbc30c2fb1b85261ac30d001b38 F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce -F src/vdbemem.c 1cac4028c0dabbf1f3259f107440e2780e05ac9fe419e9709e6eb4e166ba714b +F src/vdbemem.c 710119a8e35e47813681c48703d65a80ba22792192de90bc51dc0d6366f2a79e F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac @@ -734,7 +734,7 @@ F src/walker.c 1f1c4743e064873efff71509d8839d9f7509b8960699aa2eeb906dec41a0f667 F src/where.c 94c90f838057e8f1ac6ab6e4caf64bbf487f4d0d33e64643731ff99e80a50b54 F src/whereInt.h c7d19902863beadec1d04e66aca39c0bcd60b74f05f0eaa7422c7005dfc5d51a F src/wherecode.c bff0bc56cb1a382de266c2db3a691135c18a4360b6ad5e069e5c415d57eb0c38 -F src/whereexpr.c f0a29594a2c143e10af7adf513b32d11223d76c6981c7f428433ec1ccbc33f84 +F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00 F src/window.c b7ad9cff3ce8ae6f8cc25e18e1a258426cb6bd2999aace6f5248d781b2a74098 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -765,7 +765,7 @@ F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5 F test/altertab3.test 6c432fbb9963e0bd6549bf1422f6861d744ee5a80cb3298564e81e556481df16 F test/altertrig.test fb5951d21a2c954be3b8a8cf8e10b5c0fa20687c53fd67d63cea88d08dd058d5 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f -F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 +F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b F test/analyze3.test 03f4b3d794760cf15da2d85a52df9bae300e51c8fefe9c36cfae1f86dc10d23f F test/analyze4.test 68bd069f3ac7ac1e652ddd9f04f57d5606ddb4208450f5297005db7aa0dd707d F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d @@ -1131,7 +1131,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 0d90cee9fd7ebecdfbdbe5bdc6fad92fa32410c48ccad747cd9e0ac603b9130c +F test/fuzzcheck.c 29a2f0237553375498f891c9487a2ef3267b47deecc5d5b4335fa37f904cb8d3 F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517 F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1241,7 +1241,7 @@ F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952 F test/json501.test f71710f60fa45b19dc336fbaac9e8362f70f80cf81badefdb845ed3f7c7c2ccc F test/json502.test 98c38e3c4573841028a1381dfb81d4c3f9b105d39668167da10d055e503f6d0b F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b +F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 @@ -1582,7 +1582,7 @@ F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b4 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 -F test/timediff1.test 635b0e1857d1a3519382ae1a0aff9580c33e550c5a5cbec600b5edd2e0487018 +F test/timediff1.test d982b2b5f1b22f58380c5db94ea5b17518d50ad0c55583cf0ecfa0b176e20888 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 @@ -2052,8 +2052,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1073ef0629921dbb74719045a742d68d2bb4e28fc5fa6463e725ddd1d9e6e651 -R 92ba1ad3a67160bddd0ea15761c50c4b +P b0cb4cfceaa45c31c217e8e0edf4b1431f5e1bd05f85d49528792d69bdbdd6dc 365caf2f97e8f15842f52536e8d05d359e9d6e863182e020ce14a9a9f27ee057 +R f7e4b86dfb1aed4513de35498c9dac88 U larrybr -Z 45983338d46924a7b0c84861d7e1a312 +Z b071645d2d583c5fbb5c87c4a4c85152 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b73491bc15..93bfaa7f8b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0cb4cfceaa45c31c217e8e0edf4b1431f5e1bd05f85d49528792d69bdbdd6dc \ No newline at end of file +746733c1c5905ec8c372eaf0dd720b7efac63e1102f0c63812a2bc3bb4ed6dc3 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 6a3ab81892..d0b1f7f696 100644 --- a/src/alter.c +++ b/src/alter.c @@ -542,7 +542,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); pNew->pSchema = db->aDb[iDb].pSchema; pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; - pNew->nTabRef = 1; + assert( pNew->nTabRef==1 ); exit_begin_add_column: sqlite3SrcListDelete(db, pSrc); diff --git a/src/analyze.c b/src/analyze.c index 0823bcaefc..a7a8b6d665 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1849,14 +1849,15 @@ static int loadStatTbl( decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); - /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. + /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. ** This is in case the sample record is corrupted. In that case, the ** sqlite3VdbeRecordCompare() may read up to two varints past the ** end of the allocated buffer before it realizes it is dealing with - ** a corrupt record. Adding the two 0x00 bytes prevents this from causing + ** a corrupt record. Or it might try to read a large integer from the + ** buffer. In any case, eight 0x00 bytes prevents this from causing ** a buffer overread. */ pSample->n = sqlite3_column_bytes(pStmt, 4); - pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 8); if( pSample->p==0 ){ sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; diff --git a/src/btree.c b/src/btree.c index 9d6bdf2e5b..7f79327324 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1635,7 +1635,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ iCellStart = get2byte(&data[hdr+5]); if( nCell>0 ){ temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); + memcpy(temp, data, usableSize); src = temp; for(i=0; ibtsFlags |= BTS_PAGESIZE_FIXED; assert( (pageSize & 7)==0 ); /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte ** integer at offset 20 is the number of bytes of space at the end of @@ -3359,6 +3361,7 @@ static int lockBtree(BtShared *pBt){ releasePageOne(pPage1); pBt->usableSize = usableSize; pBt->pageSize = pageSize; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; freeTempSpace(pBt); rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, pageSize-usableSize); @@ -3378,6 +3381,7 @@ static int lockBtree(BtShared *pBt){ if( usableSize<480 ){ goto page1_init_failed; } + pBt->btsFlags |= BTS_PAGESIZE_FIXED; pBt->pageSize = pageSize; pBt->usableSize = usableSize; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -7486,7 +7490,7 @@ static int rebuildPage( if( NEVER(j>(u32)usableSize) ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); - for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kixNx[k]<=i; k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; @@ -7569,7 +7573,7 @@ static int pageInsertArray( u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; - for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kixNx[k]<=i ; k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; @@ -8679,7 +8683,7 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; b.ixNx[k]<=j && ALWAYS(k=0 && iPg=1 || i>=0 ); + assert( iPg=0 /* On the upwards pass, or... */ || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ diff --git a/src/date.c b/src/date.c index b56df143dc..d01cf12a85 100644 --- a/src/date.c +++ b/src/date.c @@ -110,8 +110,8 @@ struct DateTime { */ static int getDigits(const char *zDate, const char *zFormat, ...){ /* The aMx[] array translates the 3rd character of each format - ** spec into a max size: a b c d e f */ - static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; + ** spec into a max size: a b c d e f */ + static const u16 aMx[] = { 12, 14, 24, 31, 59, 14712 }; va_list ap; int cnt = 0; char nextC; @@ -448,6 +448,32 @@ static void computeYMD(DateTime *p){ p->validYMD = 1; } +/* GCC (and sometimes Clang too) will sometimes be off by 1 millisecond +** in computeHMS() on 32-bit platforms with optimization enabled. +** I don't know if this is a compiler bug or a bug in the code. It is hard +** to debug because with optimization enabled, gdb skips around so much +** you cannot see what is happening, and if you try adding debug printf()s +** to the code, the problem goes away. +** +** For now, I will work around the problem by disabling optimizations in +** the computeHMS() routine. +** +** Problem seen using gcc-5.4.0, gcc-9.4.0, clang-10. Works ok on +** MSVC, clang-3.4, and clang-6.0. +** +** Whatever the problem is, it causes some answers to be off by one +** millisecond. So we get results like "2021-03-05 03:04:05.599" instead +** of the desired result of "2021-03-05 03:04:05.600". +** +** To reproduce the problem using TH3: +** +** ./th3make debug.rc -O1 -m32 cfg/c1.cfg cov1/date8.test +*/ +#if SQLITE_PTRSIZE==4 && GCC_VERSION>0 +#pragma GCC push_options +#pragma GCC optimize ("O0") +#endif + /* ** Compute the Hour, Minute, and Seconds from the julian day number. */ @@ -467,6 +493,11 @@ static void computeHMS(DateTime *p){ p->validHMS = 1; } +/* Reactivate GCC optimization */ +#if SQLITE_PTRSIZE==4 && GCC_VERSION>0 +#pragma GCC pop_options +#endif + /* ** Compute both YMD and HMS */ @@ -872,13 +903,17 @@ static int parseModifier( int i; int Y,M,D,h,m,x; const char *z2 = z; + char z0 = z[0]; for(n=1; z[n]; n++){ if( z[n]==':' ) break; if( sqlite3Isspace(z[n]) ) break; - if( z[n]=='-' && n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; + if( z[n]=='-' ){ + if( n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; + if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; + } } if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ - rc = 1; + assert( rc==1 ); break; } if( z[n]=='-' ){ @@ -886,14 +921,19 @@ static int parseModifier( ** specified number of years, months, and days. MM is limited to ** the range 0-11 and DD is limited to 0-30. */ - if( z[0]!='+' && z[0]!='-' ) break; /* Must start with +/- */ - if( NEVER(n!=5) ) break; /* Must be 4-digit YYYY */ - if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; + if( z0!='+' && z0!='-' ) break; /* Must start with +/- */ + if( n==5 ){ + if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; + }else{ + assert( n==6 ); + if( getDigits(&z[1], "50f-20a-20d", &Y, &M, &D)!=3 ) break; + z++; + } if( M>=12 ) break; /* M range 0..11 */ if( D>=31 ) break; /* D range 0..30 */ computeYMD_HMS(p); p->validJD = 0; - if( z[0]=='-' ){ + if( z0=='-' ){ p->Y -= Y; p->M -= M; D = -D; @@ -937,7 +977,7 @@ static int parseModifier( tx.iJD -= 43200000; day = tx.iJD/86400000; tx.iJD -= day*86400000; - if( z[0]=='-' ) tx.iJD = -tx.iJD; + if( z0=='-' ) tx.iJD = -tx.iJD; computeJD(p); clearYMD_HMS_TZ(p); p->iJD += tx.iJD; @@ -953,7 +993,7 @@ static int parseModifier( if( n>10 || n<3 ) break; if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); - rc = 1; + assert( rc==1 ); rRounder = r<0 ? -0.5 : +0.5; for(i=0; id2.iJD ){ + while( d1.iJD>d2.iJD ){ M--; if( M<0 ){ M = 11; diff --git a/src/delete.c b/src/delete.c index e231a327c0..374121a7a7 100644 --- a/src/delete.c +++ b/src/delete.c @@ -497,7 +497,7 @@ void sqlite3DeleteFrom( if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ pPk = 0; - nPk = 1; + assert( nPk==1 ); iRowSet = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); }else{ diff --git a/src/expr.c b/src/expr.c index 795f650524..b0fe32a7eb 100644 --- a/src/expr.c +++ b/src/expr.c @@ -890,6 +890,15 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ #define exprSetHeight(y) #endif /* SQLITE_MAX_EXPR_DEPTH>0 */ +/* +** Set the error offset for an Expr node, if possible. +*/ +void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ + if( pExpr==0 ) return; + if( NEVER(ExprUseWJoin(pExpr)) ) return; + pExpr->w.iOfst = iOfst; +} + /* ** This routine is the core allocator for Expr nodes. ** @@ -4633,7 +4642,7 @@ expr_code_doover: sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); break; } - if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); return exprCodeInlineFunction(pParse, pFarg, diff --git a/src/fkey.c b/src/fkey.c index 29609916b6..3142e0ca68 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1448,9 +1448,8 @@ void sqlite3FkDelete(sqlite3 *db, Table *pTab){ if( pFKey->pPrevTo ){ pFKey->pPrevTo->pNextTo = pFKey->pNextTo; }else{ - void *p = (void *)pFKey->pNextTo; - const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); - sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); + const char *z = (pFKey->pNextTo ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, pFKey->pNextTo); } if( pFKey->pNextTo ){ pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; diff --git a/src/insert.c b/src/insert.c index b9bfb1fed2..58840bf4c9 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2658,6 +2658,8 @@ int sqlite3OpenTableAndIndices( assert( op==OP_OpenRead || op==OP_OpenWrite ); assert( op==OP_OpenWrite || p5==0 ); + assert( piDataCur!=0 ); + assert( piIdxCur!=0 ); if( IsVirtual(pTab) ){ /* This routine is a no-op for virtual tables. Leave the output ** variables *piDataCur and *piIdxCur set to illegal cursor numbers @@ -2670,18 +2672,18 @@ int sqlite3OpenTableAndIndices( assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; iDataCur = iBase++; - if( piDataCur ) *piDataCur = iDataCur; + *piDataCur = iDataCur; if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } - if( piIdxCur ) *piIdxCur = iBase; + *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - if( piDataCur ) *piDataCur = iIdxCur; + *piDataCur = iIdxCur; p5 = 0; } if( aToOpen==0 || aToOpen[i+1] ){ diff --git a/src/os_win.c b/src/os_win.c index 069cfc18ee..73a2f946d8 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3343,7 +3343,7 @@ static int winLock(sqlite3_file *id, int locktype){ */ if( locktype==EXCLUSIVE_LOCK && res ){ assert( pFile->locktype>=SHARED_LOCK ); - res = winUnlockReadLock(pFile); + (void)winUnlockReadLock(pFile); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ diff --git a/src/pager.c b/src/pager.c index d8819c89e8..7f2cb5ba76 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4679,11 +4679,7 @@ int sqlite3PagerOpen( int rc = SQLITE_OK; /* Return code */ int tempFile = 0; /* True for temp files (incl. in-memory files) */ int memDb = 0; /* True if this is an in-memory file */ -#ifndef SQLITE_OMIT_DESERIALIZE int memJM = 0; /* Memory journal mode */ -#else -# define memJM 0 -#endif int readOnly = 0; /* True if this is a read-only file */ int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ @@ -4802,12 +4798,13 @@ int sqlite3PagerOpen( ** specific formatting and order of the various filenames, so if the format ** changes here, be sure to change it there as well. */ + assert( SQLITE_PTRSIZE==sizeof(Pager*) ); pPtr = (u8 *)sqlite3MallocZero( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ - sizeof(pPager) + /* Space to hold a pointer */ + SQLITE_PTRSIZE + /* Space to hold a pointer */ 4 + /* Database prefix */ nPathname + 1 + /* database filename */ nUriByte + /* query parameters */ @@ -4828,7 +4825,7 @@ int sqlite3PagerOpen( pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); - memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); + memcpy(pPtr, &pPager, SQLITE_PTRSIZE); pPtr += SQLITE_PTRSIZE; /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ pPtr += 4; /* Skip zero prefix */ @@ -4882,9 +4879,7 @@ int sqlite3PagerOpen( int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); -#ifndef SQLITE_OMIT_DESERIALIZE pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; -#endif readOnly = (fout&SQLITE_OPEN_READONLY)!=0; /* If the file was successfully opened for read/write access, diff --git a/src/parse.y b/src/parse.y index 4dc064252e..6085c4bbe2 100644 --- a/src/parse.y +++ b/src/parse.y @@ -554,12 +554,11 @@ select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);} %endif /* SQLITE_OMIT_CTE */ -select(A) ::= selectnowith(X). { - Select *p = X; +select(A) ::= selectnowith(A). { + Select *p = A; if( p ){ parserDoubleLinkSelect(pParse, p); } - A = p; /*A-overwrites-X*/ } selectnowith(A) ::= oneselect(A). @@ -655,14 +654,17 @@ selcollist(A) ::= sclp(A) scanpt(B) expr(X) scanpt(Z) as(Y). { if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1); sqlite3ExprListSetSpan(pParse,A,B,Z); } -selcollist(A) ::= sclp(A) scanpt STAR. { +selcollist(A) ::= sclp(A) scanpt STAR(X). { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); + sqlite3ExprSetErrorOffset(p, (int)(X.z - pParse->zTail)); A = sqlite3ExprListAppend(pParse, A, p); } -selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. { - Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - Expr *pLeft = tokenExpr(pParse, TK_ID, X); - Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); +selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR(Y). { + Expr *pRight, *pLeft, *pDot; + pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + sqlite3ExprSetErrorOffset(pRight, (int)(Y.z - pParse->zTail)); + pLeft = tokenExpr(pParse, TK_ID, X); + pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); A = sqlite3ExprListAppend(pParse,A, pDot); } @@ -1758,7 +1760,7 @@ wqlist(A) ::= wqlist(A) COMMA wqitem(X). { %ifndef SQLITE_OMIT_WINDOWFUNC %type windowdefn_list {Window*} %destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);} -windowdefn_list(A) ::= windowdefn(Z). { A = Z; } +windowdefn_list(A) ::= windowdefn(A). windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). { assert( Z!=0 ); sqlite3WindowChain(pParse, Z, Y); @@ -1814,9 +1816,7 @@ window(A) ::= ORDER BY sortlist(Y) frame_opt(Z). { window(A) ::= nm(W) ORDER BY sortlist(Y) frame_opt(Z). { A = sqlite3WindowAssemble(pParse, Z, 0, Y, &W); } -window(A) ::= frame_opt(Z). { - A = Z; -} +window(A) ::= frame_opt(A). window(A) ::= nm(W) frame_opt(Z). { A = sqlite3WindowAssemble(pParse, Z, 0, 0, &W); } diff --git a/src/select.c b/src/select.c index b492d5374d..71610484b1 100644 --- a/src/select.c +++ b/src/select.c @@ -6108,10 +6108,16 @@ static int selectExpander(Walker *pWalker, Select *p){ ** expanded. */ int tableSeen = 0; /* Set to 1 when TABLE matches */ char *zTName = 0; /* text of name of TABLE */ + int iErrOfst; if( pE->op==TK_DOT ){ assert( pE->pLeft!=0 ); assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); zTName = pE->pLeft->u.zToken; + assert( ExprUseWOfst(pE->pLeft) ); + iErrOfst = pE->pRight->w.iOfst; + }else{ + assert( ExprUseWOfst(pE) ); + iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; /* Table for this data source */ @@ -6148,6 +6154,7 @@ static int selectExpander(Walker *pWalker, Select *p){ for(ii=0; iinId; ii++){ const char *zUName = pUsing->a[ii].zName; pRight = sqlite3Expr(db, TK_ID, zUName); + sqlite3ExprSetErrorOffset(pRight, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pRight); if( pNew ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; @@ -6220,6 +6227,7 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ pExpr = pRight; } + sqlite3ExprSetErrorOffset(pExpr, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); if( pNew==0 ){ break; /* OOM */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d4e255ea21..4009d4f8d5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3023,6 +3023,8 @@ struct Expr { */ #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) +#define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0) +#define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0) #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) @@ -5491,6 +5493,7 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); #define sqlite3SelectExprHeight(x) 0 #define sqlite3ExprCheckHeight(x,y) #endif +void sqlite3ExprSetErrorOffset(Expr*,int); u32 sqlite3Get4byte(const u8*); void sqlite3Put4byte(u8*, u32); diff --git a/src/update.c b/src/update.c index dfe68c074b..b7bf807766 100644 --- a/src/update.c +++ b/src/update.c @@ -813,6 +813,8 @@ void sqlite3Update( if( !isView ){ int addrOnce = 0; + int iNotUsed1 = 0; + int iNotUsed2 = 0; /* Open every index that needs updating. */ if( eOnePass!=ONEPASS_OFF ){ @@ -824,7 +826,7 @@ void sqlite3Update( addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, - aToOpen, 0, 0); + aToOpen, &iNotUsed1, &iNotUsed2); if( addrOnce ){ sqlite3VdbeJumpHereOrPopInst(v, addrOnce); } diff --git a/src/vdbe.c b/src/vdbe.c index ebdd28ba91..7045a1e4bd 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -8509,7 +8509,7 @@ case OP_FilterAdd: { printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); } #endif - h %= pIn1->n; + h %= (pIn1->n*8); pIn1->z[h/8] |= 1<<(h&7); break; } @@ -8545,7 +8545,7 @@ case OP_Filter: { /* jump */ printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); } #endif - h %= pIn1->n; + h %= (pIn1->n*8); if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ VdbeBranchTaken(1, 2); p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 57cc2a483e..8034519f98 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4231,6 +4231,15 @@ static int vdbeRecordCompareDebug( if( d1+(u64)serial_type1+2>(u64)nKey1 && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 ){ + if( serial_type1>=1 + && serial_type1<=7 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)<=(u64)nKey1+8 + && CORRUPT_DB + ){ + return 1; /* corrupt record not detected by + ** sqlite3VdbeRecordCompareWithSkip(). Return true + ** to avoid firing the assert() */ + } break; } diff --git a/src/vdbemem.c b/src/vdbemem.c index d3cd55ba9f..60bd6d6db2 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1431,6 +1431,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ } pRec->nField = p->iVal+1; + sqlite3VdbeMemSetNull(&pRec->aMem[p->iVal]); return &pRec->aMem[p->iVal]; } #else diff --git a/src/whereexpr.c b/src/whereexpr.c index 1355e9e853..daf3d5d950 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -229,7 +229,7 @@ static int isLikeOrGlob( ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ - if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ diff --git a/test/analyze.test b/test/analyze.test index ca6c9b096d..f97c78aff1 100644 --- a/test/analyze.test +++ b/test/analyze.test @@ -377,4 +377,23 @@ do_execsql_test analyze-6.1 { SELECT tbl FROM sqlite_stat1 WHERE idx IS NULL ORDER BY tbl; } {SQLiteDemo2 sqliteDemo t1} +# The following caused a small buffer overread in STAT4 processing prior +# to check-in [b99135288b157044]. +# +ifcapable stat4 { + reset_db + database_may_be_corrupt + do_execsql_test analyze-7.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t1 VALUES(1, 7223372036854775); + INSERT INTO t1 VALUES(2, 7223372036854776); + INSERT INTO t1 VALUES(3, 7223372036854777); + CREATE INDEX i1 ON t1(b); + ANALYZE; + UPDATE sqlite_stat4 SET sample = substr(sample, 0, 4); + ANALYZE sqlite_schema; + SELECT * FROM t1 WHERE b>7223372036854775 + } {2 7223372036854776 3 7223372036854777} +} + finish_test diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 59bddc96a8..76ce5af0ec 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -1130,6 +1130,44 @@ static int runDbSql(sqlite3 *db, const char *zSql, unsigned int *pBtsFlags){ return sqlite3_finalize(pStmt); } +/* Mappings into dbconfig settings for bits taken from bytes 72..75 of +** the input database. +** +** This should be the same as in dbsqlfuzz.c. Make sure those codes stay +** in sync. +*/ +static const struct { + unsigned int mask; + int iSetting; + char *zName; +} aDbConfigSettings[] = { + { 0x0001, SQLITE_DBCONFIG_ENABLE_FKEY, "enable_fkey" }, + { 0x0002, SQLITE_DBCONFIG_ENABLE_TRIGGER, "enable_trigger" }, + { 0x0004, SQLITE_DBCONFIG_ENABLE_VIEW, "enable_view" }, + { 0x0008, SQLITE_DBCONFIG_ENABLE_QPSG, "enable_qpsg" }, + { 0x0010, SQLITE_DBCONFIG_TRIGGER_EQP, "trigger_eqp" }, + { 0x0020, SQLITE_DBCONFIG_DEFENSIVE, "defensive" }, + { 0x0040, SQLITE_DBCONFIG_WRITABLE_SCHEMA, "writable_schema" }, + { 0x0080, SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, "legacy_alter_table" }, + { 0x0100, SQLITE_DBCONFIG_STMT_SCANSTATUS, "stmt_scanstatus" }, + { 0x0200, SQLITE_DBCONFIG_REVERSE_SCANORDER, "reverse_scanorder" }, +#ifdef SQLITE_DBCONFIG_STRICT_AGGREGATE + { 0x0400, SQLITE_DBCONFIG_STRICT_AGGREGATE, "strict_aggregate" }, +#endif + { 0x0800, SQLITE_DBCONFIG_DQS_DML, "dqs_dml" }, + { 0x1000, SQLITE_DBCONFIG_DQS_DDL, "dqs_ddl" }, + { 0x2000, SQLITE_DBCONFIG_TRUSTED_SCHEMA, "trusted_schema" }, +}; + +/* Toggle a dbconfig setting +*/ +static void toggleDbConfig(sqlite3 *db, int iSetting){ + int v = 0; + sqlite3_db_config(db, iSetting, -1, &v); + v = !v; + sqlite3_db_config(db, iSetting, v, 0); +} + /* Invoke this routine to run a single test case */ int runCombinedDbSqlInput( const uint8_t *aData, /* Combined DB+SQL content */ @@ -1148,6 +1186,9 @@ int runCombinedDbSqlInput( int nSql; /* Bytes of SQL text */ FuzzCtx cx; /* Fuzzing context */ unsigned int btsFlags = 0; /* Parsing flags */ + unsigned int dbFlags = 0; /* Flag values from db offset 72..75 */ + unsigned int dbOpt = 0; /* Flag values from db offset 76..79 */ + if( nByte<10 ) return 0; if( sqlite3_initialize() ) return 0; @@ -1163,6 +1204,12 @@ int runCombinedDbSqlInput( memset(&cx, 0, sizeof(cx)); iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb); if( iSql<0 ) return 0; + if( nDb>=75 ){ + dbFlags = (aDb[72]<<24) + (aDb[73]<<16) + (aDb[74]<<8) + aDb[75]; + } + if( nDb>=79 ){ + dbOpt = (aDb[76]<<24) + (aDb[77]<<16) + (aDb[78]<<8) + aDb[79]; + } nSql = (int)(nByte - iSql); if( bScript ){ char zName[100]; @@ -1183,7 +1230,12 @@ int runCombinedDbSqlInput( sqlite3_free(aDb); return 1; } - sqlite3_db_config(cx.db, SQLITE_DBCONFIG_STMT_SCANSTATUS, 1, 0); + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, cx.db, dbOpt); + for(i=0; i