/ Check-in [8d2a062e]
Login

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

Overview
Comment:Fix a problem in the ".recover" command allowing a circular loop of b-tree pages in a database file to cause an infinite loop.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8d2a062eb8a3e6fdc6a61b571c8da0070382bf208c53e797151eac8679c975a1
User & Date: dan 2019-05-09 18:33:32
Context
2019-05-09
18:37
Fix another small buffer overread in sqlite_dbdata triggered by a corrupt database page. check-in: 1dfc95b8 user: dan tags: trunk
18:33
Fix a problem in the ".recover" command allowing a circular loop of b-tree pages in a database file to cause an infinite loop. check-in: 8d2a062e user: dan tags: trunk
18:13
Make the ".schema" command in the CLI resistant to corrupt database files. check-in: f22c7e22 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to ext/misc/dbdata.c.

297
298
299
300
301
302
303
304



305
306
307
308
309
310
311
/* 
** Utility methods to decode 16 and 32-bit big-endian unsigned integers. 
*/
static unsigned int get_uint16(unsigned char *a){
  return (a[0]<<8)|a[1];
}
static unsigned int get_uint32(unsigned char *a){
  return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|a[3];



}

/*
** Load page pgno from the database via the sqlite_dbpage virtual table.
** If successful, set (*ppPage) to point to a buffer containing the page
** data, (*pnPage) to the size of that buffer in bytes and return
** SQLITE_OK. In this case it is the responsibility of the caller to







|
>
>
>







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/* 
** Utility methods to decode 16 and 32-bit big-endian unsigned integers. 
*/
static unsigned int get_uint16(unsigned char *a){
  return (a[0]<<8)|a[1];
}
static unsigned int get_uint32(unsigned char *a){
  return ((unsigned int)a[0]<<24)
       | ((unsigned int)a[1]<<16)
       | ((unsigned int)a[2]<<8)
       | ((unsigned int)a[3]);
}

/*
** Load page pgno from the database via the sqlite_dbpage virtual table.
** If successful, set (*ppPage) to point to a buffer containing the page
** data, (*pnPage) to the size of that buffer in bytes and return
** SQLITE_OK. In this case it is the responsibility of the caller to

Changes to src/shell.c.in.

6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
    "    SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
    "  ) FROM pages WHERE i>=2"
    ")"
    "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
    "  SELECT i, maxlen, NULL, ("
    "    WITH p(orig, pgno, parent) AS ("
    "      SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
    "        UNION ALL"
    "      SELECT i, p.parent, "
    "        (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
    "    )"
    "    SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
    ") "
    "FROM pages WHERE maxlen > 0 AND i NOT IN freelist;"
    "UPDATE recovery.map AS o SET intkey = ("







|







6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
    "    SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
    "  ) FROM pages WHERE i>=2"
    ")"
    "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
    "  SELECT i, maxlen, NULL, ("
    "    WITH p(orig, pgno, parent) AS ("
    "      SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
    "        UNION "
    "      SELECT i, p.parent, "
    "        (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
    "    )"
    "    SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
    ") "
    "FROM pages WHERE maxlen > 0 AND i NOT IN freelist;"
    "UPDATE recovery.map AS o SET intkey = ("