diff options
Diffstat (limited to 'ext/misc/scrub.c')
-rw-r--r-- | ext/misc/scrub.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c index 1d21fc538..92718e23d 100644 --- a/ext/misc/scrub.c +++ b/ext/misc/scrub.c @@ -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. */ |