SQLite

Check-in [2544f233f1]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2544f233f1041a42bbdbb5413d2bc92b2a2e0397
User & Date: dan 2012-01-10 17:28:10.499
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: cb774b26e1 user: drh tags: trunk)
Context
2012-01-10
17:59
Refactor sqlite3OsFileControlNoFail() into sqlite3FileControlHint(). (check-in: 722735a4f3 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: 2544f233f1 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: af59b182d7 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pager.c.
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401





2402

2403
2404
2405

2406













2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435

2436
2437
2438
2439
2440
2441
2442
  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
  ** sufficient space (in zMasterPtr) to hold the names of master
  ** journal files extracted from regular rollback-journals.
  */
  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  nMasterPtr = pVfs->mxPathname+1;
  zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
  if( !zMasterJournal ){
    rc = SQLITE_NOMEM;
    goto delmaster_out;
  }
  zMasterPtr = &zMasterJournal[nMasterJournal+1];
  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
  if( rc!=SQLITE_OK ) goto delmaster_out;





  zMasterJournal[nMasterJournal] = 0;


  zJournal = zMasterJournal;
  while( (zJournal-zMasterJournal)<nMasterJournal ){

    int exists;













    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
    if( rc!=SQLITE_OK ){
      goto delmaster_out;
    }
    if( exists ){
      /* One of the journals pointed to by the master journal exists.
      ** Open it and check if it points at the master journal. If
      ** so, return without deleting the master journal file.
      */
      int c;
      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
      if( rc!=SQLITE_OK ){
        goto delmaster_out;
      }

      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
      sqlite3OsClose(pJournal);
      if( rc!=SQLITE_OK ){
        goto delmaster_out;
      }

      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
      if( c ){
        /* We have a match. Do not delete the master journal file. */
        goto delmaster_out;
      }
    }
    zJournal += (sqlite3Strlen30(zJournal)+1);

  }
 
  sqlite3OsClose(pMaster);
  rc = sqlite3OsDelete(pVfs, zMaster, 0);

delmaster_out:
  sqlite3_free(zMasterJournal);







|




|


>
>
>
>
>

>



>

>
>
>
>
>
>
>
>
>
>
>
>
>









<












|
<




|
>







2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435

2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448

2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
  ** sufficient space (in zMasterPtr) to hold the names of master
  ** journal files extracted from regular rollback-journals.
  */
  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  nMasterPtr = pVfs->mxPathname+1;
  zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 2);
  if( !zMasterJournal ){
    rc = SQLITE_NOMEM;
    goto delmaster_out;
  }
  zMasterPtr = &zMasterJournal[nMasterJournal+2];
  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
  if( rc!=SQLITE_OK ) goto delmaster_out;

  /* Ensure that even if the contents of the master journal file are corrupt,
  ** they are terminated by a pair of 0x00 bytes. This prevents buffer 
  ** overreads in any calls made to sqlite3_uri_xxx() via sqlite3OsOpen()
  ** below.  */
  zMasterJournal[nMasterJournal] = 0;
  zMasterJournal[nMasterJournal+1] = 0;

  zJournal = zMasterJournal;
  while( (zJournal-zMasterJournal)<nMasterJournal ){
    char c;
    int exists;
    int nJournal = sqlite3Strlen30(zJournal);

    /* The sqlite3OsAccess() and sqlite3OsOpen() functions require argument
    ** strings that may be passed to the sqlite3_uri_xxx() API functions.
    ** In this case that means strings terminated by a pair of 0x00 bytes.
    ** But the master-journal file contains strings terminated by a single
    ** 0x00 only. So temporarily replace the first byte of the following
    ** string with a second 0x00. The original value is restored before the
    ** next iteration of this loop.  */
    assert( &zJournal[nJournal+1] < zMasterPtr );
    c = zJournal[nJournal+1];
    zJournal[nJournal+1] = '\0';

    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
    if( rc!=SQLITE_OK ){
      goto delmaster_out;
    }
    if( exists ){
      /* One of the journals pointed to by the master journal exists.
      ** Open it and check if it points at the master journal. If
      ** so, return without deleting the master journal file.
      */

      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
      if( rc!=SQLITE_OK ){
        goto delmaster_out;
      }

      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
      sqlite3OsClose(pJournal);
      if( rc!=SQLITE_OK ){
        goto delmaster_out;
      }

      if( zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0 ){

        /* We have a match. Do not delete the master journal file. */
        goto delmaster_out;
      }
    }
    zJournal += nJournal+1;
    zJournal[0] = c;
  }
 
  sqlite3OsClose(pMaster);
  rc = sqlite3OsDelete(pVfs, zMaster, 0);

delmaster_out:
  sqlite3_free(zMasterJournal);