]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Check super-journal names for validity earlier, as this simplifies master
authordrh <>
Thu, 25 Jun 2026 20:26:17 +0000 (20:26 +0000)
committerdrh <>
Thu, 25 Jun 2026 20:26:17 +0000 (20:26 +0000)
verification that the logic is correct.

FossilOrigin-Name: 6ba9e19430092aef59f2a7ab6fb7bdacacbb85988f41c155a5af490b0d8a8270

manifest
manifest.uuid
src/pager.c

index 5ad9f89b1a5c23dea4e3ca956af3cde39ebfef13..7f43d7568aefd334431aa5aed4ef8cae17a9ee7a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Have\sAPI\sfunctions\ssqlite3_serialize,\ssqlite3_limit,\ssqlite3_busy_timeout,\ssqlite3_error_offset,\ssqlite3_db_name,\ssqlite3_get_autocommit,\ssqlite3_errcode,\ssqlite3_total_changes64,\ssqlite3_changes64,\ssqlite3_last_insert_rowid\sand\ssqlite3_expired\stake\sand\shold\sthe\sdatabase\smutex\swhile\srunning.
-D 2026-06-25T17:07:53.090
+C Check\ssuper-journal\snames\sfor\svalidity\searlier,\sas\sthis\ssimplifies\nverification\sthat\sthe\slogic\sis\scorrect.
+D 2026-06-25T20:26:17.638
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -725,7 +725,7 @@ F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae
 F src/os_unix.c 83759942d1ea8d59daed50901c123016f845fada74caf3496b8a2537c9a08838
 F src/os_win.c 1227a3e962b017d676d985a8aec0d64f273991931ea0a0b99773651102f62df4
 F src/os_win.h c06ccc3a090cf54202ea58981c298817f3309d4c9e4d52ad0a02927346493721
-F src/pager.c 927713c6cc3033268f2c440f3ccc45081266fe956e018ce6c04092f1776215e7
+F src/pager.c 678ee3b68638ee427cc1b071b11181d0f2a827f6cb4d6ec7c12d5fa5f6a752d0
 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
 F src/parse.y d5a3c5b0277a441c38b35071c05e2b61ff5fc918a63309c809f4b6706179c320
 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
@@ -2208,9 +2208,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P c30ea3cefe346a3d87b57710a51b059371543c5abc75d08c4ca827bbe3b3f622 46509e48d3049a1ca52d9cc3f023634a651cd633d36bd9056ca0172759ba201e
-R bf72fafaea2070ac4d3be5ad21ee93ea
-T +closed 46509e48d3049a1ca52d9cc3f023634a651cd633d36bd9056ca0172759ba201e
-U dan
-Z 8ba48b9154271fe0d84b01609d2c1867
+P 7bfd5c810c6f04ddfd275457a2a03b4da0c3e7d4ee5acb61a54d805e2e67f819
+R fcb35e9d64943876915ecd53a38bf408
+U drh
+Z a532ffc4f25f92a370d40bff92615b32
 # Remove this line to create a well-formed Fossil manifest.
index 104584242f5165fd95e09c626c543735f5eb7e03..8b8644f0d33682360f28ecdc49e42bc852762654 100644 (file)
@@ -1 +1 @@
-7bfd5c810c6f04ddfd275457a2a03b4da0c3e7d4ee5acb61a54d805e2e67f819
+6ba9e19430092aef59f2a7ab6fb7bdacacbb85988f41c155a5af490b0d8a8270
index 53397037a3548e4799a472a883dba277b819dfb6..b52886e45e65f3526fd0006afc8a5ead1d22eacf 100644 (file)
@@ -1280,6 +1280,41 @@ static void freeSuperJournal(char *zSuper){
   }
 }
 
+/* 
+** 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 mode.
+**
+**   + 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;
+
+#ifdef SQLITE_ENABLE_8_3_NAMES
+  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;
+#endif
+  if( nSuper<12 ) return 0;
+  if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0;
+  if( zSuper[nSuper-3]!='9' ) return 0;
+  for(ii=nSuper-9; ii<nSuper; ii++){
+    if( sqlite3Isxdigit(zSuper[ii])==0 ) return 0;
+  }
+  return 1;
+}
+
 /*
 ** Parameter pJrnl is a file-handle open on a journal file. This function
 ** attempts to read a super-journal file name from the end of the journal 
@@ -1317,14 +1352,13 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
    || len==0
    || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
    || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
-   || memcmp(aMagic, aJournalMagic, 8)
   ){
     return rc;
   }
 
   zOut = (char*)sqlite3MallocZero(4 + len + 2);
   if( !zOut ){
-    rc = SQLITE_NOMEM_BKPT;
+    rc = memcmp(aMagic,aJournalMagic,8) ? SQLITE_OK : SQLITE_NOMEM_BKPT;
   }else{
     zOut = &zOut[4];
     if( SQLITE_OK==(rc = sqlite3OsRead(pJrnl, zOut, len, szJ-16-len)) ){
@@ -1334,11 +1368,14 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
         cksum -= zOut[u];
       }
     }
-    if( rc!=SQLITE_OK || cksum ){
-      /* If the checksum doesn't add up, then one or more of the disk sectors
-      ** containing the super-journal filename is corrupted. This means
-      ** definitely roll back, so just return SQLITE_OK and report a (nul)
-      ** super-journal filename.  */
+    if( rc!=SQLITE_OK                        /* Couldn't read the name */
+     || !pagerIsSuperJrnlName(zOut)          /* Name is not valid */
+     || cksum                                /* checksum is incorrect */
+     || memcmp(aMagic, aJournalMagic, 8)!=0  /* Bad magic number */
+    ){
+      /* If any validity checks fail, that means the super-journal filename
+      ** is corrupted, so rollback.  Return SQLITE_K and a NULL super-journal
+      ** name */
       freeSuperJournal(zOut);
       zOut = 0;
     }
@@ -1721,6 +1758,7 @@ static int writeSuperJournal(Pager *pPager, const char *zSuper){
 
   assert( pPager->setSuper==0 );
   assert( !pagerUseWal(pPager) );
+  assert( zSuper==0 || pagerIsSuperJrnlName(zSuper) );
 
   if( !zSuper
    || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
@@ -2499,40 +2537,6 @@ static int pager_playback_one_page(
   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 mode.
-**
-**   + 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;
-#ifdef SQLITE_ENABLE_8_3_NAMES
-  if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0;
-  if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0;
-  if( zSuper[nSuper-4]=='.' ) return 1;
-#endif
-  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.
@@ -2590,8 +2594,12 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
   /* 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 ){
+  ** SQLite to delete arbitrary files.
+  **
+  ** This test never fails, becaue the super journal name is checked
+  ** by readSuperJournal().
+  */
+  if( NEVER(pagerIsSuperJrnlName(zSuper)==0) ){
     return SQLITE_OK;
   }