summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-29 05:06:41 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-29 05:06:41 +0000
commit0d811a4265bbd36a7af8b09920ceb17348832200 (patch)
treed346d8674116855dea993c264e176d0c9a50b444
parentad3c649648d61dd03304bd964e3e3b444c042933 (diff)
downloadchromium_src-0d811a4265bbd36a7af8b09920ceb17348832200.zip
chromium_src-0d811a4265bbd36a7af8b09920ceb17348832200.tar.gz
chromium_src-0d811a4265bbd36a7af8b09920ceb17348832200.tar.bz2
[sql] Fix leafCursorCellDecode() crash.
If sqlite_master lists a valid root page for the table, and the root page is an interior b-tree page, and none of the children are valid pages, then recoverOpen() gets to leafCursorCreate(), and: - leafCursorLoadPage() loads the page as an interior node into a parent of the leaf cursor. - leafCursorNextPage() returns SQLITE_DONE because no more pages are available. - SQLITE_OK is returned, but pCursor->pPage is left empty. Then recoverFilter() calls leafCursorCellDecode(), which attempts to access pCursor->pPage->pgno, where pPage is NULL and pgno is at offset 12, causing a crash accessing 0x0000000c. The fix handles this by using bEOF to signal no data. This matches what would happen if there were valid leaf pages which contained no valid rows (recoverFilter() would call recoverNext() which would see SQLITE_DONE from leafCursorNextValidCall(), set bEOF, and return SQLITE_OK). Reverts r241341, a diagnostic which is no longer necessary. BUG=326646,329302 TBR=michaeln@chromium.org Review URL: https://codereview.chromium.org/116853004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242701 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--third_party/sqlite/amalgamation/sqlite3.c16
-rw-r--r--third_party/sqlite/src/src/recover.c16
2 files changed, 28 insertions, 4 deletions
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
index ceaa966..5dfdd2c 100644
--- a/third_party/sqlite/amalgamation/sqlite3.c
+++ b/third_party/sqlite/amalgamation/sqlite3.c
@@ -111873,6 +111873,12 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
pCursor->pLeafCursor = pLeafCursor;
pCursor->iEncoding = iEncoding;
+ /* If no leaf pages were found, empty result set. */
+ /* TODO(shess): leafCursorNextValidCell() would return SQLITE_ROW or
+ * SQLITE_DONE to indicate whether there is further data to consider.
+ */
+ pCursor->bEOF = (pLeafCursor->pPage==NULL);
+
*ppCursor = (sqlite3_vtab_cursor*)pCursor;
return SQLITE_OK;
}
@@ -111961,8 +111967,14 @@ static int recoverFilter(
FNENTRY();
- /* Load the first cell, and iterate forward if it's not valid. */
- /* TODO(shess): What happens if no cells at all are valid? */
+ /* There were no valid leaf pages in the table. */
+ if( pCursor->bEOF ){
+ return SQLITE_OK;
+ }
+
+ /* Load the first cell, and iterate forward if it's not valid. If no cells at
+ * all are valid, recoverNext() sets bEOF and returns appropriately.
+ */
rc = leafCursorCellDecode(pCursor->pLeafCursor);
if( rc!=SQLITE_OK || recoverValidateLeafCell(pRecover, pCursor)!=SQLITE_OK ){
return recoverNext(pVtabCursor);
diff --git a/third_party/sqlite/src/src/recover.c b/third_party/sqlite/src/src/recover.c
index 6430c8b..24ccfbd 100644
--- a/third_party/sqlite/src/src/recover.c
+++ b/third_party/sqlite/src/src/recover.c
@@ -1627,6 +1627,12 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
pCursor->pLeafCursor = pLeafCursor;
pCursor->iEncoding = iEncoding;
+ /* If no leaf pages were found, empty result set. */
+ /* TODO(shess): leafCursorNextValidCell() would return SQLITE_ROW or
+ * SQLITE_DONE to indicate whether there is further data to consider.
+ */
+ pCursor->bEOF = (pLeafCursor->pPage==NULL);
+
*ppCursor = (sqlite3_vtab_cursor*)pCursor;
return SQLITE_OK;
}
@@ -1715,8 +1721,14 @@ static int recoverFilter(
FNENTRY();
- /* Load the first cell, and iterate forward if it's not valid. */
- /* TODO(shess): What happens if no cells at all are valid? */
+ /* There were no valid leaf pages in the table. */
+ if( pCursor->bEOF ){
+ return SQLITE_OK;
+ }
+
+ /* Load the first cell, and iterate forward if it's not valid. If no cells at
+ * all are valid, recoverNext() sets bEOF and returns appropriately.
+ */
rc = leafCursorCellDecode(pCursor->pLeafCursor);
if( rc!=SQLITE_OK || recoverValidateLeafCell(pRecover, pCursor)!=SQLITE_OK ){
return recoverNext(pVtabCursor);