SQLite

Check-in [e736da9c18]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Have ".recover" handle cases where the sqlite_master table contains malformed SQL statements.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e736da9c18fad138c5502d354c3553373cba15358b69e44b257f60def59422e2
User & Date: dan 2019-05-09 14:15:19.691
Context
2019-05-09
15:07
Fix further buffer overreads triggered by passing corrupt records to the sqlite_dbdata module. (check-in: dbc6a9f7f6 user: dan tags: trunk)
14:15
Have ".recover" handle cases where the sqlite_master table contains malformed SQL statements. (check-in: e736da9c18 user: dan tags: trunk)
11:45
Fix a problem with running the ".recover" command on a database that is zero pages in size. (check-in: 47fa65343e user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/shell.c.in.
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
      shellFinalize(&rc, pPkFinder);
    }
  }

 finished:
  sqlite3_close(dbtmp);
  *pRc = rc;
  if( rc!=SQLITE_OK ){
    recoverFreeTable(pTab);
    pTab = 0;
  }
  return pTab;
}

/*







|







6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
      shellFinalize(&rc, pPkFinder);
    }
  }

 finished:
  sqlite3_close(dbtmp);
  *pRc = rc;
  if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
    recoverFreeTable(pTab);
    pTab = 0;
  }
  return pTab;
}

/*
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
    }
    shellFinalize(&rc, pStmt);
  }

  /* Figure out if an orphan table will be required. And if so, how many
  ** user columns it should contain */
  shellPrepare(pState->db, &rc, 
      "SELECT coalesce(max(maxlen), -2) FROM recovery.map" 
      "  WHERE root>1 AND root NOT IN (SELECT rootpage FROM recovery.schema)"
      , &pLoop
  );
  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
    nOrphan = sqlite3_column_int(pLoop, 0);
  }
  shellFinalize(&rc, pLoop);
  pLoop = 0;
  pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);

  shellPrepare(pState->db, &rc,
      "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  );
  shellPrepare(pState->db, &rc,
      "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
      "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"







|
<







<







6676
6677
6678
6679
6680
6681
6682
6683

6684
6685
6686
6687
6688
6689
6690

6691
6692
6693
6694
6695
6696
6697
    }
    shellFinalize(&rc, pStmt);
  }

  /* Figure out if an orphan table will be required. And if so, how many
  ** user columns it should contain */
  shellPrepare(pState->db, &rc, 
      "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"

      , &pLoop
  );
  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
    nOrphan = sqlite3_column_int(pLoop, 0);
  }
  shellFinalize(&rc, pLoop);
  pLoop = 0;


  shellPrepare(pState->db, &rc,
      "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  );
  shellPrepare(pState->db, &rc,
      "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
      "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
6712
6713
6714
6715
6716
6717
6718
6719






6720
6721
6722
6723
6724
6725
6726
    int bIntkey = sqlite3_column_int(pLoop, 1);
    int nCol = sqlite3_column_int(pLoop, 2);
    int bNoop = 0;
    RecoverTable *pTab;

    pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
    if( bNoop || rc ) continue;
    if( pTab==0 ) pTab = pOrphan;







    if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){
      raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
    }
    sqlite3_bind_int(pPages, 1, iRoot);
    sqlite3_bind_int(pCells, 2, pTab->iPk);








|
>
>
>
>
>
>







6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
    int bIntkey = sqlite3_column_int(pLoop, 1);
    int nCol = sqlite3_column_int(pLoop, 2);
    int bNoop = 0;
    RecoverTable *pTab;

    pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
    if( bNoop || rc ) continue;
    if( pTab==0 ){
      if( pOrphan==0 ){
        pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
      }
      pTab = pOrphan;
      if( pTab==0 ) break;
    }

    if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){
      raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
    }
    sqlite3_bind_int(pPages, 1, iRoot);
    sqlite3_bind_int(pCells, 2, pTab->iPk);