Fix a problem in backup.c causing OsTruncate() to be called with an argument larger than the current file-size. (CVS 6271)

FossilOrigin-Name: b34bde80c7e2028baf7ba2ff26e587a63a170f3d
This commit is contained in:
danielk1977 2009-02-09 18:55:45 +00:00
parent 08c6d4468c
commit 3d0cbc3362
4 changed files with 46 additions and 23 deletions

View File

@ -1,5 +1,5 @@
C Add\sassert()\sstatements\sto\sos_unix.c\swhich\sfire\sif\sthere\sis\sa\sread\sor\nwrite\sfor\sthe\slocking\sregion\sof\sa\sdatabase\sfile.\s(CVS\s6270) C Fix\sa\sproblem\sin\sbackup.c\scausing\sOsTruncate()\sto\sbe\scalled\swith\san\sargument\slarger\sthan\sthe\scurrent\sfile-size.\s(CVS\s6271)
D 2009-02-09T17:34:07 D 2009-02-09T18:55:46
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -101,7 +101,7 @@ F src/alter.c 0ec29744c36c6e976596ce38c16289ebc5dc94db
F src/analyze.c c86fd6a1425b22b3a46ce72ad403e4280026364f F src/analyze.c c86fd6a1425b22b3a46ce72ad403e4280026364f
F src/attach.c 81d37d1948f409146a7b22b96998fd90649d1fd3 F src/attach.c 81d37d1948f409146a7b22b96998fd90649d1fd3
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/backup.c 9563f47385f491579135fd7924d70c76c2eba740 F src/backup.c 7aff2b795c4a001716c40fff7e3928750e2f6b8f
F src/bitvec.c 44f7059ac1f874d364b34af31b9617e52223ba75 F src/bitvec.c 44f7059ac1f874d364b34af31b9617e52223ba75
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
F src/btree.c 71f30e74389aa7ae51421592dfaf69511152677c F src/btree.c 71f30e74389aa7ae51421592dfaf69511152677c
@ -233,7 +233,7 @@ F test/autoinc.test ab549b48b389cabd92967b86c379ec8b31fa6c16
F test/autovacuum.test 61260e25744189ff766f61ca3df23c1eeec0060e F test/autovacuum.test 61260e25744189ff766f61ca3df23c1eeec0060e
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6 F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650 F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650
F test/backup.test 12d7ad0545f47175e27445267d0810a277679ef2 F test/backup.test e1ccee089c190f480afe32f7795690399c644dea
F test/backup2.test 392318e059b83e87e5e4175f08be181a6ddce468 F test/backup2.test 392318e059b83e87e5e4175f08be181a6ddce468
F test/backup_ioerr.test a9b8084e488154341719833783ac9db321e14284 F test/backup_ioerr.test a9b8084e488154341719833783ac9db321e14284
F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387 F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387
@ -701,7 +701,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P e20bf384668bcde7c2f2152ca88e28cf65a02679 P 93e792ffa88ba2e8422d041f36b70d9b2e220da2
R 3a3cb4e439892d819d6a33e750f5e099 R f4d030cfc7856238ca71232918484f1a
U drh U danielk1977
Z 7b54fb55986a7fded747f515afad0223 Z e7286071c615582b1903f957fbdb0fad

View File

@ -1 +1 @@
93e792ffa88ba2e8422d041f36b70d9b2e220da2 b34bde80c7e2028baf7ba2ff26e587a63a170f3d

View File

@ -12,7 +12,7 @@
** This file contains the implementation of the sqlite3_backup_XXX() ** This file contains the implementation of the sqlite3_backup_XXX()
** API functions and the related features. ** API functions and the related features.
** **
** $Id: backup.c,v 1.8 2009/02/06 05:59:44 danielk1977 Exp $ ** $Id: backup.c,v 1.9 2009/02/09 18:55:46 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "btreeInt.h" #include "btreeInt.h"
@ -254,6 +254,23 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
return rc; return rc;
} }
/*
** If pFile is currently larger than iSize bytes, then truncate it to
** exactly iSize bytes. If pFile is not larger than iSize bytes, then
** this function is a no-op.
**
** Return SQLITE_OK if everything is successful, or an SQLite error
** code if an error occurs.
*/
static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
i64 iCurrent;
int rc = sqlite3OsFileSize(pFile, &iCurrent);
if( rc==SQLITE_OK && iCurrent>iSize ){
rc = sqlite3OsTruncate(pFile, iSize);
}
return rc;
}
/* /*
** Copy nPage pages from the source b-tree to the destination. ** Copy nPage pages from the source b-tree to the destination.
*/ */
@ -330,8 +347,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc); const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest); const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
int nDestTruncate; int nDestTruncate;
sqlite3_file *pFile = 0;
i64 iSize;
/* Update the schema version field in the destination database. This /* Update the schema version field in the destination database. This
** is to make sure that the schema-version really does change in ** is to make sure that the schema-version really does change in
@ -373,11 +388,13 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
** pending-byte page in the source database may need to be ** pending-byte page in the source database may need to be
** copied into the destination database. ** copied into the destination database.
*/ */
iSize = (i64)nSrcPagesize * (i64)nSrcPage; const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage;
pFile = sqlite3PagerFile(pDestPager); sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
assert( pFile ); assert( pFile );
assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize );
if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1)) if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1))
&& SQLITE_OK==(rc = sqlite3OsTruncate(pFile, iSize)) && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize))
&& SQLITE_OK==(rc = sqlite3PagerSync(pDestPager)) && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager))
){ ){
i64 iOff; i64 iOff;

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is testing the sqlite3_backup_XXX API. # focus of this file is testing the sqlite3_backup_XXX API.
# #
# $Id: backup.test,v 1.4 2009/02/06 05:59:45 danielk1977 Exp $ # $Id: backup.test,v 1.5 2009/02/09 18:55:46 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -263,7 +263,7 @@ foreach nPagePerStep {1 200} {
# * Target database page-size is smaller than the source. # * Target database page-size is smaller than the source.
# #
set iTest 1 set iTest 1
foreach nSrcRow {10 100} { foreach nSrcPg {10 64 65 66 100} {
foreach nDestRow {10 100} { foreach nDestRow {10 100} {
foreach nDestPgsz {512 1024 2048 4096} { foreach nDestPgsz {512 1024 2048 4096} {
@ -274,18 +274,24 @@ foreach nDestPgsz {512 1024 2048 4096} {
# Set up the content of the two databases. # Set up the content of the two databases.
# #
foreach {db nRow} [list db $nSrcRow db2 $nDestRow] { execsql { PRAGMA page_size = 1024 }
execsql "PRAGMA page_size = $nDestPgsz" db2
foreach db {db db2} {
execsql { execsql {
BEGIN; BEGIN;
CREATE TABLE t1(a, b); CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b); CREATE INDEX i1 ON t1(a, b);
COMMIT;
} $db } $db
for {set ii 0} {$ii < $nSrcRow} {incr ii} {
execsql { INSERT INTO t1 VALUES($ii, randstr(1000,1000)) } $db
}
execsql COMMIT $db
} }
while {[file size test.db]/1024 < $nSrcPg} {
execsql { INSERT INTO t1 VALUES($ii, randstr(200,200)) }
}
for {set ii 0} {$ii < $nDestRow} {incr ii} {
execsql { INSERT INTO t1 VALUES($ii, randstr(1000,1000)) } db2
}
# Backup the source database. # Backup the source database.
do_test backup-3.$iTest.1 { do_test backup-3.$iTest.1 {
sqlite3_backup B db main db2 main sqlite3_backup B db main db2 main