Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(662)

Unified Diff: third_party/sqlite/src/src/recover.c

Issue 1685073003: [sqlite] Replace sqlite3Btree* calls with info from header. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@zzsql_recover_handle_review1
Patch Set: And apparently clang is less pedantic than Visual Studio about unused variables. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/amalgamation/sqlite3.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/src/src/recover.c
diff --git a/third_party/sqlite/src/src/recover.c b/third_party/sqlite/src/src/recover.c
index 9e6c35c542dbeee82e2b51dd8aa6426479bca8bc..5ff6f78c90065131eaa6135c15687d14877ea9d8 100644
--- a/third_party/sqlite/src/src/recover.c
+++ b/third_party/sqlite/src/src/recover.c
@@ -237,6 +237,15 @@
static const unsigned char kTableLeafPage = 0x0D;
static const unsigned char kTableInteriorPage = 0x05;
+/* From section 1.2. */
+static const unsigned kiHeaderPageSizeOffset = 16;
+static const unsigned kiHeaderReservedSizeOffset = 20;
+static const unsigned kiHeaderEncodingOffset = 56;
+/* TODO(shess) |static const unsigned| fails creating the header in GetPager()
+** because |knHeaderSize| isn't |constexpr|. But this isn't C++, either.
+*/
+enum { knHeaderSize = 100};
+
/* From section 1.5. */
static const unsigned kiPageTypeOffset = 0;
static const unsigned kiPageFreeBlockOffset = 1;
@@ -478,8 +487,7 @@ static const unsigned char *PageData(RecoverPage *pPage, unsigned iOffset){
*/
static const unsigned char *PageHeader(RecoverPage *pPage){
if( pPage->pgno==1 ){
- const unsigned nDatabaseHeader = 100;
- return PageData(pPage, nDatabaseHeader);
+ return PageData(pPage, knHeaderSize);
}else{
return PageData(pPage, 0);
}
@@ -487,21 +495,13 @@ static const unsigned char *PageHeader(RecoverPage *pPage){
/* Helper to fetch the pager and page size for the named database. */
static int GetPager(sqlite3 *db, const char *zName,
- RecoverPager **ppPager, unsigned *pnPageSize){
- int i, rc;
+ RecoverPager **ppPager, unsigned *pnPageSize,
+ int *piEncoding){
+ int rc, iEncoding;
unsigned nPageSize, nReservedSize;
+ unsigned char header[knHeaderSize];
sqlite3_file *pFile = NULL;
- Btree *pBt = NULL;
RecoverPager *pPager;
- for( i=0; i<db->nDb; ++i ){
- if( ascii_strcasecmp(db->aDb[i].zName, zName)==0 ){
- pBt = db->aDb[i].pBt;
- break;
- }
- }
- if( !pBt ){
- return SQLITE_ERROR;
- }
rc = sqlite3_file_control(db, zName, SQLITE_FCNTL_FILE_POINTER, &pFile);
if( rc!=SQLITE_OK ) {
@@ -519,8 +519,41 @@ static int GetPager(sqlite3 *db, const char *zName,
return rc;
}
- nPageSize = sqlite3BtreeGetPageSize(pBt);
- nReservedSize = sqlite3BtreeGetOptimalReserve(pBt);
+ /* Read the Initial header information. In case of SQLITE_IOERR_SHORT_READ,
+ ** the header is incomplete, which means no data could be recovered anyhow.
+ */
+ rc = pFile->pMethods->xRead(pFile, header, sizeof(header), 0);
+ if( rc != SQLITE_OK ){
+ pFile->pMethods->xUnlock(pFile, SQLITE_LOCK_NONE);
+ if( rc==SQLITE_IOERR_SHORT_READ ){
+ return SQLITE_CORRUPT;
+ }
+ return rc;
+ }
+
+ /* Page size must be a power of two between 512 and 32768 inclusive. */
+ nPageSize = decodeUnsigned16(header + kiHeaderPageSizeOffset);
+ if( (nPageSize&(nPageSize-1)) || nPageSize>32768 || nPageSize<512 ){
+ pFile->pMethods->xUnlock(pFile, SQLITE_LOCK_NONE);
+ return rc;
+ }
+
+ /* Space reserved a the end of the page for extensions. Usually 0. */
+ nReservedSize = header[kiHeaderReservedSizeOffset];
+
+ /* 1 for UTF-8, 2 for UTF-16le, 3 for UTF-16be. */
+ iEncoding = decodeUnsigned32(header + kiHeaderEncodingOffset);
+ if( iEncoding==3 ){
+ *piEncoding = SQLITE_UTF16BE;
+ } else if( iEncoding==2 ){
+ *piEncoding = SQLITE_UTF16LE;
+ } else if( iEncoding==1 ){
+ *piEncoding = SQLITE_UTF8;
+ } else {
+ /* This case should not be possible. */
+ *piEncoding = SQLITE_UTF8;
+ }
+
rc = pagerCreate(pFile, nPageSize, &pPager);
if( rc!=SQLITE_OK ){
pFile->pMethods->xUnlock(pFile, SQLITE_LOCK_NONE);
@@ -529,6 +562,7 @@ static int GetPager(sqlite3 *db, const char *zName,
*ppPager = pPager;
*pnPageSize = nPageSize - nReservedSize;
+ *piEncoding = iEncoding;
return SQLITE_OK;
}
@@ -655,57 +689,6 @@ static int getRootPage(sqlite3 *db, const char *zDb, const char *zTable,
return rc;
}
-static int getEncoding(sqlite3 *db, const char *zDb, int* piEncoding){
- sqlite3_stmt *pStmt;
- int rc;
- char *zSql = sqlite3_mprintf("PRAGMA %s.encoding", zDb);
- if( !zSql ){
- return SQLITE_NOMEM;
- }
-
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Require a result. */
- rc = sqlite3_step(pStmt);
- if( rc==SQLITE_DONE ){
- /* This case should not be possible. */
- rc = SQLITE_CORRUPT;
- }else if( rc==SQLITE_ROW ){
- if( sqlite3_column_type(pStmt, 0)==SQLITE_TEXT ){
- const char* z = (const char *)sqlite3_column_text(pStmt, 0);
- /* These strings match the literals in pragma.c. */
- if( !strcmp(z, "UTF-16le") ){
- *piEncoding = SQLITE_UTF16LE;
- }else if( !strcmp(z, "UTF-16be") ){
- *piEncoding = SQLITE_UTF16BE;
- }else if( !strcmp(z, "UTF-8") ){
- *piEncoding = SQLITE_UTF8;
- }else{
- /* This case should not be possible. */
- *piEncoding = SQLITE_UTF8;
- }
- }else{
- /* This case should not be possible. */
- *piEncoding = SQLITE_UTF8;
- }
-
- /* Require only one result. */
- rc = sqlite3_step(pStmt);
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- }else if( rc==SQLITE_ROW ){
- /* This case should not be possible. */
- rc = SQLITE_CORRUPT;
- }
- }
- sqlite3_finalize(pStmt);
- return rc;
-}
-
/* Cursor for iterating interior nodes. Interior page cells contain a
* child page number and a rowid. The child page contains items left
* of the rowid (less than). The rightmost page of the subtree is
@@ -1761,13 +1744,7 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
return rc;
}
- iEncoding = 0;
- rc = getEncoding(pRecover->db, pRecover->zDb, &iEncoding);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- rc = GetPager(pRecover->db, pRecover->zDb, &pPager, &nPageSize);
+ rc = GetPager(pRecover->db, pRecover->zDb, &pPager, &nPageSize, &iEncoding);
if( rc!=SQLITE_OK ){
return rc;
}
« no previous file with comments | « third_party/sqlite/amalgamation/sqlite3.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698