Ensure that the sqlite3_scrub_backup() extension creates a backup database at least as large as indicated by the database header, even if the last page of the input database is a free-list leaf.

FossilOrigin-Name: 483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd
This commit is contained in:
dan
2016-07-26 10:46:21 +00:00
parent 9d60875901
commit 2900a6222f
3 changed files with 24 additions and 8 deletions
+16
View File
@@ -74,6 +74,7 @@ struct ScrubState {
u32 szPage; /* Page size */
u32 szUsable; /* Usable bytes on each page */
u32 nPage; /* Number of pages */
u32 iLastPage; /* Page number of last page written so far*/
u8 *page1; /* Content of page 1 */
};
@@ -130,6 +131,7 @@ static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){
scrubBackupErr(p, "write failed for page %d", pgno);
p->rcErr = SQLITE_IOERR;
}
if( pgno>p->iLastPage ) p->iLastPage = pgno;
}
/* Prepare a statement against the "db" database. */
@@ -541,6 +543,20 @@ int sqlite3_scrub_backup(
}
sqlite3_finalize(pStmt);
/* If the last page of the input db file is a free-list leaf, then the
** backup file on disk is still smaller than the size indicated within
** the database header. In this case, write a page of zeroes to the
** last page of the backup database so that SQLite does not mistakenly
** think the db is corrupt. */
if( s.iLastPage<s.nPage ){
u8 *aZero = scrubBackupAllocPage(&s);
if( aZero ){
memset(aZero, 0, s.szPage);
scrubBackupWrite(&s, s.nPage, aZero);
sqlite3_free(aZero);
}
}
scrub_abort:
/* Close the destination database without closing the transaction. If we
** commit, page zero will be overwritten. */