/ Check-in [2544f233]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Avoid passing strings with a single nul-terminator (two are required) to the VFS xOpen() method from within the code that checks to see if a master-journal file may be safely deleted.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2544f233f1041a42bbdbb5413d2bc92b2a2e0397
User & Date: dan 2012-01-10 17:28:10
References
2012-01-10
23:18
Only require double-zero terminators on database filenames, not any every files supplied to the xOpen method. This backs out [2544f233f1]. Also refactor the fillInUnixFile() routine in os_unix.c to reduce the number of parameters. check-in: cb774b26 user: drh tags: trunk
Context
2012-01-10
17:59
Refactor sqlite3OsFileControlNoFail() into sqlite3FileControlHint(). check-in: 722735a4 user: drh tags: trunk
17:28
Avoid passing strings with a single nul-terminator (two are required) to the VFS xOpen() method from within the code that checks to see if a master-journal file may be safely deleted. check-in: 2544f233 user: dan tags: trunk
16:56
Add function sqlite3OsFileControlNoFail(), which is the same as sqlite3OsFileControl() except that it does not simulate OOM errors. This saves adding calls to the BenignMalloc() functions around each of the invocations of sqliteOsFileControl() that ignore the return code. check-in: af59b182 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

  2387   2387     ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
  2388   2388     ** sufficient space (in zMasterPtr) to hold the names of master
  2389   2389     ** journal files extracted from regular rollback-journals.
  2390   2390     */
  2391   2391     rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
  2392   2392     if( rc!=SQLITE_OK ) goto delmaster_out;
  2393   2393     nMasterPtr = pVfs->mxPathname+1;
  2394         -  zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
         2394  +  zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 2);
  2395   2395     if( !zMasterJournal ){
  2396   2396       rc = SQLITE_NOMEM;
  2397   2397       goto delmaster_out;
  2398   2398     }
  2399         -  zMasterPtr = &zMasterJournal[nMasterJournal+1];
         2399  +  zMasterPtr = &zMasterJournal[nMasterJournal+2];
  2400   2400     rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
  2401   2401     if( rc!=SQLITE_OK ) goto delmaster_out;
         2402  +
         2403  +  /* Ensure that even if the contents of the master journal file are corrupt,
         2404  +  ** they are terminated by a pair of 0x00 bytes. This prevents buffer 
         2405  +  ** overreads in any calls made to sqlite3_uri_xxx() via sqlite3OsOpen()
         2406  +  ** below.  */
  2402   2407     zMasterJournal[nMasterJournal] = 0;
         2408  +  zMasterJournal[nMasterJournal+1] = 0;
  2403   2409   
  2404   2410     zJournal = zMasterJournal;
  2405   2411     while( (zJournal-zMasterJournal)<nMasterJournal ){
         2412  +    char c;
  2406   2413       int exists;
         2414  +    int nJournal = sqlite3Strlen30(zJournal);
         2415  +
         2416  +    /* The sqlite3OsAccess() and sqlite3OsOpen() functions require argument
         2417  +    ** strings that may be passed to the sqlite3_uri_xxx() API functions.
         2418  +    ** In this case that means strings terminated by a pair of 0x00 bytes.
         2419  +    ** But the master-journal file contains strings terminated by a single
         2420  +    ** 0x00 only. So temporarily replace the first byte of the following
         2421  +    ** string with a second 0x00. The original value is restored before the
         2422  +    ** next iteration of this loop.  */
         2423  +    assert( &zJournal[nJournal+1] < zMasterPtr );
         2424  +    c = zJournal[nJournal+1];
         2425  +    zJournal[nJournal+1] = '\0';
         2426  +
  2407   2427       rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
  2408   2428       if( rc!=SQLITE_OK ){
  2409   2429         goto delmaster_out;
  2410   2430       }
  2411   2431       if( exists ){
  2412   2432         /* One of the journals pointed to by the master journal exists.
  2413   2433         ** Open it and check if it points at the master journal. If
  2414   2434         ** so, return without deleting the master journal file.
  2415   2435         */
  2416         -      int c;
  2417   2436         int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
  2418   2437         rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
  2419   2438         if( rc!=SQLITE_OK ){
  2420   2439           goto delmaster_out;
  2421   2440         }
  2422   2441   
  2423   2442         rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
  2424   2443         sqlite3OsClose(pJournal);
  2425   2444         if( rc!=SQLITE_OK ){
  2426   2445           goto delmaster_out;
  2427   2446         }
  2428   2447   
  2429         -      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
  2430         -      if( c ){
         2448  +      if( zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0 ){
  2431   2449           /* We have a match. Do not delete the master journal file. */
  2432   2450           goto delmaster_out;
  2433   2451         }
  2434   2452       }
  2435         -    zJournal += (sqlite3Strlen30(zJournal)+1);
         2453  +    zJournal += nJournal+1;
         2454  +    zJournal[0] = c;
  2436   2455     }
  2437   2456    
  2438   2457     sqlite3OsClose(pMaster);
  2439   2458     rc = sqlite3OsDelete(pVfs, zMaster, 0);
  2440   2459   
  2441   2460   delmaster_out:
  2442   2461     sqlite3_free(zMasterJournal);