-C Avoid\strying\sto\sdelete\sa\sdatabase\sfile\swhile\sit\sis\sstill\sopen\sin\sbackup5.test.
-D 2026-06-24T14:17:52.488
+C When\srolling\sback\sa\sjournal\sthat\scontains\sa\ssuper-journal\spointer,\sonly\sattempt\sto\sunlink\sthe\ssuper-journal\sif\sthe\sfilename\slooks\slike\sone\sthat\sSQLite\smight\shave\sgenerated.\sThis\sis\sto\slimit\sthe\sextent\sto\swhich\sSQLite\scan\sbe\scaused\sto\sdelete\sarbitrary\sfiles\sby\ssupplying\sit\swith\sa\scrafted\shot-journal.\s\sBug\s[bugs:/info/2026-06-24T14:18:00Z\s|\s2026-06-24T14:18:00Z].
+D 2026-06-24T17:14:57.054
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/os_unix.c 83759942d1ea8d59daed50901c123016f845fada74caf3496b8a2537c9a08838
F src/os_win.c 1227a3e962b017d676d985a8aec0d64f273991931ea0a0b99773651102f62df4
F src/os_win.h c06ccc3a090cf54202ea58981c298817f3309d4c9e4d52ad0a02927346493721
-F src/pager.c f88073a00933c885b167b6d25afc4d1b83c1706943572f5653fb64a7f5bde105
+F src/pager.c a2b8fa68af33b9942603e5d81fddd3a14b349eee7ef01938748855cb438ec312
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
F src/parse.y d5a3c5b0277a441c38b35071c05e2b61ff5fc918a63309c809f4b6706179c320
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F test/misc7.test d595599972ec0b436985f0f02f243b68500ffc977b9b3194ec66c0866cfddcab
F test/misc8.test 08d2380bc435486b12161521f225043ac2be26f02471c2c1ea4cac0b1548edbd
F test/misuse.test 859f37014d9824ca66bd90c36372c08c80c51c9593a7cfa8a31d4f92cd4d5b7f
-F test/mjournal.test 3570ca4241b0d19ca1f47616f5293722f7c2fc9f2d359fc7933d67ef51dc2137
+F test/mjournal.test 39677dd63cacb12aaf62173ef4ab0e9b7af3cdabdeb0ea335d17d1f22c4bb84b
F test/mmap1.test 18de3fd7b70a777af6004ca2feecfcdd3d0be17fa04058e808baf530c94b1a1d
F test/mmap2.test dba452dc7db91e9df10f70bdd73dc4190c7b8ee7b5133b4684f04277ada0b9ac
F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigfault.tes fc5918e64f3867156fefe7cfca9d8e1f495134a5229b2b511b0dc11c07f2eab4
F test/temptrigger.test a00f258ed8d21a0e8fd4f322f15e8cfb5cef2e43655670e07a753e3fb4769d61
-F test/tester.tcl 2d943f60200e0a36bcd3f1f0baf181a751cd3604ef6b6bd4c8dc39b4e8a53116
+F test/tester.tcl dfd8dd05b54bc493a8db6cc1263ee364c36e3c27fab258dad7305cd79b948f3f
F test/testloadext.c 862b848783eaed9985fbce46c65cd214664376b549fae252b364d5d1ef350a27
F test/testrunner.tcl 8171b887ab78d55b73fd971e22690eff0fabec913fbf3b5fbeaf159b3f00b2dc x
F test/testrunner_data.tcl 4b3cf036d39c98b83f9289a5c047eb01089c932d4f59a81bf764f6800589b959
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 5482548b6bca2827246cd2cc928c89a953365da5ebe42d3a2876371ec6880f1b
-R b0d4c11e49460a97cc1177e498ab6558
+P 395cbed103af08e3a4fafd9a3041205535e019d4aeb58b46c4a7e4f3bca545c9
+R 73c1d4bd2cc78546d34368e3afe8224e
+T *branch * del-super-filter
+T *sym-del-super-filter *
+T -sym-trunk *
U dan
-Z d794be864d6f3f101d67593b1a8e2b43
+Z b9d7aa6744ea09c029dff1ca3aa0a964
# Remove this line to create a well-formed Fossil manifest.
-branch trunk
-tag trunk
+branch del-super-filter
+tag del-super-filter
-395cbed103af08e3a4fafd9a3041205535e019d4aeb58b46c4a7e4f3bca545c9
+0cdde6755837935e4feaa4367a0b107e363582adc8112a91dc7416f1100ae3aa
return rc;
}
+/*
+** Check if zSuper is a valid super-journal name. There are two valid
+** formats:
+**
+** + The 3rd and 4th last bytes of the filename are ".9", and the
+** following 2 bytes are hex digits. This is a file created in 8.3
+** filenames
+**
+** + The 3rd last byte of the filename is "9" and the filename
+** contains the string "-mj" starting at the 12th last byte.
+** All bytes following the "-mj" are hex digits.
+**
+** If the filename matches either of these patterns, return non-zero.
+** Otherwise, return zero.
+*/
+static int pagerIsSuperJrnlName(const char *zSuper){
+ const int nSuper = sqlite3Strlen30(zSuper);
+ int ii;
+
+ if( nSuper<4 ) return 0;
+ if( zSuper[nSuper-3]!='9' ) return 0;
+ if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0;
+ if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0;
+ if( zSuper[nSuper-4]=='.' ) return 1;
+ if( nSuper<12 ) return 0;
+ if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0;
+ for(ii=nSuper-9; ii<nSuper; ii++){
+ if( sqlite3Isxdigit(zSuper[ii])==0 ) return 0;
+ }
+ return 1;
+}
+
/*
** Parameter zSuper is the name of a super-journal file. A single journal
** file that referred to the super-journal file has just been rolled back.
char *zJournal; /* Pointer to one journal within MJ file */
char *zFree = 0; /* Free this buffer */
+ /* Check if this looks like a real super-journal name. If it does not,
+ ** return SQLITE_OK without attempting to delete it. This is to limit
+ ** the degree to which a crafted journal file can be used to cause
+ ** SQLite to delete arbitrary files. */
+ if( pagerIsSuperJrnlName(zSuper)==0 ){
+ return SQLITE_OK;
+ }
+
/* Allocate space for both the pJournal and pSuper file descriptors.
** If successful, open the super-journal file for reading.
*/
SELECT type, name, tbl_name, sql FROM sqlite_schema
} {table t1 t1 {CREATE TABLE t1(x, y)}}
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 4.0 {
+ CREATE TABLE t1(x INTEGER PRIMARY KEY);
+}
+db_save_and_close
+proc append_super_journal {jrnl mjname} {
+ binary scan $mjname c* bytes
+ set cksum 0
+ foreach b $bytes { incr cksum $b }
+ set fd [open $jrnl a+]
+ fconfigure $fd -translation binary -encoding iso8859-1
+ puts -nonewline $fd $mjname
+ puts -nonewline $fd [binary format I [string length $mjname]]
+ puts -nonewline $fd [binary format I $cksum]
+ puts -nonewline $fd [binary decode hex "d9d505f920a163d7"]
+ close $fd
+}
+
+foreach {tn mjname bDel} {
+ 1 notamasterjournal 0
+ 2 master.9FF 1
+ 3 master-mj1234569AA 1
+ 4 master-mj123456_AA 0
+ 5 abc 0
+ 6 masterr9FF 0
+ 7 master-fj123456_AA 0
+ 8 -mj1234569AA 1
+ 9 1-mj1234569AA 1
+ 10 .9AB 1
+ 11 master.9X2 0
+ 12 master.92X 0
+ 13 master-mj12G4569AA 0
+} {
+ db_restore_and_reopen
+ execsql {
+ PRAGMA synchronous = OFF;
+ BEGIN;
+ INSERT INTO t1 DEFAULT VALUES;
+ }
+
+ db_save_and_close
+ db_restore
+
+ append_super_journal test.db-journal $mjname
+ set fd [open $mjname w]
+ puts $fd "helloworld"
+ close $fd
+
+ sqlite3 db test.db
+ do_test 4.$tn.1 {
+ execsql { SELECT * FROM t1 }
+ file exists $mjname
+ } [expr !$bDel]
+ do_test 4.$tn.2 {
+ file exists test.db-journal
+ } {0}
+
+ forcedelete $mjname
+}
finish_test
+
+
for {set i 0} {$i<$nRetry} {incr i} {
set rc [catch {
if {$force} {
- file delete -force $filename
+ file delete -force -- $filename
} else {
- file delete $filename
+ file delete -- $filename
}
} msg]
if {$rc==0} break
if {$rc} { error $msg }
} else {
if {$force} {
- file delete -force $filename
+ file delete -force -- $filename
} else {
- file delete $filename
+ file delete -- $filename
}
}
}