/ Hex Artifact Content
Login

Artifact cb787825d761b0f869764d6990531382840de872:


0000: 23 20 32 30 30 34 20 41 75 67 75 73 74 20 33 30  # 2004 August 30
0010: 0a 23 0a 23 20 54 68 65 20 61 75 74 68 6f 72 20  .#.# The author 
0020: 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 72 69  disclaims copyri
0030: 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f 75 72  ght to this sour
0040: 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61  ce code.  In pla
0050: 63 65 20 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20  ce of.# a legal 
0060: 6e 6f 74 69 63 65 2c 20 68 65 72 65 20 69 73 20  notice, here is 
0070: 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20  a blessing:.#.# 
0080: 20 20 20 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f     May you do go
0090: 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e  od and not evil.
00a0: 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 66 69  .#    May you fi
00b0: 6e 64 20 66 6f 72 67 69 76 65 6e 65 73 73 20 66  nd forgiveness f
00c0: 6f 72 20 79 6f 75 72 73 65 6c 66 20 61 6e 64 20  or yourself and 
00d0: 66 6f 72 67 69 76 65 20 6f 74 68 65 72 73 2e 0a  forgive others..
00e0: 23 20 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61  #    May you sha
00f0: 72 65 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72  re freely, never
0100: 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61   taking more tha
0110: 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a  n you give..#.#*
0120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73 20 66 69  ******.# This fi
0170: 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 72 65  le implements re
0180: 67 72 65 73 73 69 6f 6e 20 74 65 73 74 73 20 66  gression tests f
0190: 6f 72 20 53 51 4c 69 74 65 20 6c 69 62 72 61 72  or SQLite librar
01a0: 79 2e 0a 23 0a 23 20 54 68 69 73 20 66 69 6c 65  y..#.# This file
01b0: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 65 73 74   implements test
01c0: 73 20 74 6f 20 6d 61 6b 65 20 73 75 72 65 20 53  s to make sure S
01d0: 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74 20 63  QLite does not c
01e0: 72 61 73 68 20 6f 72 0a 23 20 73 65 67 66 61 75  rash or.# segfau
01f0: 6c 74 20 69 66 20 69 74 20 73 65 65 73 20 61 20  lt if it sees a 
0200: 63 6f 72 72 75 70 74 20 64 61 74 61 62 61 73 65  corrupt database
0210: 20 66 69 6c 65 2e 0a 23 0a 23 20 24 49 64 3a 20   file..#.# $Id: 
0220: 63 6f 72 72 75 70 74 32 2e 74 65 73 74 2c 76 20  corrupt2.test,v 
0230: 31 2e 32 30 20 32 30 30 39 2f 30 34 2f 30 36 20  1.20 2009/04/06 
0240: 31 37 3a 35 30 3a 30 33 20 64 61 6e 69 65 6c 6b  17:50:03 danielk
0250: 31 39 37 37 20 45 78 70 20 24 0a 0a 73 65 74 20  1977 Exp $..set 
0260: 74 65 73 74 64 69 72 20 5b 66 69 6c 65 20 64 69  testdir [file di
0270: 72 6e 61 6d 65 20 24 61 72 67 76 30 5d 0a 73 6f  rname $argv0].so
0280: 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 74 65  urce $testdir/te
0290: 73 74 65 72 2e 74 63 6c 0a 73 65 74 20 74 65 73  ster.tcl.set tes
02a0: 74 70 72 65 66 69 78 20 63 6f 72 72 75 70 74 32  tprefix corrupt2
02b0: 0a 0a 23 20 44 6f 20 6e 6f 74 20 75 73 65 20 61  ..# Do not use a
02c0: 20 63 6f 64 65 63 20 66 6f 72 20 74 65 73 74 73   codec for tests
02d0: 20 69 6e 20 74 68 69 73 20 66 69 6c 65 2c 20 61   in this file, a
02e0: 73 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  s the database f
02f0: 69 6c 65 20 69 73 0a 23 20 6d 61 6e 69 70 75 6c  ile is.# manipul
0300: 61 74 65 64 20 64 69 72 65 63 74 6c 79 20 75 73  ated directly us
0310: 69 6e 67 20 74 63 6c 20 73 63 72 69 70 74 73 20  ing tcl scripts 
0320: 28 75 73 69 6e 67 20 74 68 65 20 5b 68 65 78 69  (using the [hexi
0330: 6f 5f 77 72 69 74 65 5d 20 63 6f 6d 6d 61 6e 64  o_write] command
0340: 29 2e 0a 23 0a 64 6f 5f 6e 6f 74 5f 75 73 65 5f  )..#.do_not_use_
0350: 63 6f 64 65 63 0a 0a 23 20 54 68 65 73 65 20 74  codec..# These t
0360: 65 73 74 73 20 64 65 61 6c 20 77 69 74 68 20 63  ests deal with c
0370: 6f 72 72 75 70 74 20 64 61 74 61 62 61 73 65 20  orrupt database 
0380: 66 69 6c 65 73 0a 23 0a 64 61 74 61 62 61 73 65  files.#.database
0390: 5f 6d 61 79 5f 62 65 5f 63 6f 72 72 75 70 74 0a  _may_be_corrupt.
03a0: 0a 73 65 74 20 70 72 65 73 71 6c 20 22 22 0a 63  .set presql "".c
03b0: 61 74 63 68 20 7b 20 73 65 74 20 70 72 65 73 71  atch { set presq
03c0: 6c 20 22 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65  l "$::G(perm:pre
03d0: 73 71 6c 29 3b 22 20 7d 0a 75 6e 73 65 74 20 2d  sql);" }.unset -
03e0: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 3a 3a 47 28 70  nocomplain ::G(p
03f0: 65 72 6d 3a 70 72 65 73 71 6c 29 0a 0a 23 20 54  erm:presql)..# T
0400: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 65 73  he following tes
0410: 74 73 20 2d 20 63 6f 72 72 75 70 74 32 2d 31 2e  ts - corrupt2-1.
0420: 2a 20 2d 20 63 72 65 61 74 65 20 73 6f 6d 65 20  * - create some 
0430: 64 61 74 61 62 61 73 65 73 20 63 6f 72 72 75 70  databases corrup
0440: 74 65 64 20 69 6e 0a 23 20 73 70 65 63 69 66 69  ted in.# specifi
0450: 63 20 77 61 79 73 20 61 6e 64 20 65 6e 73 75 72  c ways and ensur
0460: 65 20 74 68 61 74 20 53 51 4c 69 74 65 20 64 65  e that SQLite de
0470: 74 65 63 74 73 20 74 68 65 6d 20 61 73 20 63 6f  tects them as co
0480: 72 72 75 70 74 2e 0a 23 0a 64 6f 5f 74 65 73 74  rrupt..#.do_test
0490: 20 63 6f 72 72 75 70 74 32 2d 31 2e 31 20 7b 0a   corrupt2-1.1 {.
04a0: 20 20 65 78 65 63 73 71 6c 20 7b 0a 20 20 20 20    execsql {.    
04b0: 50 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75  PRAGMA auto_vacu
04c0: 75 6d 3d 30 3b 0a 20 20 20 20 50 52 41 47 4d 41  um=0;.    PRAGMA
04d0: 20 70 61 67 65 5f 73 69 7a 65 3d 31 30 32 34 3b   page_size=1024;
04e0: 0a 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c  .    CREATE TABL
04f0: 45 20 61 62 63 28 61 2c 20 62 2c 20 63 29 3b 0a  E abc(a, b, c);.
0500: 20 20 7d 0a 7d 20 7b 7d 0a 0a 64 6f 5f 74 65 73    }.} {}..do_tes
0510: 74 20 63 6f 72 72 75 70 74 32 2d 31 2e 32 20 7b  t corrupt2-1.2 {
0520: 0a 0a 20 20 23 20 43 6f 72 72 75 70 74 20 74 68  ..  # Corrupt th
0530: 65 20 31 36 20 62 79 74 65 20 6d 61 67 69 63 20  e 16 byte magic 
0540: 73 74 72 69 6e 67 20 61 74 20 74 68 65 20 73 74  string at the st
0550: 61 72 74 20 6f 66 20 74 68 65 20 66 69 6c 65 0a  art of the file.
0560: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63 6f    forcedelete co
0570: 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63 65  rrupt.db.  force
0580: 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e 64  delete corrupt.d
0590: 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72 63  b-journal.  forc
05a0: 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63 6f  ecopy test.db co
05b0: 72 72 75 70 74 2e 64 62 0a 20 20 73 65 74 20 66  rrupt.db.  set f
05c0: 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e 64   [open corrupt.d
05d0: 62 20 52 44 57 52 5d 0a 20 20 73 65 65 6b 20 24  b RDWR].  seek $
05e0: 66 20 38 20 73 74 61 72 74 0a 20 20 70 75 74 73  f 8 start.  puts
05f0: 20 24 66 20 62 6c 61 68 0a 20 20 63 6c 6f 73 65   $f blah.  close
0600: 20 24 66 0a 0a 20 20 73 71 6c 69 74 65 33 20 64   $f..  sqlite3 d
0610: 62 32 20 63 6f 72 72 75 70 74 2e 64 62 0a 20 20  b2 corrupt.db.  
0620: 63 61 74 63 68 73 71 6c 20 22 0a 20 20 20 20 24  catchsql ".    $
0630: 3a 3a 70 72 65 73 71 6c 0a 20 20 20 20 53 45 4c  ::presql.    SEL
0640: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
0650: 65 5f 6d 61 73 74 65 72 3b 0a 20 20 22 20 64 62  e_master;.  " db
0660: 32 0a 7d 20 7b 31 20 7b 66 69 6c 65 20 69 73 20  2.} {1 {file is 
0670: 65 6e 63 72 79 70 74 65 64 20 6f 72 20 69 73 20  encrypted or is 
0680: 6e 6f 74 20 61 20 64 61 74 61 62 61 73 65 7d 7d  not a database}}
0690: 0a 0a 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70  ..do_test corrup
06a0: 74 32 2d 31 2e 33 20 7b 0a 20 20 64 62 32 20 63  t2-1.3 {.  db2 c
06b0: 6c 6f 73 65 0a 0a 20 20 23 20 43 6f 72 72 75 70  lose..  # Corrup
06c0: 74 20 74 68 65 20 70 61 67 65 2d 73 69 7a 65 20  t the page-size 
06d0: 28 62 79 74 65 73 20 31 36 20 61 6e 64 20 31 37  (bytes 16 and 17
06e0: 20 6f 66 20 70 61 67 65 20 31 29 2e 0a 20 20 66   of page 1)..  f
06f0: 6f 72 63 65 64 65 6c 65 74 65 20 63 6f 72 72 75  orcedelete corru
0700: 70 74 2e 64 62 0a 20 20 66 6f 72 63 65 64 65 6c  pt.db.  forcedel
0710: 65 74 65 20 63 6f 72 72 75 70 74 2e 64 62 2d 6a  ete corrupt.db-j
0720: 6f 75 72 6e 61 6c 0a 20 20 66 6f 72 63 65 63 6f  ournal.  forceco
0730: 70 79 20 74 65 73 74 2e 64 62 20 63 6f 72 72 75  py test.db corru
0740: 70 74 2e 64 62 0a 20 20 73 65 74 20 66 20 5b 6f  pt.db.  set f [o
0750: 70 65 6e 20 63 6f 72 72 75 70 74 2e 64 62 20 52  pen corrupt.db R
0760: 44 57 52 5d 0a 20 20 66 63 6f 6e 66 69 67 75 72  DWR].  fconfigur
0770: 65 20 24 66 20 2d 65 6e 63 6f 64 69 6e 67 20 62  e $f -encoding b
0780: 69 6e 61 72 79 0a 20 20 73 65 65 6b 20 24 66 20  inary.  seek $f 
0790: 31 36 20 73 74 61 72 74 0a 20 20 70 75 74 73 20  16 start.  puts 
07a0: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66 20 22 5c  -nonewline $f "\
07b0: 78 30 30 5c 78 46 46 22 0a 20 20 63 6c 6f 73 65  x00\xFF".  close
07c0: 20 24 66 0a 0a 20 20 73 71 6c 69 74 65 33 20 64   $f..  sqlite3 d
07d0: 62 32 20 63 6f 72 72 75 70 74 2e 64 62 0a 20 20  b2 corrupt.db.  
07e0: 63 61 74 63 68 73 71 6c 20 22 0a 20 20 20 20 24  catchsql ".    $
07f0: 3a 3a 70 72 65 73 71 6c 0a 20 20 20 20 53 45 4c  ::presql.    SEL
0800: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
0810: 65 5f 6d 61 73 74 65 72 3b 0a 20 20 22 20 64 62  e_master;.  " db
0820: 32 0a 7d 20 7b 31 20 7b 66 69 6c 65 20 69 73 20  2.} {1 {file is 
0830: 65 6e 63 72 79 70 74 65 64 20 6f 72 20 69 73 20  encrypted or is 
0840: 6e 6f 74 20 61 20 64 61 74 61 62 61 73 65 7d 7d  not a database}}
0850: 0a 0a 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70  ..do_test corrup
0860: 74 32 2d 31 2e 34 20 7b 0a 20 20 64 62 32 20 63  t2-1.4 {.  db2 c
0870: 6c 6f 73 65 0a 0a 20 20 23 20 43 6f 72 72 75 70  lose..  # Corrup
0880: 74 20 74 68 65 20 66 72 65 65 2d 62 6c 6f 63 6b  t the free-block
0890: 20 6c 69 73 74 20 6f 6e 20 70 61 67 65 20 31 2e   list on page 1.
08a0: 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63  .  forcedelete c
08b0: 6f 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63  orrupt.db.  forc
08c0: 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e  edelete corrupt.
08d0: 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72  db-journal.  for
08e0: 63 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63  cecopy test.db c
08f0: 6f 72 72 75 70 74 2e 64 62 0a 20 20 73 65 74 20  orrupt.db.  set 
0900: 66 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e  f [open corrupt.
0910: 64 62 20 52 44 57 52 5d 0a 20 20 66 63 6f 6e 66  db RDWR].  fconf
0920: 69 67 75 72 65 20 24 66 20 2d 65 6e 63 6f 64 69  igure $f -encodi
0930: 6e 67 20 62 69 6e 61 72 79 0a 20 20 73 65 65 6b  ng binary.  seek
0940: 20 24 66 20 31 30 31 20 73 74 61 72 74 0a 20 20   $f 101 start.  
0950: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
0960: 24 66 20 22 5c 78 46 46 5c 78 46 46 22 0a 20 20  $f "\xFF\xFF".  
0970: 63 6c 6f 73 65 20 24 66 0a 0a 20 20 73 71 6c 69  close $f..  sqli
0980: 74 65 33 20 64 62 32 20 63 6f 72 72 75 70 74 2e  te3 db2 corrupt.
0990: 64 62 0a 20 20 63 61 74 63 68 73 71 6c 20 22 0a  db.  catchsql ".
09a0: 20 20 20 20 24 3a 3a 70 72 65 73 71 6c 0a 20 20      $::presql.  
09b0: 20 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20    SELECT * FROM 
09c0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 0a 20  sqlite_master;. 
09d0: 20 22 20 64 62 32 0a 7d 20 7b 31 20 7b 64 61 74   " db2.} {1 {dat
09e0: 61 62 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65  abase disk image
09f0: 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a   is malformed}}.
0a00: 0a 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74  .do_test corrupt
0a10: 32 2d 31 2e 35 20 7b 0a 20 20 64 62 32 20 63 6c  2-1.5 {.  db2 cl
0a20: 6f 73 65 0a 0a 20 20 23 20 43 6f 72 72 75 70 74  ose..  # Corrupt
0a30: 20 74 68 65 20 66 72 65 65 2d 62 6c 6f 63 6b 20   the free-block 
0a40: 6c 69 73 74 20 6f 6e 20 70 61 67 65 20 31 2e 0a  list on page 1..
0a50: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63 6f    forcedelete co
0a60: 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63 65  rrupt.db.  force
0a70: 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e 64  delete corrupt.d
0a80: 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72 63  b-journal.  forc
0a90: 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63 6f  ecopy test.db co
0aa0: 72 72 75 70 74 2e 64 62 0a 20 20 73 65 74 20 66  rrupt.db.  set f
0ab0: 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e 64   [open corrupt.d
0ac0: 62 20 52 44 57 52 5d 0a 20 20 66 63 6f 6e 66 69  b RDWR].  fconfi
0ad0: 67 75 72 65 20 24 66 20 2d 65 6e 63 6f 64 69 6e  gure $f -encodin
0ae0: 67 20 62 69 6e 61 72 79 0a 20 20 73 65 65 6b 20  g binary.  seek 
0af0: 24 66 20 31 30 31 20 73 74 61 72 74 0a 20 20 70  $f 101 start.  p
0b00: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24  uts -nonewline $
0b10: 66 20 22 5c 78 30 30 5c 78 43 38 22 0a 20 20 73  f "\x00\xC8".  s
0b20: 65 65 6b 20 24 66 20 32 30 30 20 73 74 61 72 74  eek $f 200 start
0b30: 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69  .  puts -nonewli
0b40: 6e 65 20 24 66 20 22 5c 78 30 30 5c 78 30 30 22  ne $f "\x00\x00"
0b50: 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69  .  puts -nonewli
0b60: 6e 65 20 24 66 20 22 5c 78 31 30 5c 78 30 30 22  ne $f "\x10\x00"
0b70: 0a 20 20 63 6c 6f 73 65 20 24 66 0a 0a 20 20 73  .  close $f..  s
0b80: 71 6c 69 74 65 33 20 64 62 32 20 63 6f 72 72 75  qlite3 db2 corru
0b90: 70 74 2e 64 62 0a 20 20 63 61 74 63 68 73 71 6c  pt.db.  catchsql
0ba0: 20 22 0a 20 20 20 20 24 3a 3a 70 72 65 73 71 6c   ".    $::presql
0bb0: 0a 20 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52  .    SELECT * FR
0bc0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
0bd0: 3b 0a 20 20 22 20 64 62 32 0a 7d 20 7b 31 20 7b  ;.  " db2.} {1 {
0be0: 64 61 74 61 62 61 73 65 20 64 69 73 6b 20 69 6d  database disk im
0bf0: 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64  age is malformed
0c00: 7d 7d 0a 64 62 32 20 63 6c 6f 73 65 0a 0a 23 20  }}.db2 close..# 
0c10: 43 6f 72 72 75 70 74 20 61 20 64 61 74 61 62 61  Corrupt a databa
0c20: 73 65 20 62 79 20 68 61 76 69 6e 67 20 32 20 69  se by having 2 i
0c30: 6e 64 69 63 65 73 20 6f 66 20 74 68 65 20 73 61  ndices of the sa
0c40: 6d 65 20 6e 61 6d 65 3a 0a 64 6f 5f 74 65 73 74  me name:.do_test
0c50: 20 63 6f 72 72 75 70 74 32 2d 32 2e 31 20 7b 0a   corrupt2-2.1 {.
0c60: 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63  .  forcedelete c
0c70: 6f 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63  orrupt.db.  forc
0c80: 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e  edelete corrupt.
0c90: 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72  db-journal.  for
0ca0: 63 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63  cecopy test.db c
0cb0: 6f 72 72 75 70 74 2e 64 62 0a 0a 20 20 73 71 6c  orrupt.db..  sql
0cc0: 69 74 65 33 20 64 62 32 20 63 6f 72 72 75 70 74  ite3 db2 corrupt
0cd0: 2e 64 62 20 0a 20 20 65 78 65 63 73 71 6c 20 22  .db .  execsql "
0ce0: 0a 20 20 20 20 24 3a 3a 70 72 65 73 71 6c 0a 20  .    $::presql. 
0cf0: 20 20 20 43 52 45 41 54 45 20 49 4e 44 45 58 20     CREATE INDEX 
0d00: 61 31 20 4f 4e 20 61 62 63 28 61 29 3b 0a 20 20  a1 ON abc(a);.  
0d10: 20 20 43 52 45 41 54 45 20 49 4e 44 45 58 20 61    CREATE INDEX a
0d20: 32 20 4f 4e 20 61 62 63 28 62 29 3b 0a 20 20 20  2 ON abc(b);.   
0d30: 20 50 52 41 47 4d 41 20 77 72 69 74 61 62 6c 65   PRAGMA writable
0d40: 5f 73 63 68 65 6d 61 20 3d 20 31 3b 0a 20 20 20  _schema = 1;.   
0d50: 20 55 50 44 41 54 45 20 73 71 6c 69 74 65 5f 6d   UPDATE sqlite_m
0d60: 61 73 74 65 72 20 0a 20 20 20 20 20 20 53 45 54  aster .      SET
0d70: 20 6e 61 6d 65 20 3d 20 27 61 33 27 2c 20 73 71   name = 'a3', sq
0d80: 6c 20 3d 20 27 43 52 45 41 54 45 20 49 4e 44 45  l = 'CREATE INDE
0d90: 58 20 61 33 27 20 7c 7c 20 73 75 62 73 74 72 28  X a3' || substr(
0da0: 73 71 6c 2c 20 31 36 2c 20 31 30 30 30 30 29 0a  sql, 16, 10000).
0db0: 20 20 20 20 20 20 57 48 45 52 45 20 74 79 70 65        WHERE type
0dc0: 20 3d 20 27 69 6e 64 65 78 27 3b 0a 20 20 20 20   = 'index';.    
0dd0: 50 52 41 47 4d 41 20 77 72 69 74 61 62 6c 65 5f  PRAGMA writable_
0de0: 73 63 68 65 6d 61 20 3d 20 30 3b 0a 20 20 22 20  schema = 0;.  " 
0df0: 64 62 32 0a 0a 20 20 64 62 32 20 63 6c 6f 73 65  db2..  db2 close
0e00: 0a 20 20 73 71 6c 69 74 65 33 20 64 62 32 20 63  .  sqlite3 db2 c
0e10: 6f 72 72 75 70 74 2e 64 62 20 0a 20 20 63 61 74  orrupt.db .  cat
0e20: 63 68 73 71 6c 20 22 0a 20 20 20 20 24 3a 3a 70  chsql ".    $::p
0e30: 72 65 73 71 6c 0a 20 20 20 20 53 45 4c 45 43 54  resql.    SELECT
0e40: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
0e50: 61 73 74 65 72 3b 0a 20 20 22 20 64 62 32 0a 7d  aster;.  " db2.}
0e60: 20 7b 31 20 7b 6d 61 6c 66 6f 72 6d 65 64 20 64   {1 {malformed d
0e70: 61 74 61 62 61 73 65 20 73 63 68 65 6d 61 20 28  atabase schema (
0e80: 61 33 29 20 2d 20 69 6e 64 65 78 20 61 33 20 61  a3) - index a3 a
0e90: 6c 72 65 61 64 79 20 65 78 69 73 74 73 7d 7d 0a  lready exists}}.
0ea0: 0a 64 62 32 20 63 6c 6f 73 65 0a 0a 64 6f 5f 74  .db2 close..do_t
0eb0: 65 73 74 20 63 6f 72 72 75 70 74 32 2d 33 2e 31  est corrupt2-3.1
0ec0: 20 7b 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65   {.  forcedelete
0ed0: 20 63 6f 72 72 75 70 74 2e 64 62 0a 20 20 66 6f   corrupt.db.  fo
0ee0: 72 63 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70  rcedelete corrup
0ef0: 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 73  t.db-journal.  s
0f00: 71 6c 69 74 65 33 20 64 62 32 20 63 6f 72 72 75  qlite3 db2 corru
0f10: 70 74 2e 64 62 20 0a 0a 20 20 65 78 65 63 73 71  pt.db ..  execsq
0f20: 6c 20 22 0a 20 20 20 20 24 3a 3a 70 72 65 73 71  l ".    $::presq
0f30: 6c 0a 20 20 20 20 50 52 41 47 4d 41 20 61 75 74  l.    PRAGMA aut
0f40: 6f 5f 76 61 63 75 75 6d 20 3d 20 31 3b 0a 20 20  o_vacuum = 1;.  
0f50: 20 20 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69    PRAGMA page_si
0f60: 7a 65 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 43  ze = 1024;.    C
0f70: 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61  REATE TABLE t1(a
0f80: 2c 20 62 2c 20 63 29 3b 0a 20 20 20 20 43 52 45  , b, c);.    CRE
0f90: 41 54 45 20 54 41 42 4c 45 20 74 32 28 61 2c 20  ATE TABLE t2(a, 
0fa0: 62 2c 20 63 29 3b 0a 20 20 20 20 49 4e 53 45 52  b, c);.    INSER
0fb0: 54 20 49 4e 54 4f 20 74 32 20 56 41 4c 55 45 53  T INTO t2 VALUES
0fc0: 28 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29  (randomblob(100)
0fd0: 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30  , randomblob(100
0fe0: 29 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30  ), randomblob(10
0ff0: 30 29 29 3b 0a 20 20 20 20 49 4e 53 45 52 54 20  0));.    INSERT 
1000: 49 4e 54 4f 20 74 32 20 53 45 4c 45 43 54 20 2a  INTO t2 SELECT *
1010: 20 46 52 4f 4d 20 74 32 3b 0a 20 20 20 20 49 4e   FROM t2;.    IN
1020: 53 45 52 54 20 49 4e 54 4f 20 74 32 20 53 45 4c  SERT INTO t2 SEL
1030: 45 43 54 20 2a 20 46 52 4f 4d 20 74 32 3b 0a 20  ECT * FROM t2;. 
1040: 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74     INSERT INTO t
1050: 32 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20  2 SELECT * FROM 
1060: 74 32 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49  t2;.    INSERT I
1070: 4e 54 4f 20 74 32 20 53 45 4c 45 43 54 20 2a 20  NTO t2 SELECT * 
1080: 46 52 4f 4d 20 74 32 3b 0a 20 20 22 20 64 62 32  FROM t2;.  " db2
1090: 0a 0a 20 20 64 62 32 20 63 6c 6f 73 65 0a 0a 20  ..  db2 close.. 
10a0: 20 23 20 4f 6e 20 74 68 65 20 72 6f 6f 74 20 70   # On the root p
10b0: 61 67 65 20 6f 66 20 74 61 62 6c 65 20 74 32 20  age of table t2 
10c0: 28 70 61 67 65 20 34 29 2c 20 73 65 74 20 6f 6e  (page 4), set on
10d0: 65 20 6f 66 20 74 68 65 20 63 68 69 6c 64 20 70  e of the child p
10e0: 61 67 65 2d 6e 75 6d 62 65 72 73 0a 20 20 23 20  age-numbers.  # 
10f0: 74 6f 20 30 2e 20 54 68 69 73 20 63 6f 72 72 75  to 0. This corru
1100: 70 74 69 6f 6e 20 77 69 6c 6c 20 62 65 20 64 65  ption will be de
1110: 74 65 63 74 65 64 20 77 68 65 6e 20 53 51 4c 69  tected when SQLi
1120: 74 65 20 61 74 74 65 6d 70 74 73 20 74 6f 20 75  te attempts to u
1130: 70 64 61 74 65 0a 20 20 23 20 74 68 65 20 70 6f  pdate.  # the po
1140: 69 6e 74 65 72 2d 6d 61 70 20 61 66 74 65 72 20  inter-map after 
1150: 6d 6f 76 69 6e 67 20 74 68 65 20 63 6f 6e 74 65  moving the conte
1160: 6e 74 20 6f 66 20 70 61 67 65 20 34 20 74 6f 20  nt of page 4 to 
1170: 70 61 67 65 20 33 20 61 73 20 70 61 72 74 0a 20  page 3 as part. 
1180: 20 23 20 6f 66 20 74 68 65 20 44 52 4f 50 20 54   # of the DROP T
1190: 41 42 4c 45 20 6f 70 65 72 61 74 69 6f 6e 20 62  ABLE operation b
11a0: 65 6c 6f 77 2e 0a 20 20 23 0a 20 20 73 65 74 20  elow..  #.  set 
11b0: 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74  fd [open corrupt
11c0: 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e 66 69  .db r+].  fconfi
11d0: 67 75 72 65 20 24 66 64 20 2d 65 6e 63 6f 64 69  gure $fd -encodi
11e0: 6e 67 20 62 69 6e 61 72 79 20 2d 74 72 61 6e 73  ng binary -trans
11f0: 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20  lation binary.  
1200: 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20 31  seek $fd [expr 1
1210: 30 32 34 2a 33 20 2b 20 31 32 5d 0a 20 20 73 65  024*3 + 12].  se
1220: 74 20 7a 43 65 6c 6c 6f 66 66 73 65 74 20 5b 72  t zCelloffset [r
1230: 65 61 64 20 24 66 64 20 32 5d 0a 20 20 62 69 6e  ead $fd 2].  bin
1240: 61 72 79 20 73 63 61 6e 20 24 7a 43 65 6c 6c 6f  ary scan $zCello
1250: 66 66 73 65 74 20 53 20 69 43 65 6c 6c 6f 66 66  ffset S iCelloff
1260: 73 65 74 0a 20 20 73 65 65 6b 20 24 66 64 20 5b  set.  seek $fd [
1270: 65 78 70 72 20 31 30 32 34 2a 33 20 2b 20 24 69  expr 1024*3 + $i
1280: 43 65 6c 6c 6f 66 66 73 65 74 5d 0a 20 20 70 75  Celloffset].  pu
1290: 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66  ts -nonewline $f
12a0: 64 20 22 5c 30 30 5c 30 30 5c 30 30 5c 30 30 22  d "\00\00\00\00"
12b0: 20 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 0a 20   .  close $fd.. 
12c0: 20 73 71 6c 69 74 65 33 20 64 62 32 20 63 6f 72   sqlite3 db2 cor
12d0: 72 75 70 74 2e 64 62 20 0a 20 20 63 61 74 63 68  rupt.db .  catch
12e0: 73 71 6c 20 22 0a 20 20 20 20 24 3a 3a 70 72 65  sql ".    $::pre
12f0: 73 71 6c 0a 20 20 20 20 44 52 4f 50 20 54 41 42  sql.    DROP TAB
1300: 4c 45 20 74 31 3b 0a 20 20 22 20 64 62 32 0a 7d  LE t1;.  " db2.}
1310: 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20 64 69   {1 {database di
1320: 73 6b 20 69 6d 61 67 65 20 69 73 20 6d 61 6c 66  sk image is malf
1330: 6f 72 6d 65 64 7d 7d 0a 0a 64 6f 5f 74 65 73 74  ormed}}..do_test
1340: 20 63 6f 72 72 75 70 74 32 2d 34 2e 31 20 7b 0a   corrupt2-4.1 {.
1350: 20 20 63 61 74 63 68 73 71 6c 20 7b 0a 20 20 20    catchsql {.   
1360: 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74   SELECT * FROM t
1370: 32 3b 0a 20 20 7d 20 64 62 32 0a 7d 20 7b 31 20  2;.  } db2.} {1 
1380: 7b 64 61 74 61 62 61 73 65 20 64 69 73 6b 20 69  {database disk i
1390: 6d 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65  mage is malforme
13a0: 64 7d 7d 0a 0a 64 62 32 20 63 6c 6f 73 65 0a 0a  d}}..db2 close..
13b0: 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69  unset -nocomplai
13c0: 6e 20 72 65 73 75 6c 74 0a 64 6f 5f 74 65 73 74  n result.do_test
13d0: 20 63 6f 72 72 75 70 74 32 2d 35 2e 31 20 7b 0a   corrupt2-5.1 {.
13e0: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63 6f    forcedelete co
13f0: 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63 65  rrupt.db.  force
1400: 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e 64  delete corrupt.d
1410: 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 73 71 6c 69  b-journal.  sqli
1420: 74 65 33 20 64 62 32 20 63 6f 72 72 75 70 74 2e  te3 db2 corrupt.
1430: 64 62 20 0a 0a 20 20 65 78 65 63 73 71 6c 20 22  db ..  execsql "
1440: 0a 20 20 20 20 24 3a 3a 70 72 65 73 71 6c 0a 20  .    $::presql. 
1450: 20 20 20 50 52 41 47 4d 41 20 61 75 74 6f 5f 76     PRAGMA auto_v
1460: 61 63 75 75 6d 20 3d 20 30 3b 0a 20 20 20 20 50  acuum = 0;.    P
1470: 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65 20  RAGMA page_size 
1480: 3d 20 31 30 32 34 3b 0a 20 20 20 20 43 52 45 41  = 1024;.    CREA
1490: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 20 62  TE TABLE t1(a, b
14a0: 2c 20 63 29 3b 0a 20 20 20 20 43 52 45 41 54 45  , c);.    CREATE
14b0: 20 54 41 42 4c 45 20 74 32 28 61 2c 20 62 2c 20   TABLE t2(a, b, 
14c0: 63 29 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49  c);.    INSERT I
14d0: 4e 54 4f 20 74 32 20 56 41 4c 55 45 53 28 72 61  NTO t2 VALUES(ra
14e0: 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 2c 20 72  ndomblob(100), r
14f0: 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 2c 20  andomblob(100), 
1500: 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 29  randomblob(100))
1510: 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  ;.    INSERT INT
1520: 4f 20 74 32 20 53 45 4c 45 43 54 20 2a 20 46 52  O t2 SELECT * FR
1530: 4f 4d 20 74 32 3b 0a 20 20 20 20 49 4e 53 45 52  OM t2;.    INSER
1540: 54 20 49 4e 54 4f 20 74 32 20 53 45 4c 45 43 54  T INTO t2 SELECT
1550: 20 2a 20 46 52 4f 4d 20 74 32 3b 0a 20 20 20 20   * FROM t2;.    
1560: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 32 20 53  INSERT INTO t2 S
1570: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 32 3b  ELECT * FROM t2;
1580: 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  .    INSERT INTO
1590: 20 74 32 20 53 45 4c 45 43 54 20 2a 20 46 52 4f   t2 SELECT * FRO
15a0: 4d 20 74 32 3b 0a 20 20 20 20 49 4e 53 45 52 54  M t2;.    INSERT
15b0: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
15c0: 2a 20 46 52 4f 4d 20 74 32 3b 0a 20 20 22 20 64  * FROM t2;.  " d
15d0: 62 32 0a 0a 20 20 64 62 32 20 63 6c 6f 73 65 0a  b2..  db2 close.
15e0: 0a 20 20 23 20 54 68 69 73 20 62 6c 6f 63 6b 20  .  # This block 
15f0: 6c 69 6e 6b 73 20 61 20 70 61 67 65 20 66 72 6f  links a page fro
1600: 6d 20 74 61 62 6c 65 20 74 32 20 69 6e 74 6f 20  m table t2 into 
1610: 74 68 65 20 74 31 20 74 61 62 6c 65 20 73 74 72  the t1 table str
1620: 75 63 74 75 72 65 2e 0a 20 20 23 0a 20 20 73 65  ucture..  #.  se
1630: 74 20 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75  t fd [open corru
1640: 70 74 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e  pt.db r+].  fcon
1650: 66 69 67 75 72 65 20 24 66 64 20 2d 65 6e 63 6f  figure $fd -enco
1660: 64 69 6e 67 20 62 69 6e 61 72 79 20 2d 74 72 61  ding binary -tra
1670: 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a  nslation binary.
1680: 20 20 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72    seek $fd [expr
1690: 20 31 30 32 34 20 2b 20 31 32 5d 0a 20 20 73 65   1024 + 12].  se
16a0: 74 20 7a 43 65 6c 6c 6f 66 66 73 65 74 20 5b 72  t zCelloffset [r
16b0: 65 61 64 20 24 66 64 20 32 5d 0a 20 20 62 69 6e  ead $fd 2].  bin
16c0: 61 72 79 20 73 63 61 6e 20 24 7a 43 65 6c 6c 6f  ary scan $zCello
16d0: 66 66 73 65 74 20 53 20 69 43 65 6c 6c 6f 66 66  ffset S iCelloff
16e0: 73 65 74 0a 20 20 73 65 65 6b 20 24 66 64 20 5b  set.  seek $fd [
16f0: 65 78 70 72 20 31 30 32 34 20 2b 20 24 69 43 65  expr 1024 + $iCe
1700: 6c 6c 6f 66 66 73 65 74 5d 0a 20 20 73 65 74 20  lloffset].  set 
1710: 7a 43 68 69 6c 64 50 61 67 65 20 5b 72 65 61 64  zChildPage [read
1720: 20 24 66 64 20 34 5d 0a 20 20 73 65 65 6b 20 24   $fd 4].  seek $
1730: 66 64 20 5b 65 78 70 72 20 32 2a 31 30 32 34 20  fd [expr 2*1024 
1740: 2b 20 31 32 5d 0a 20 20 73 65 74 20 7a 43 65 6c  + 12].  set zCel
1750: 6c 6f 66 66 73 65 74 20 5b 72 65 61 64 20 24 66  loffset [read $f
1760: 64 20 32 5d 0a 20 20 62 69 6e 61 72 79 20 73 63  d 2].  binary sc
1770: 61 6e 20 24 7a 43 65 6c 6c 6f 66 66 73 65 74 20  an $zCelloffset 
1780: 53 20 69 43 65 6c 6c 6f 66 66 73 65 74 0a 20 20  S iCelloffset.  
1790: 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20 32  seek $fd [expr 2
17a0: 2a 31 30 32 34 20 2b 20 24 69 43 65 6c 6c 6f 66  *1024 + $iCellof
17b0: 66 73 65 74 5d 0a 20 20 70 75 74 73 20 2d 6e 6f  fset].  puts -no
17c0: 6e 65 77 6c 69 6e 65 20 24 66 64 20 24 7a 43 68  newline $fd $zCh
17d0: 69 6c 64 50 61 67 65 0a 20 20 63 6c 6f 73 65 20  ildPage.  close 
17e0: 24 66 64 0a 0a 20 20 73 71 6c 69 74 65 33 20 64  $fd..  sqlite3 d
17f0: 62 32 20 63 6f 72 72 75 70 74 2e 64 62 20 0a 20  b2 corrupt.db . 
1800: 20 64 62 32 20 65 76 61 6c 20 24 3a 3a 70 72 65   db2 eval $::pre
1810: 73 71 6c 0a 20 20 64 62 32 20 65 76 61 6c 20 7b  sql.  db2 eval {
1820: 53 45 4c 45 43 54 20 72 6f 77 69 64 20 46 52 4f  SELECT rowid FRO
1830: 4d 20 74 31 7d 20 7b 0a 20 20 20 20 73 65 74 20  M t1} {.    set 
1840: 72 65 73 75 6c 74 20 5b 64 62 32 20 65 76 61 6c  result [db2 eval
1850: 20 7b 70 72 61 67 6d 61 20 69 6e 74 65 67 72 69   {pragma integri
1860: 74 79 5f 63 68 65 63 6b 7d 5d 0a 20 20 20 20 62  ty_check}].    b
1870: 72 65 61 6b 0a 20 20 7d 0a 20 20 73 65 74 20 72  reak.  }.  set r
1880: 65 73 75 6c 74 0a 7d 20 7b 7b 2a 2a 2a 20 69 6e  esult.} {{*** in
1890: 20 64 61 74 61 62 61 73 65 20 6d 61 69 6e 20 2a   database main *
18a0: 2a 2a 0a 4f 6e 20 74 72 65 65 20 70 61 67 65 20  **.On tree page 
18b0: 32 20 63 65 6c 6c 20 30 3a 20 32 6e 64 20 72 65  2 cell 0: 2nd re
18c0: 66 65 72 65 6e 63 65 20 74 6f 20 70 61 67 65 20  ference to page 
18d0: 31 30 0a 50 61 67 65 20 34 20 69 73 20 6e 65 76  10.Page 4 is nev
18e0: 65 72 20 75 73 65 64 7d 7d 0a 0a 64 62 32 20 63  er used}}..db2 c
18f0: 6c 6f 73 65 0a 0a 70 72 6f 63 20 63 6f 72 72 75  lose..proc corru
1900: 70 74 69 6f 6e 5f 74 65 73 74 20 7b 61 72 67 73  ption_test {args
1910: 7d 20 7b 0a 20 20 73 65 74 20 41 28 2d 63 6f 72  } {.  set A(-cor
1920: 72 75 70 74 29 20 7b 7d 0a 20 20 73 65 74 20 41  rupt) {}.  set A
1930: 28 2d 73 71 6c 70 72 65 70 29 20 7b 7d 0a 20 20  (-sqlprep) {}.  
1940: 73 65 74 20 41 28 2d 74 63 6c 70 72 65 70 29 20  set A(-tclprep) 
1950: 7b 7d 0a 20 20 61 72 72 61 79 20 73 65 74 20 41  {}.  array set A
1960: 20 24 61 72 67 73 0a 0a 20 20 63 61 74 63 68 20   $args..  catch 
1970: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66 6f 72  {db close}.  for
1980: 63 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74  cedelete corrupt
1990: 2e 64 62 0a 20 20 66 6f 72 63 65 64 65 6c 65 74  .db.  forcedelet
19a0: 65 20 63 6f 72 72 75 70 74 2e 64 62 2d 6a 6f 75  e corrupt.db-jou
19b0: 72 6e 61 6c 0a 0a 20 20 73 71 6c 69 74 65 33 20  rnal..  sqlite3 
19c0: 64 62 20 63 6f 72 72 75 70 74 2e 64 62 20 0a 20  db corrupt.db . 
19d0: 20 64 62 20 65 76 61 6c 20 24 3a 3a 70 72 65 73   db eval $::pres
19e0: 71 6c 0a 20 20 65 76 61 6c 20 24 41 28 2d 74 63  ql.  eval $A(-tc
19f0: 6c 70 72 65 70 29 0a 20 20 64 62 20 65 76 61 6c  lprep).  db eval
1a00: 20 24 41 28 2d 73 71 6c 70 72 65 70 29 0a 20 20   $A(-sqlprep).  
1a10: 64 62 20 63 6c 6f 73 65 0a 0a 20 20 65 76 61 6c  db close..  eval
1a20: 20 24 41 28 2d 63 6f 72 72 75 70 74 29 0a 0a 20   $A(-corrupt).. 
1a30: 20 73 71 6c 69 74 65 33 20 64 62 20 63 6f 72 72   sqlite3 db corr
1a40: 75 70 74 2e 64 62 0a 20 20 65 76 61 6c 20 24 41  upt.db.  eval $A
1a50: 28 2d 74 65 73 74 29 0a 7d 0a 0a 69 66 63 61 70  (-test).}..ifcap
1a60: 61 62 6c 65 20 61 75 74 6f 76 61 63 75 75 6d 20  able autovacuum 
1a70: 7b 0a 20 20 23 20 54 68 65 20 74 65 73 74 73 20  {.  # The tests 
1a80: 77 69 74 68 69 6e 20 74 68 69 73 20 62 6c 6f 63  within this bloc
1a90: 6b 20 2d 20 63 6f 72 72 75 70 74 32 2d 36 2e 2a  k - corrupt2-6.*
1aa0: 20 2d 20 61 69 6d 20 74 6f 20 74 65 73 74 20 63   - aim to test c
1ab0: 6f 72 72 75 70 74 69 6f 6e 0a 20 20 23 20 64 65  orruption.  # de
1ac0: 74 65 63 74 69 6f 6e 20 77 69 74 68 69 6e 20 61  tection within a
1ad0: 6e 20 69 6e 63 72 65 6d 65 6e 74 61 6c 2d 76 61  n incremental-va
1ae0: 63 75 75 6d 2e 20 57 68 65 6e 20 61 6e 20 69 6e  cuum. When an in
1af0: 63 72 65 6d 65 6e 74 61 6c 2d 76 61 63 75 75 6d  cremental-vacuum
1b00: 0a 20 20 23 20 73 74 65 70 20 69 73 20 65 78 65  .  # step is exe
1b10: 63 75 74 65 64 2c 20 74 68 65 20 6c 61 73 74 20  cuted, the last 
1b20: 6e 6f 6e 2d 66 72 65 65 20 70 61 67 65 20 6f 66  non-free page of
1b30: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
1b40: 6c 65 20 69 73 20 0a 20 20 23 20 6d 6f 76 65 64  le is .  # moved
1b50: 20 69 6e 74 6f 20 61 20 66 72 65 65 20 73 70 61   into a free spa
1b60: 63 65 20 69 6e 20 74 68 65 20 62 6f 64 79 20 6f  ce in the body o
1b70: 66 20 74 68 65 20 66 69 6c 65 2e 20 41 66 74 65  f the file. Afte
1b80: 72 20 64 6f 69 6e 67 20 73 6f 2c 0a 20 20 23 20  r doing so,.  # 
1b90: 74 68 65 20 70 61 67 65 20 72 65 66 65 72 65 6e  the page referen
1ba0: 63 65 20 69 6e 20 74 68 65 20 70 61 72 65 6e 74  ce in the parent
1bb0: 20 70 61 67 65 20 6d 75 73 74 20 62 65 20 75 70   page must be up
1bc0: 64 61 74 65 64 20 74 6f 20 72 65 66 65 72 0a 20  dated to refer. 
1bd0: 20 23 20 74 6f 20 74 68 65 20 6e 65 77 20 6c 6f   # to the new lo
1be0: 63 61 74 69 6f 6e 2e 20 54 68 65 73 65 20 74 65  cation. These te
1bf0: 73 74 73 20 74 65 73 74 20 74 68 65 20 6f 75 74  sts test the out
1c00: 63 6f 6d 65 20 6f 66 20 63 6f 72 72 75 70 74 69  come of corrupti
1c10: 6e 67 0a 20 20 23 20 74 68 61 74 20 70 61 67 65  ng.  # that page
1c20: 20 72 65 66 65 72 65 6e 63 65 20 62 65 66 6f 72   reference befor
1c30: 65 20 70 65 72 66 6f 72 6d 69 6e 67 20 74 68 65  e performing the
1c40: 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 76 61 63   incremental vac
1c50: 75 75 6d 2e 0a 20 20 23 0a 0a 20 20 23 20 54 68  uum..  #..  # Th
1c60: 65 20 6c 61 73 74 20 70 61 67 65 20 69 6e 20 74  e last page in t
1c70: 68 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65  he database page
1c80: 20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20 70   is the second p
1c90: 61 67 65 20 0a 20 20 23 20 69 6e 20 61 6e 20 6f  age .  # in an o
1ca0: 76 65 72 66 6c 6f 77 20 63 68 61 69 6e 2e 0a 20  verflow chain.. 
1cb0: 20 23 0a 20 20 63 6f 72 72 75 70 74 69 6f 6e 5f   #.  corruption_
1cc0: 74 65 73 74 20 2d 73 71 6c 70 72 65 70 20 7b 0a  test -sqlprep {.
1cd0: 20 20 20 20 50 52 41 47 4d 41 20 61 75 74 6f 5f      PRAGMA auto_
1ce0: 76 61 63 75 75 6d 20 3d 20 69 6e 63 72 65 6d 65  vacuum = increme
1cf0: 6e 74 61 6c 3b 0a 20 20 20 20 50 52 41 47 4d 41  ntal;.    PRAGMA
1d00: 20 70 61 67 65 5f 73 69 7a 65 20 3d 20 31 30 32   page_size = 102
1d10: 34 3b 0a 20 20 20 20 43 52 45 41 54 45 20 54 41  4;.    CREATE TA
1d20: 42 4c 45 20 74 31 28 61 2c 20 62 29 3b 0a 20 20  BLE t1(a, b);.  
1d30: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
1d40: 20 56 41 4c 55 45 53 28 31 2c 20 72 61 6e 64 6f   VALUES(1, rando
1d50: 6d 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20  mblob(2500));.  
1d60: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
1d70: 20 56 41 4c 55 45 53 28 32 2c 20 72 61 6e 64 6f   VALUES(2, rando
1d80: 6d 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20  mblob(2500));.  
1d90: 20 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31    DELETE FROM t1
1da0: 20 57 48 45 52 45 20 61 20 3d 20 31 3b 0a 20 20   WHERE a = 1;.  
1db0: 7d 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 20  } -corrupt {.   
1dc0: 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63 6f 72   hexio_write cor
1dd0: 72 75 70 74 2e 64 62 20 5b 65 78 70 72 20 31 30  rupt.db [expr 10
1de0: 32 34 2a 35 5d 20 30 30 30 30 30 30 30 38 0a 20  24*5] 00000008. 
1df0: 20 7d 20 2d 74 65 73 74 20 7b 0a 20 20 20 20 64   } -test {.    d
1e00: 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d  o_test corrupt2-
1e10: 36 2e 31 20 7b 0a 20 20 20 20 20 20 63 61 74 63  6.1 {.      catc
1e20: 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c  hsql " $::presql
1e30: 20 70 72 61 67 6d 61 20 69 6e 63 72 65 6d 65 6e   pragma incremen
1e40: 74 61 6c 5f 76 61 63 75 75 6d 20 3d 20 31 20 22  tal_vacuum = 1 "
1e50: 0a 20 20 20 20 7d 20 7b 31 20 7b 64 61 74 61 62  .    } {1 {datab
1e60: 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69  ase disk image i
1e70: 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20  s malformed}}.  
1e80: 7d 0a 0a 20 20 23 20 54 68 65 20 6c 61 73 74 20  }..  # The last 
1e90: 70 61 67 65 20 69 6e 20 74 68 65 20 64 61 74 61  page in the data
1ea0: 62 61 73 65 20 70 61 67 65 20 69 73 20 61 20 6e  base page is a n
1eb0: 6f 6e 2d 72 6f 6f 74 20 62 2d 74 72 65 65 20 70  on-root b-tree p
1ec0: 61 67 65 2e 0a 20 20 23 0a 20 20 63 6f 72 72 75  age..  #.  corru
1ed0: 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c 70  ption_test -sqlp
1ee0: 72 65 70 20 7b 0a 20 20 20 20 50 52 41 47 4d 41  rep {.    PRAGMA
1ef0: 20 61 75 74 6f 5f 76 61 63 75 75 6d 20 3d 20 69   auto_vacuum = i
1f00: 6e 63 72 65 6d 65 6e 74 61 6c 3b 0a 20 20 20 20  ncremental;.    
1f10: 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65  PRAGMA page_size
1f20: 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 43 52 45   = 1024;.    CRE
1f30: 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49  ATE TABLE t1(a I
1f40: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b  NTEGER PRIMARY K
1f50: 45 59 2c 20 62 29 3b 0a 20 20 20 20 49 4e 53 45  EY, b);.    INSE
1f60: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
1f70: 53 28 31 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  S(1, randomblob(
1f80: 32 35 30 30 29 29 3b 0a 20 20 20 20 49 4e 53 45  2500));.    INSE
1f90: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
1fa0: 53 28 32 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  S(2, randomblob(
1fb0: 35 30 29 29 3b 0a 20 20 20 20 49 4e 53 45 52 54  50));.    INSERT
1fc0: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
1fd0: 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  NULL, randomblob
1fe0: 28 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20  (50) FROM t1;.  
1ff0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
2000: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
2010: 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f  ndomblob(50) FRO
2020: 4d 20 74 31 3b 0a 20 20 20 20 49 4e 53 45 52 54  M t1;.    INSERT
2030: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
2040: 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  NULL, randomblob
2050: 28 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20  (50) FROM t1;.  
2060: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
2070: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
2080: 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f  ndomblob(50) FRO
2090: 4d 20 74 31 3b 0a 20 20 20 20 44 45 4c 45 54 45  M t1;.    DELETE
20a0: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 61   FROM t1 WHERE a
20b0: 20 3d 20 31 3b 0a 20 20 7d 20 2d 63 6f 72 72 75   = 1;.  } -corru
20c0: 70 74 20 7b 0a 20 20 20 20 68 65 78 69 6f 5f 77  pt {.    hexio_w
20d0: 72 69 74 65 20 63 6f 72 72 75 70 74 2e 64 62 20  rite corrupt.db 
20e0: 5b 65 78 70 72 20 31 30 32 34 2a 32 20 2b 20 38  [expr 1024*2 + 8
20f0: 5d 20 30 30 30 30 30 30 30 39 0a 20 20 7d 20 2d  ] 00000009.  } -
2100: 74 65 73 74 20 7b 0a 20 20 20 20 64 6f 5f 74 65  test {.    do_te
2110: 73 74 20 63 6f 72 72 75 70 74 32 2d 36 2e 32 20  st corrupt2-6.2 
2120: 7b 0a 20 20 20 20 20 20 63 61 74 63 68 73 71 6c  {.      catchsql
2130: 20 22 20 24 3a 3a 70 72 65 73 71 6c 20 70 72 61   " $::presql pra
2140: 67 6d 61 20 69 6e 63 72 65 6d 65 6e 74 61 6c 5f  gma incremental_
2150: 76 61 63 75 75 6d 20 3d 20 31 20 22 0a 20 20 20  vacuum = 1 ".   
2160: 20 7d 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20   } {1 {database 
2170: 64 69 73 6b 20 69 6d 61 67 65 20 69 73 20 6d 61  disk image is ma
2180: 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20 7d 0a 0a 20  lformed}}.  }.. 
2190: 20 23 20 53 65 74 20 75 70 20 61 20 70 6f 69 6e   # Set up a poin
21a0: 74 65 72 2d 6d 61 70 20 65 6e 74 72 79 20 73 6f  ter-map entry so
21b0: 20 74 68 61 74 20 74 68 65 20 6c 61 73 74 20 70   that the last p
21c0: 61 67 65 20 6f 66 20 74 68 65 20 64 61 74 61 62  age of the datab
21d0: 61 73 65 0a 20 20 23 20 66 69 6c 65 20 61 70 70  ase.  # file app
21e0: 65 61 72 73 20 74 6f 20 62 65 20 61 20 62 2d 74  ears to be a b-t
21f0: 72 65 65 20 72 6f 6f 74 20 70 61 67 65 2e 20 54  ree root page. T
2200: 68 69 73 20 73 68 6f 75 6c 64 20 62 65 20 64 65  his should be de
2210: 74 65 63 74 65 64 0a 20 20 23 20 61 73 20 63 6f  tected.  # as co
2220: 72 72 75 70 74 69 6f 6e 2e 0a 20 20 23 0a 20 20  rruption..  #.  
2230: 63 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20  corruption_test 
2240: 2d 73 71 6c 70 72 65 70 20 7b 0a 20 20 20 20 50  -sqlprep {.    P
2250: 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75  RAGMA auto_vacuu
2260: 6d 20 3d 20 69 6e 63 72 65 6d 65 6e 74 61 6c 3b  m = incremental;
2270: 0a 20 20 20 20 50 52 41 47 4d 41 20 70 61 67 65  .    PRAGMA page
2280: 5f 73 69 7a 65 20 3d 20 31 30 32 34 3b 0a 20 20  _size = 1024;.  
2290: 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74    CREATE TABLE t
22a0: 31 28 61 20 49 4e 54 45 47 45 52 20 50 52 49 4d  1(a INTEGER PRIM
22b0: 41 52 59 20 4b 45 59 2c 20 62 29 3b 0a 20 20 20  ARY KEY, b);.   
22c0: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
22d0: 56 41 4c 55 45 53 28 31 2c 20 72 61 6e 64 6f 6d  VALUES(1, random
22e0: 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20 20  blob(2500));.   
22f0: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
2300: 56 41 4c 55 45 53 28 32 2c 20 72 61 6e 64 6f 6d  VALUES(2, random
2310: 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20 20  blob(2500));.   
2320: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
2330: 56 41 4c 55 45 53 28 33 2c 20 72 61 6e 64 6f 6d  VALUES(3, random
2340: 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20 20  blob(2500));.   
2350: 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31 20   DELETE FROM t1 
2360: 57 48 45 52 45 20 61 20 3d 20 31 3b 0a 20 20 7d  WHERE a = 1;.  }
2370: 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 20 20   -corrupt {.    
2380: 73 65 74 20 6e 50 61 67 65 20 5b 65 78 70 72 20  set nPage [expr 
2390: 5b 66 69 6c 65 20 73 69 7a 65 20 63 6f 72 72 75  [file size corru
23a0: 70 74 2e 64 62 5d 20 2f 20 31 30 32 34 5d 0a 20  pt.db] / 1024]. 
23b0: 20 20 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63     hexio_write c
23c0: 6f 72 72 75 70 74 2e 64 62 20 5b 65 78 70 72 20  orrupt.db [expr 
23d0: 31 30 32 34 20 2b 20 28 24 6e 50 61 67 65 2d 33  1024 + ($nPage-3
23e0: 29 2a 35 5d 20 30 31 30 30 30 30 30 30 30 0a 20  )*5] 010000000. 
23f0: 20 7d 20 2d 74 65 73 74 20 7b 0a 20 20 20 20 64   } -test {.    d
2400: 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d  o_test corrupt2-
2410: 36 2e 33 20 7b 0a 20 20 20 20 20 20 63 61 74 63  6.3 {.      catc
2420: 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c  hsql " $::presql
2430: 20 70 72 61 67 6d 61 20 69 6e 63 72 65 6d 65 6e   pragma incremen
2440: 74 61 6c 5f 76 61 63 75 75 6d 20 3d 20 31 20 22  tal_vacuum = 1 "
2450: 0a 20 20 20 20 7d 20 7b 31 20 7b 64 61 74 61 62  .    } {1 {datab
2460: 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69  ase disk image i
2470: 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20  s malformed}}.  
2480: 7d 0a 0a 20 20 63 6f 72 72 75 70 74 69 6f 6e 5f  }..  corruption_
2490: 74 65 73 74 20 2d 73 71 6c 70 72 65 70 20 7b 0a  test -sqlprep {.
24a0: 20 20 20 20 50 52 41 47 4d 41 20 61 75 74 6f 5f      PRAGMA auto_
24b0: 76 61 63 75 75 6d 20 3d 20 31 3b 0a 20 20 20 20  vacuum = 1;.    
24c0: 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65  PRAGMA page_size
24d0: 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 43 52 45   = 1024;.    CRE
24e0: 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49  ATE TABLE t1(a I
24f0: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b  NTEGER PRIMARY K
2500: 45 59 2c 20 62 29 3b 0a 20 20 20 20 49 4e 53 45  EY, b);.    INSE
2510: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
2520: 53 28 31 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  S(1, randomblob(
2530: 32 35 30 30 29 29 3b 0a 20 20 20 20 44 45 4c 45  2500));.    DELE
2540: 54 45 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45  TE FROM t1 WHERE
2550: 20 61 20 3d 20 31 3b 0a 20 20 7d 20 2d 63 6f 72   a = 1;.  } -cor
2560: 72 75 70 74 20 7b 0a 20 20 20 20 73 65 74 20 6e  rupt {.    set n
2570: 41 70 70 65 6e 64 20 5b 65 78 70 72 20 31 30 32  Append [expr 102
2580: 34 2a 32 30 37 20 2d 20 5b 66 69 6c 65 20 73 69  4*207 - [file si
2590: 7a 65 20 63 6f 72 72 75 70 74 2e 64 62 5d 5d 0a  ze corrupt.db]].
25a0: 20 20 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e      set fd [open
25b0: 20 63 6f 72 72 75 70 74 2e 64 62 20 72 2b 5d 0a   corrupt.db r+].
25c0: 20 20 20 20 73 65 65 6b 20 24 66 64 20 30 20 65      seek $fd 0 e
25d0: 6e 64 0a 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e  nd.    puts -non
25e0: 65 77 6c 69 6e 65 20 24 66 64 20 5b 73 74 72 69  ewline $fd [stri
25f0: 6e 67 20 72 65 70 65 61 74 20 78 20 24 6e 41 70  ng repeat x $nAp
2600: 70 65 6e 64 5d 0a 20 20 20 20 63 6c 6f 73 65 20  pend].    close 
2610: 24 66 64 0a 20 20 20 20 68 65 78 69 6f 5f 77 72  $fd.    hexio_wr
2620: 69 74 65 20 63 6f 72 72 75 70 74 2e 64 62 20 32  ite corrupt.db 2
2630: 38 20 30 30 30 30 30 30 30 30 0a 20 20 7d 20 2d  8 00000000.  } -
2640: 74 65 73 74 20 7b 0a 20 20 20 20 64 6f 5f 74 65  test {.    do_te
2650: 73 74 20 63 6f 72 72 75 70 74 32 2d 36 2e 34 20  st corrupt2-6.4 
2660: 7b 0a 20 20 20 20 20 20 63 61 74 63 68 73 71 6c  {.      catchsql
2670: 20 22 20 0a 20 20 20 20 20 20 20 20 24 3a 3a 70   " .        $::p
2680: 72 65 73 71 6c 20 0a 20 20 20 20 20 20 20 20 42  resql .        B
2690: 45 47 49 4e 20 45 58 43 4c 55 53 49 56 45 3b 0a  EGIN EXCLUSIVE;.
26a0: 20 20 20 20 20 20 20 20 43 4f 4d 4d 49 54 3b 0a          COMMIT;.
26b0: 20 20 20 20 20 20 22 0a 20 20 20 20 7d 20 7b 31        ".    } {1
26c0: 20 7b 64 61 74 61 62 61 73 65 20 64 69 73 6b 20   {database disk 
26d0: 69 6d 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d  image is malform
26e0: 65 64 7d 7d 0a 20 20 7d 0a 7d 0a 0a 0a 73 65 74  ed}}.  }.}...set
26f0: 20 73 71 6c 70 72 65 70 20 7b 0a 20 20 50 52 41   sqlprep {.  PRA
2700: 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75 6d 20  GMA auto_vacuum 
2710: 3d 20 30 3b 0a 20 20 50 52 41 47 4d 41 20 70 61  = 0;.  PRAGMA pa
2720: 67 65 5f 73 69 7a 65 20 3d 20 31 30 32 34 3b 0a  ge_size = 1024;.
2730: 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74    CREATE TABLE t
2740: 31 28 61 20 49 4e 54 45 47 45 52 20 50 52 49 4d  1(a INTEGER PRIM
2750: 41 52 59 20 4b 45 59 2c 20 62 29 3b 0a 20 20 43  ARY KEY, b);.  C
2760: 52 45 41 54 45 20 49 4e 44 45 58 20 69 31 20 4f  REATE INDEX i1 O
2770: 4e 20 74 31 28 62 29 3b 0a 20 20 49 4e 53 45 52  N t1(b);.  INSER
2780: 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53  T INTO t1 VALUES
2790: 28 31 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 35  (1, randomblob(5
27a0: 30 29 29 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e  0));.  INSERT IN
27b0: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c  TO t1 SELECT NUL
27c0: 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 35 30  L, randomblob(50
27d0: 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53  ) FROM t1;.  INS
27e0: 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45  ERT INTO t1 SELE
27f0: 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62  CT NULL, randomb
2800: 6c 6f 62 28 35 30 29 20 46 52 4f 4d 20 74 31 3b  lob(50) FROM t1;
2810: 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74  .  INSERT INTO t
2820: 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72  1 SELECT NULL, r
2830: 61 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52  andomblob(50) FR
2840: 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54 20  OM t1;.  INSERT 
2850: 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e  INTO t1 SELECT N
2860: 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  ULL, randomblob(
2870: 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49  50) FROM t1;.  I
2880: 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45  NSERT INTO t1 SE
2890: 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 6f  LECT NULL, rando
28a0: 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f 4d 20 74  mblob(50) FROM t
28b0: 31 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  1;.  INSERT INTO
28c0: 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c   t1 SELECT NULL,
28d0: 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20   randomblob(50) 
28e0: 46 52 4f 4d 20 74 31 3b 0a 7d 0a 0a 63 6f 72 72  FROM t1;.}..corr
28f0: 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c  uption_test -sql
2900: 70 72 65 70 20 24 73 71 6c 70 72 65 70 20 2d 63  prep $sqlprep -c
2910: 6f 72 72 75 70 74 20 7b 0a 20 20 23 20 53 65 74  orrupt {.  # Set
2920: 20 74 68 65 20 70 61 67 65 2d 66 6c 61 67 73 20   the page-flags 
2930: 6f 66 20 6f 6e 65 20 6f 66 20 74 68 65 20 6c 65  of one of the le
2940: 61 66 20 70 61 67 65 73 20 6f 66 20 74 68 65 20  af pages of the 
2950: 69 6e 64 65 78 20 42 2d 54 72 65 65 20 74 6f 0a  index B-Tree to.
2960: 20 20 23 20 30 78 30 44 20 28 69 6e 74 65 72 70    # 0x0D (interp
2970: 72 65 74 65 64 20 62 79 20 53 51 4c 69 74 65 20  reted by SQLite 
2980: 61 73 20 22 6c 65 61 66 20 70 61 67 65 20 6f 66  as "leaf page of
2990: 20 61 20 74 61 62 6c 65 20 42 2d 54 72 65 65 22   a table B-Tree"
29a0: 29 2e 0a 20 20 23 0a 20 20 73 65 74 20 66 64 20  )..  #.  set fd 
29b0: 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e 64 62  [open corrupt.db
29c0: 20 72 2b 5d 0a 20 20 66 63 6f 6e 66 69 67 75 72   r+].  fconfigur
29d0: 65 20 24 66 64 20 2d 74 72 61 6e 73 6c 61 74 69  e $fd -translati
29e0: 6f 6e 20 62 69 6e 61 72 79 20 2d 65 6e 63 6f 64  on binary -encod
29f0: 69 6e 67 20 62 69 6e 61 72 79 0a 20 20 73 65 65  ing binary.  see
2a00: 6b 20 24 66 64 20 5b 65 78 70 72 20 31 30 32 34  k $fd [expr 1024
2a10: 2a 32 20 2b 20 38 5d 20 0a 20 20 73 65 74 20 7a  *2 + 8] .  set z
2a20: 52 69 67 68 74 43 68 69 6c 64 20 5b 72 65 61 64  RightChild [read
2a30: 20 24 66 64 20 34 5d 0a 20 20 62 69 6e 61 72 79   $fd 4].  binary
2a40: 20 73 63 61 6e 20 24 7a 52 69 67 68 74 43 68 69   scan $zRightChi
2a50: 6c 64 20 49 20 69 52 69 67 68 74 43 68 69 6c 64  ld I iRightChild
2a60: 0a 20 20 73 65 65 6b 20 24 66 64 20 5b 65 78 70  .  seek $fd [exp
2a70: 72 20 31 30 32 34 2a 28 24 69 52 69 67 68 74 43  r 1024*($iRightC
2a80: 68 69 6c 64 2d 31 29 5d 0a 20 20 70 75 74 73 20  hild-1)].  puts 
2a90: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66 64 20 22  -nonewline $fd "
2aa0: 5c 78 30 44 22 0a 20 20 63 6c 6f 73 65 20 24 66  \x0D".  close $f
2ab0: 64 0a 7d 20 2d 74 65 73 74 20 7b 0a 20 20 64 6f  d.} -test {.  do
2ac0: 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d 37  _test corrupt2-7
2ad0: 2e 31 20 7b 0a 20 20 20 20 63 61 74 63 68 73 71  .1 {.    catchsq
2ae0: 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c 20 53 45  l " $::presql SE
2af0: 4c 45 43 54 20 62 20 46 52 4f 4d 20 74 31 20 4f  LECT b FROM t1 O
2b00: 52 44 45 52 20 42 59 20 62 20 41 53 43 20 22 0a  RDER BY b ASC ".
2b10: 20 20 7d 20 7b 31 20 7b 64 61 74 61 62 61 73 65    } {1 {database
2b20: 20 64 69 73 6b 20 69 6d 61 67 65 20 69 73 20 6d   disk image is m
2b30: 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d 0a 0a 63 6f  alformed}}.}..co
2b40: 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73  rruption_test -s
2b50: 71 6c 70 72 65 70 20 24 73 71 6c 70 72 65 70 20  qlprep $sqlprep 
2b60: 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 23 20 4d  -corrupt {.  # M
2b70: 65 73 73 20 75 70 20 74 68 65 20 70 61 67 65 2d  ess up the page-
2b80: 68 65 61 64 65 72 20 6f 66 20 6f 6e 65 20 6f 66  header of one of
2b90: 20 74 68 65 20 6c 65 61 66 20 70 61 67 65 73 20   the leaf pages 
2ba0: 6f 66 20 74 68 65 20 69 6e 64 65 78 20 42 2d 54  of the index B-T
2bb0: 72 65 65 2e 0a 20 20 23 20 54 68 65 20 63 6f 72  ree..  # The cor
2bc0: 72 75 70 74 69 6f 6e 20 69 73 20 64 65 74 65 63  ruption is detec
2bd0: 74 65 64 20 61 73 20 70 61 72 74 20 6f 66 20 61  ted as part of a
2be0: 6e 20 4f 50 5f 50 72 65 76 20 6f 70 63 6f 64 65  n OP_Prev opcode
2bf0: 2e 0a 20 20 23 0a 20 20 73 65 74 20 66 64 20 5b  ..  #.  set fd [
2c00: 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e 64 62 20  open corrupt.db 
2c10: 72 2b 5d 0a 20 20 66 63 6f 6e 66 69 67 75 72 65  r+].  fconfigure
2c20: 20 24 66 64 20 2d 74 72 61 6e 73 6c 61 74 69 6f   $fd -translatio
2c30: 6e 20 62 69 6e 61 72 79 20 2d 65 6e 63 6f 64 69  n binary -encodi
2c40: 6e 67 20 62 69 6e 61 72 79 0a 20 20 73 65 65 6b  ng binary.  seek
2c50: 20 24 66 64 20 5b 65 78 70 72 20 31 30 32 34 2a   $fd [expr 1024*
2c60: 32 20 2b 20 31 32 5d 20 0a 20 20 73 65 74 20 7a  2 + 12] .  set z
2c70: 43 65 6c 6c 4f 66 66 73 65 74 20 5b 72 65 61 64  CellOffset [read
2c80: 20 24 66 64 20 32 5d 0a 20 20 62 69 6e 61 72 79   $fd 2].  binary
2c90: 20 73 63 61 6e 20 24 7a 43 65 6c 6c 4f 66 66 73   scan $zCellOffs
2ca0: 65 74 20 53 20 69 43 65 6c 6c 4f 66 66 73 65 74  et S iCellOffset
2cb0: 0a 20 20 73 65 65 6b 20 24 66 64 20 5b 65 78 70  .  seek $fd [exp
2cc0: 72 20 31 30 32 34 2a 32 20 2b 20 24 69 43 65 6c  r 1024*2 + $iCel
2cd0: 6c 4f 66 66 73 65 74 5d 0a 20 20 73 65 74 20 7a  lOffset].  set z
2ce0: 43 68 69 6c 64 20 5b 72 65 61 64 20 24 66 64 20  Child [read $fd 
2cf0: 34 5d 0a 20 20 62 69 6e 61 72 79 20 73 63 61 6e  4].  binary scan
2d00: 20 24 7a 43 68 69 6c 64 20 49 20 69 43 68 69 6c   $zChild I iChil
2d10: 64 0a 20 20 73 65 65 6b 20 24 66 64 20 5b 65 78  d.  seek $fd [ex
2d20: 70 72 20 31 30 32 34 2a 28 24 69 43 68 69 6c 64  pr 1024*($iChild
2d30: 2d 31 29 2b 33 5d 0a 20 20 70 75 74 73 20 2d 6e  -1)+3].  puts -n
2d40: 6f 6e 65 77 6c 69 6e 65 20 24 66 64 20 22 5c 78  onewline $fd "\x
2d50: 46 46 46 46 22 0a 20 20 63 6c 6f 73 65 20 24 66  FFFF".  close $f
2d60: 64 0a 7d 20 2d 74 65 73 74 20 7b 0a 20 20 64 6f  d.} -test {.  do
2d70: 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d 37  _test corrupt2-7
2d80: 2e 31 20 7b 0a 20 20 20 20 63 61 74 63 68 73 71  .1 {.    catchsq
2d90: 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c 20 53 45  l " $::presql SE
2da0: 4c 45 43 54 20 62 20 46 52 4f 4d 20 74 31 20 4f  LECT b FROM t1 O
2db0: 52 44 45 52 20 42 59 20 62 20 44 45 53 43 20 22  RDER BY b DESC "
2dc0: 0a 20 20 7d 20 7b 31 20 7b 64 61 74 61 62 61 73  .  } {1 {databas
2dd0: 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69 73 20  e disk image is 
2de0: 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d 0a 0a 63  malformed}}.}..c
2df0: 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d  orruption_test -
2e00: 73 71 6c 70 72 65 70 20 24 73 71 6c 70 72 65 70  sqlprep $sqlprep
2e10: 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 23 20   -corrupt {.  # 
2e20: 53 65 74 20 74 68 65 20 70 61 67 65 2d 66 6c 61  Set the page-fla
2e30: 67 73 20 6f 66 20 6f 6e 65 20 6f 66 20 74 68 65  gs of one of the
2e40: 20 6c 65 61 66 20 70 61 67 65 73 20 6f 66 20 74   leaf pages of t
2e50: 68 65 20 74 61 62 6c 65 20 42 2d 54 72 65 65 20  he table B-Tree 
2e60: 74 6f 0a 20 20 23 20 30 78 30 41 20 28 69 6e 74  to.  # 0x0A (int
2e70: 65 72 70 72 65 74 65 64 20 62 79 20 53 51 4c 69  erpreted by SQLi
2e80: 74 65 20 61 73 20 22 6c 65 61 66 20 70 61 67 65  te as "leaf page
2e90: 20 6f 66 20 61 6e 20 69 6e 64 65 78 20 42 2d 54   of an index B-T
2ea0: 72 65 65 22 29 2e 0a 20 20 23 0a 20 20 73 65 74  ree")..  #.  set
2eb0: 20 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70   fd [open corrup
2ec0: 74 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e 66  t.db r+].  fconf
2ed0: 69 67 75 72 65 20 24 66 64 20 2d 74 72 61 6e 73  igure $fd -trans
2ee0: 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 20 2d 65  lation binary -e
2ef0: 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79 0a 20  ncoding binary. 
2f00: 20 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20   seek $fd [expr 
2f10: 31 30 32 34 2a 31 20 2b 20 38 5d 20 0a 20 20 73  1024*1 + 8] .  s
2f20: 65 74 20 7a 52 69 67 68 74 43 68 69 6c 64 20 5b  et zRightChild [
2f30: 72 65 61 64 20 24 66 64 20 34 5d 0a 20 20 62 69  read $fd 4].  bi
2f40: 6e 61 72 79 20 73 63 61 6e 20 24 7a 52 69 67 68  nary scan $zRigh
2f50: 74 43 68 69 6c 64 20 49 20 69 52 69 67 68 74 43  tChild I iRightC
2f60: 68 69 6c 64 0a 20 20 73 65 65 6b 20 24 66 64 20  hild.  seek $fd 
2f70: 5b 65 78 70 72 20 31 30 32 34 2a 28 24 69 52 69  [expr 1024*($iRi
2f80: 67 68 74 43 68 69 6c 64 2d 31 29 5d 0a 20 20 70  ghtChild-1)].  p
2f90: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24  uts -nonewline $
2fa0: 66 64 20 22 5c 78 30 41 22 0a 20 20 63 6c 6f 73  fd "\x0A".  clos
2fb0: 65 20 24 66 64 0a 7d 20 2d 74 65 73 74 20 7b 0a  e $fd.} -test {.
2fc0: 20 20 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70    do_test corrup
2fd0: 74 32 2d 38 2e 31 20 7b 0a 20 20 20 20 63 61 74  t2-8.1 {.    cat
2fe0: 63 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71  chsql " $::presq
2ff0: 6c 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20  l SELECT * FROM 
3000: 74 31 20 57 48 45 52 45 20 72 6f 77 69 64 3d 31  t1 WHERE rowid=1
3010: 30 30 30 20 22 0a 20 20 7d 20 7b 31 20 7b 64 61  000 ".  } {1 {da
3020: 74 61 62 61 73 65 20 64 69 73 6b 20 69 6d 61 67  tabase disk imag
3030: 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d  e is malformed}}
3040: 0a 7d 0a 0a 63 6f 72 72 75 70 74 69 6f 6e 5f 74  .}..corruption_t
3050: 65 73 74 20 2d 73 71 6c 70 72 65 70 20 7b 0a 20  est -sqlprep {. 
3060: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31   CREATE TABLE t1
3070: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3080: 45 20 54 41 42 4c 45 20 74 38 28 61 2c 20 62 2c  E TABLE t8(a, b,
3090: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
30a0: 45 20 74 45 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E tE(a, b, c);. 
30b0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32   CREATE TABLE t2
30c0: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
30d0: 45 20 54 41 42 4c 45 20 74 39 28 61 2c 20 62 2c  E TABLE t9(a, b,
30e0: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
30f0: 45 20 74 46 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E tF(a, b, c);. 
3100: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 33   CREATE TABLE t3
3110: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3120: 45 20 54 41 42 4c 45 20 74 41 28 61 2c 20 62 2c  E TABLE tA(a, b,
3130: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3140: 45 20 74 47 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E tG(a, b, c);. 
3150: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 34   CREATE TABLE t4
3160: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3170: 45 20 54 41 42 4c 45 20 74 42 28 61 2c 20 62 2c  E TABLE tB(a, b,
3180: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3190: 45 20 74 48 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E tH(a, b, c);. 
31a0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 35   CREATE TABLE t5
31b0: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
31c0: 45 20 54 41 42 4c 45 20 74 43 28 61 2c 20 62 2c  E TABLE tC(a, b,
31d0: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
31e0: 45 20 74 49 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E tI(a, b, c);. 
31f0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 36   CREATE TABLE t6
3200: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3210: 45 20 54 41 42 4c 45 20 74 44 28 61 2c 20 62 2c  E TABLE tD(a, b,
3220: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3230: 45 20 74 4a 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E tJ(a, b, c);. 
3240: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 31   CREATE TABLE x1
3250: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3260: 45 20 54 41 42 4c 45 20 78 38 28 61 2c 20 62 2c  E TABLE x8(a, b,
3270: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3280: 45 20 78 45 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E xE(a, b, c);. 
3290: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 32   CREATE TABLE x2
32a0: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
32b0: 45 20 54 41 42 4c 45 20 78 39 28 61 2c 20 62 2c  E TABLE x9(a, b,
32c0: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
32d0: 45 20 78 46 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E xF(a, b, c);. 
32e0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 33   CREATE TABLE x3
32f0: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3300: 45 20 54 41 42 4c 45 20 78 41 28 61 2c 20 62 2c  E TABLE xA(a, b,
3310: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3320: 45 20 78 47 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E xG(a, b, c);. 
3330: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 34   CREATE TABLE x4
3340: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
3350: 45 20 54 41 42 4c 45 20 78 42 28 61 2c 20 62 2c  E TABLE xB(a, b,
3360: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3370: 45 20 78 48 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E xH(a, b, c);. 
3380: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 35   CREATE TABLE x5
3390: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
33a0: 45 20 54 41 42 4c 45 20 78 43 28 61 2c 20 62 2c  E TABLE xC(a, b,
33b0: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
33c0: 45 20 78 49 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E xI(a, b, c);. 
33d0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 36   CREATE TABLE x6
33e0: 28 61 2c 20 62 2c 20 63 29 3b 20 43 52 45 41 54  (a, b, c); CREAT
33f0: 45 20 54 41 42 4c 45 20 78 44 28 61 2c 20 62 2c  E TABLE xD(a, b,
3400: 20 63 29 3b 20 43 52 45 41 54 45 20 54 41 42 4c   c); CREATE TABL
3410: 45 20 78 4a 28 61 2c 20 62 2c 20 63 29 3b 0a 7d  E xJ(a, b, c);.}
3420: 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 73 65   -corrupt {.  se
3430: 74 20 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75  t fd [open corru
3440: 70 74 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e  pt.db r+].  fcon
3450: 66 69 67 75 72 65 20 24 66 64 20 2d 74 72 61 6e  figure $fd -tran
3460: 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 20 2d  slation binary -
3470: 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79 0a  encoding binary.
3480: 20 20 73 65 65 6b 20 24 66 64 20 31 30 38 0a 20    seek $fd 108. 
3490: 20 73 65 74 20 7a 52 69 67 68 74 43 68 69 6c 64   set zRightChild
34a0: 20 5b 72 65 61 64 20 24 66 64 20 34 5d 0a 20 20   [read $fd 4].  
34b0: 62 69 6e 61 72 79 20 73 63 61 6e 20 24 7a 52 69  binary scan $zRi
34c0: 67 68 74 43 68 69 6c 64 20 49 20 69 52 69 67 68  ghtChild I iRigh
34d0: 74 43 68 69 6c 64 0a 20 20 73 65 65 6b 20 24 66  tChild.  seek $f
34e0: 64 20 5b 65 78 70 72 20 31 30 32 34 2a 28 24 69  d [expr 1024*($i
34f0: 52 69 67 68 74 43 68 69 6c 64 2d 31 29 2b 33 5d  RightChild-1)+3]
3500: 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69  .  puts -nonewli
3510: 6e 65 20 24 66 64 20 22 5c 78 30 30 5c 78 30 30  ne $fd "\x00\x00
3520: 22 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 7d 20  ".  close $fd.} 
3530: 2d 74 65 73 74 20 7b 0a 20 20 64 6f 5f 74 65 73  -test {.  do_tes
3540: 74 20 63 6f 72 72 75 70 74 32 2d 39 2e 31 20 7b  t corrupt2-9.1 {
3550: 0a 20 20 20 20 63 61 74 63 68 73 71 6c 20 22 20  .    catchsql " 
3560: 24 3a 3a 70 72 65 73 71 6c 20 53 45 4c 45 43 54  $::presql SELECT
3570: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
3580: 5f 6d 61 73 74 65 72 20 22 0a 20 20 7d 20 7b 31  _master ".  } {1
3590: 20 7b 64 61 74 61 62 61 73 65 20 64 69 73 6b 20   {database disk 
35a0: 69 6d 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d  image is malform
35b0: 65 64 7d 7d 0a 7d 0a 0a 63 6f 72 72 75 70 74 69  ed}}.}..corrupti
35c0: 6f 6e 5f 74 65 73 74 20 2d 73 71 6c 70 72 65 70  on_test -sqlprep
35d0: 20 7b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c   {.  CREATE TABL
35e0: 45 20 74 31 28 61 2c 20 62 2c 20 63 29 3b 0a 20  E t1(a, b, c);. 
35f0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32   CREATE TABLE t2
3600: 28 61 2c 20 62 2c 20 63 29 3b 0a 20 20 50 52 41  (a, b, c);.  PRA
3610: 47 4d 41 20 77 72 69 74 61 62 6c 65 5f 73 63 68  GMA writable_sch
3620: 65 6d 61 20 3d 20 31 3b 0a 20 20 55 50 44 41 54  ema = 1;.  UPDAT
3630: 45 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  E sqlite_master 
3640: 53 45 54 20 72 6f 6f 74 70 61 67 65 20 3d 20 4e  SET rootpage = N
3650: 55 4c 4c 20 57 48 45 52 45 20 6e 61 6d 65 20 3d  ULL WHERE name =
3660: 20 27 74 32 27 3b 0a 7d 20 2d 74 65 73 74 20 7b   't2';.} -test {
3670: 0a 20 20 64 6f 5f 74 65 73 74 20 63 6f 72 72 75  .  do_test corru
3680: 70 74 32 2d 31 30 2e 31 20 7b 0a 20 20 20 20 63  pt2-10.1 {.    c
3690: 61 74 63 68 73 71 6c 20 22 20 24 3a 3a 70 72 65  atchsql " $::pre
36a0: 73 71 6c 20 53 45 4c 45 43 54 20 2a 20 46 52 4f  sql SELECT * FRO
36b0: 4d 20 74 32 20 22 0a 20 20 7d 20 7b 31 20 7b 6d  M t2 ".  } {1 {m
36c0: 61 6c 66 6f 72 6d 65 64 20 64 61 74 61 62 61 73  alformed databas
36d0: 65 20 73 63 68 65 6d 61 20 28 74 32 29 7d 7d 0a  e schema (t2)}}.
36e0: 20 20 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70    do_test corrup
36f0: 74 32 2d 31 30 2e 32 20 7b 0a 20 20 20 20 73 71  t2-10.2 {.    sq
3700: 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 20 64 62  lite3_errcode db
3710: 0a 20 20 7d 20 7b 53 51 4c 49 54 45 5f 43 4f 52  .  } {SQLITE_COR
3720: 52 55 50 54 7d 0a 7d 0a 0a 63 6f 72 72 75 70 74  RUPT}.}..corrupt
3730: 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c 70 72 65  ion_test -sqlpre
3740: 70 20 7b 0a 20 20 50 52 41 47 4d 41 20 61 75 74  p {.  PRAGMA aut
3750: 6f 5f 76 61 63 75 75 6d 20 3d 20 69 6e 63 72 65  o_vacuum = incre
3760: 6d 65 6e 74 61 6c 3b 0a 20 20 43 52 45 41 54 45  mental;.  CREATE
3770: 20 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45   TABLE t1(a INTE
3780: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c  GER PRIMARY KEY,
3790: 20 62 29 3b 0a 20 20 43 52 45 41 54 45 20 54 41   b);.  CREATE TA
37a0: 42 4c 45 20 74 32 28 61 20 49 4e 54 45 47 45 52  BLE t2(a INTEGER
37b0: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 29   PRIMARY KEY, b)
37c0: 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20  ;.  INSERT INTO 
37d0: 74 31 20 56 41 4c 55 45 53 28 31 2c 20 72 61 6e  t1 VALUES(1, ran
37e0: 64 73 74 72 28 31 30 30 2c 31 30 30 29 29 3b 0a  dstr(100,100));.
37f0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3800: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
3810: 6e 64 73 74 72 28 31 30 30 2c 31 30 30 29 20 46  ndstr(100,100) F
3820: 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54  ROM t1;.  INSERT
3830: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
3840: 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72 28 31 30  NULL, randstr(10
3850: 30 2c 31 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a  0,100) FROM t1;.
3860: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3870: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
3880: 6e 64 73 74 72 28 31 30 30 2c 31 30 30 29 20 46  ndstr(100,100) F
3890: 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54  ROM t1;.  INSERT
38a0: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
38b0: 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72 28 31 30  NULL, randstr(10
38c0: 30 2c 31 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a  0,100) FROM t1;.
38d0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
38e0: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
38f0: 6e 64 73 74 72 28 31 30 30 2c 31 30 30 29 20 46  ndstr(100,100) F
3900: 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54  ROM t1;.  INSERT
3910: 20 49 4e 54 4f 20 74 32 20 53 45 4c 45 43 54 20   INTO t2 SELECT 
3920: 2a 20 46 52 4f 4d 20 74 31 3b 0a 20 20 44 45 4c  * FROM t1;.  DEL
3930: 45 54 45 20 46 52 4f 4d 20 74 31 3b 0a 7d 20 2d  ETE FROM t1;.} -
3940: 63 6f 72 72 75 70 74 20 7b 0a 20 20 73 65 74 20  corrupt {.  set 
3950: 6f 66 66 73 65 74 20 5b 65 78 70 72 20 5b 66 69  offset [expr [fi
3960: 6c 65 20 73 69 7a 65 20 63 6f 72 72 75 70 74 2e  le size corrupt.
3970: 64 62 5d 20 2d 20 31 30 32 34 5d 0a 20 20 68 65  db] - 1024].  he
3980: 78 69 6f 5f 77 72 69 74 65 20 63 6f 72 72 75 70  xio_write corrup
3990: 74 2e 64 62 20 24 6f 66 66 73 65 74 20 46 46 20  t.db $offset FF 
39a0: 0a 20 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63  .  hexio_write c
39b0: 6f 72 72 75 70 74 2e 64 62 20 32 34 20 20 20 31  orrupt.db 24   1
39c0: 32 33 34 35 36 37 38 0a 7d 20 2d 74 65 73 74 20  2345678.} -test 
39d0: 7b 0a 20 20 64 6f 5f 74 65 73 74 20 63 6f 72 72  {.  do_test corr
39e0: 75 70 74 32 2d 31 31 2e 31 20 7b 0a 20 20 20 20  upt2-11.1 {.    
39f0: 63 61 74 63 68 73 71 6c 20 22 20 24 3a 3a 70 72  catchsql " $::pr
3a00: 65 73 71 6c 20 50 52 41 47 4d 41 20 69 6e 63 72  esql PRAGMA incr
3a10: 65 6d 65 6e 74 61 6c 5f 76 61 63 75 75 6d 20 22  emental_vacuum "
3a20: 0a 20 20 7d 20 7b 31 20 7b 64 61 74 61 62 61 73  .  } {1 {databas
3a30: 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69 73 20  e disk image is 
3a40: 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d 0a 63 6f  malformed}}.}.co
3a50: 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73  rruption_test -s
3a60: 71 6c 70 72 65 70 20 7b 0a 20 20 50 52 41 47 4d  qlprep {.  PRAGM
3a70: 41 20 61 75 74 6f 5f 76 61 63 75 75 6d 20 3d 20  A auto_vacuum = 
3a80: 69 6e 63 72 65 6d 65 6e 74 61 6c 3b 0a 20 20 43  incremental;.  C
3a90: 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61  REATE TABLE t1(a
3aa0: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59   INTEGER PRIMARY
3ab0: 20 4b 45 59 2c 20 62 29 3b 0a 20 20 43 52 45 41   KEY, b);.  CREA
3ac0: 54 45 20 54 41 42 4c 45 20 74 32 28 61 20 49 4e  TE TABLE t2(a IN
3ad0: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45  TEGER PRIMARY KE
3ae0: 59 2c 20 62 29 3b 0a 20 20 49 4e 53 45 52 54 20  Y, b);.  INSERT 
3af0: 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 31  INTO t1 VALUES(1
3b00: 2c 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31 30  , randstr(100,10
3b10: 30 29 29 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e  0));.  INSERT IN
3b20: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c  TO t1 SELECT NUL
3b30: 4c 2c 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31  L, randstr(100,1
3b40: 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49  00) FROM t1;.  I
3b50: 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45  NSERT INTO t1 SE
3b60: 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 73  LECT NULL, rands
3b70: 74 72 28 31 30 30 2c 31 30 30 29 20 46 52 4f 4d  tr(100,100) FROM
3b80: 20 74 31 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e   t1;.  INSERT IN
3b90: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c  TO t1 SELECT NUL
3ba0: 4c 2c 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31  L, randstr(100,1
3bb0: 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49  00) FROM t1;.  I
3bc0: 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45  NSERT INTO t1 SE
3bd0: 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 73  LECT NULL, rands
3be0: 74 72 28 31 30 30 2c 31 30 30 29 20 46 52 4f 4d  tr(100,100) FROM
3bf0: 20 74 31 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e   t1;.  INSERT IN
3c00: 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c  TO t1 SELECT NUL
3c10: 4c 2c 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31  L, randstr(100,1
3c20: 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49  00) FROM t1;.  I
3c30: 4e 53 45 52 54 20 49 4e 54 4f 20 74 32 20 53 45  NSERT INTO t2 SE
3c40: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 31 3b 0a  LECT * FROM t1;.
3c50: 20 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31    DELETE FROM t1
3c60: 3b 0a 7d 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20  ;.} -corrupt {. 
3c70: 20 73 65 74 20 70 67 6e 6f 20 5b 65 78 70 72 20   set pgno [expr 
3c80: 5b 66 69 6c 65 20 73 69 7a 65 20 63 6f 72 72 75  [file size corru
3c90: 70 74 2e 64 62 5d 20 2f 20 31 30 32 34 5d 0a 20  pt.db] / 1024]. 
3ca0: 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63 6f 72   hexio_write cor
3cb0: 72 75 70 74 2e 64 62 20 5b 65 78 70 72 20 31 30  rupt.db [expr 10
3cc0: 32 34 2b 35 2a 28 24 70 67 6e 6f 2d 33 29 5d 20  24+5*($pgno-3)] 
3cd0: 30 33 20 0a 20 20 68 65 78 69 6f 5f 77 72 69 74  03 .  hexio_writ
3ce0: 65 20 63 6f 72 72 75 70 74 2e 64 62 20 32 34 20  e corrupt.db 24 
3cf0: 20 20 31 32 33 34 35 36 37 38 0a 7d 20 2d 74 65    12345678.} -te
3d00: 73 74 20 7b 0a 20 20 64 6f 5f 74 65 73 74 20 63  st {.  do_test c
3d10: 6f 72 72 75 70 74 32 2d 31 32 2e 31 20 7b 0a 20  orrupt2-12.1 {. 
3d20: 20 20 20 63 61 74 63 68 73 71 6c 20 22 20 24 3a     catchsql " $:
3d30: 3a 70 72 65 73 71 6c 20 50 52 41 47 4d 41 20 69  :presql PRAGMA i
3d40: 6e 63 72 65 6d 65 6e 74 61 6c 5f 76 61 63 75 75  ncremental_vacuu
3d50: 6d 20 22 0a 20 20 7d 20 7b 31 20 7b 64 61 74 61  m ".  } {1 {data
3d60: 62 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20  base disk image 
3d70: 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d  is malformed}}.}
3d80: 0a 0a 69 66 63 61 70 61 62 6c 65 20 61 75 74 6f  ..ifcapable auto
3d90: 76 61 63 75 75 6d 20 7b 0a 20 20 23 20 49 74 20  vacuum {.  # It 
3da0: 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20  is not possible 
3db0: 66 6f 72 20 74 68 65 20 6c 61 73 74 20 70 61 67  for the last pag
3dc0: 65 20 69 6e 20 61 20 64 61 74 61 62 61 73 65 20  e in a database 
3dd0: 66 69 6c 65 20 74 6f 20 62 65 20 74 68 65 0a 20  file to be the. 
3de0: 20 23 20 70 65 6e 64 69 6e 67 2d 62 79 74 65 20   # pending-byte 
3df0: 70 61 67 65 20 28 41 4b 41 20 74 68 65 20 6c 6f  page (AKA the lo
3e00: 63 6b 69 6e 67 20 70 61 67 65 29 2e 20 54 68 69  cking page). Thi
3e10: 73 20 74 65 73 74 20 76 65 72 69 66 69 65 73 20  s test verifies 
3e20: 74 68 61 74 20 69 66 0a 20 20 23 20 61 6e 20 61  that if.  # an a
3e30: 74 74 65 6d 70 74 20 69 73 20 6d 61 64 65 20 74  ttempt is made t
3e40: 6f 20 63 6f 6d 6d 69 74 20 61 20 74 72 61 6e 73  o commit a trans
3e50: 61 63 74 69 6f 6e 20 74 6f 20 73 75 63 68 20 61  action to such a
3e60: 6e 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 0a 20  n auto-vacuum . 
3e70: 20 23 20 64 61 74 61 62 61 73 65 20 53 51 4c 49   # database SQLI
3e80: 54 45 5f 43 4f 52 52 55 50 54 20 69 73 20 72 65  TE_CORRUPT is re
3e90: 74 75 72 6e 65 64 2e 0a 20 20 23 0a 20 20 63 6f  turned..  #.  co
3ea0: 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d 74  rruption_test -t
3eb0: 63 6c 70 72 65 70 20 7b 0a 20 20 20 20 64 62 20  clprep {.    db 
3ec0: 65 76 61 6c 20 7b 20 0a 20 20 20 20 20 20 50 52  eval { .      PR
3ed0: 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75 6d  AGMA auto_vacuum
3ee0: 20 3d 20 66 75 6c 6c 3b 0a 20 20 20 20 20 20 50   = full;.      P
3ef0: 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65 20  RAGMA page_size 
3f00: 3d 20 31 30 32 34 3b 0a 20 20 20 20 20 20 43 52  = 1024;.      CR
3f10: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20  EATE TABLE t1(a 
3f20: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20  INTEGER PRIMARY 
3f30: 4b 45 59 2c 20 62 29 3b 0a 20 20 20 20 20 20 49  KEY, b);.      I
3f40: 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 56 41  NSERT INTO t1 VA
3f50: 4c 55 45 53 28 4e 55 4c 4c 2c 20 72 61 6e 64 73  LUES(NULL, rands
3f60: 74 72 28 35 30 2c 35 30 29 29 3b 0a 20 20 20 20  tr(50,50));.    
3f70: 7d 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69  }.    for {set i
3f80: 69 20 30 7d 20 7b 24 69 69 20 3c 20 31 30 7d 20  i 0} {$ii < 10} 
3f90: 7b 69 6e 63 72 20 69 69 7d 20 7b 0a 20 20 20 20  {incr ii} {.    
3fa0: 20 20 64 62 20 65 76 61 6c 20 22 20 24 3a 3a 70    db eval " $::p
3fb0: 72 65 73 71 6c 20 49 4e 53 45 52 54 20 49 4e 54  resql INSERT INT
3fc0: 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c  O t1 SELECT NULL
3fd0: 2c 20 72 61 6e 64 73 74 72 28 35 30 2c 35 30 29  , randstr(50,50)
3fe0: 20 46 52 4f 4d 20 74 31 20 22 0a 20 20 20 20 7d   FROM t1 ".    }
3ff0: 0a 20 20 7d 20 2d 63 6f 72 72 75 70 74 20 7b 0a  .  } -corrupt {.
4000: 20 20 20 20 64 6f 5f 74 65 73 74 20 63 6f 72 72      do_test corr
4010: 75 70 74 32 2d 31 33 2e 31 20 7b 0a 20 20 20 20  upt2-13.1 {.    
4020: 20 20 66 69 6c 65 20 73 69 7a 65 20 63 6f 72 72    file size corr
4030: 75 70 74 2e 64 62 0a 20 20 20 20 7d 20 24 3a 3a  upt.db.    } $::
4040: 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62  sqlite_pending_b
4050: 79 74 65 0a 20 20 20 20 68 65 78 69 6f 5f 77 72  yte.    hexio_wr
4060: 69 74 65 20 63 6f 72 72 75 70 74 2e 64 62 20 5b  ite corrupt.db [
4070: 65 78 70 72 20 24 3a 3a 73 71 6c 69 74 65 5f 70  expr $::sqlite_p
4080: 65 6e 64 69 6e 67 5f 62 79 74 65 2b 31 30 32 33  ending_byte+1023
4090: 5d 20 30 30 0a 20 20 20 20 68 65 78 69 6f 5f 77  ] 00.    hexio_w
40a0: 72 69 74 65 20 63 6f 72 72 75 70 74 2e 64 62 20  rite corrupt.db 
40b0: 32 38 20 30 30 30 30 30 30 30 30 0a 20 20 7d 20  28 00000000.  } 
40c0: 2d 74 65 73 74 20 7b 0a 20 20 20 20 64 6f 5f 74  -test {.    do_t
40d0: 65 73 74 20 63 6f 72 72 75 70 74 32 2d 31 33 2e  est corrupt2-13.
40e0: 32 20 7b 0a 20 20 20 20 20 20 66 69 6c 65 20 73  2 {.      file s
40f0: 69 7a 65 20 63 6f 72 72 75 70 74 2e 64 62 0a 20  ize corrupt.db. 
4100: 20 20 20 7d 20 5b 65 78 70 72 20 24 3a 3a 73 71     } [expr $::sq
4110: 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62 79 74  lite_pending_byt
4120: 65 20 2b 20 31 30 32 34 5d 0a 20 20 20 20 64 6f  e + 1024].    do
4130: 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d 31  _test corrupt2-1
4140: 33 2e 33 20 7b 0a 20 20 20 20 20 20 63 61 74 63  3.3 {.      catc
4150: 68 73 71 6c 20 7b 20 44 45 4c 45 54 45 20 46 52  hsql { DELETE FR
4160: 4f 4d 20 74 31 20 57 48 45 52 45 20 72 6f 77 69  OM t1 WHERE rowi
4170: 64 20 3c 20 33 30 3b 20 7d 0a 20 20 20 20 7d 20  d < 30; }.    } 
4180: 7b 31 20 7b 64 61 74 61 62 61 73 65 20 64 69 73  {1 {database dis
4190: 6b 20 69 6d 61 67 65 20 69 73 20 6d 61 6c 66 6f  k image is malfo
41a0: 72 6d 65 64 7d 7d 0a 20 20 7d 0a 7d 0a 0a 23 2d  rmed}}.  }.}..#-
41b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
41c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
41d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
41e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
41f0: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 54 65 73 74 20  --------.# Test 
4200: 74 68 61 74 20 50 52 41 47 4d 41 20 69 6e 74 65  that PRAGMA inte
4210: 67 72 69 74 79 5f 63 68 65 63 6b 20 64 65 74 65  grity_check dete
4220: 63 74 73 20 63 61 73 65 73 20 77 68 65 72 65 20  cts cases where 
4230: 74 68 65 20 66 72 65 65 6c 69 73 74 2d 63 6f 75  the freelist-cou
4240: 6e 74 0a 23 20 68 65 61 64 65 72 20 66 69 65 6c  nt.# header fiel
4250: 64 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61  d is smaller tha
4260: 6e 20 74 68 65 20 61 63 74 75 61 6c 20 6e 75 6d  n the actual num
4270: 62 65 72 20 6f 66 20 70 61 67 65 73 20 6f 6e 20  ber of pages on 
4280: 74 68 65 20 66 72 65 65 6c 69 73 74 2e 0a 23 0a  the freelist..#.
4290: 0a 72 65 73 65 74 5f 64 62 0a 64 6f 5f 65 78 65  .reset_db.do_exe
42a0: 63 73 71 6c 5f 74 65 73 74 20 31 34 2e 30 20 7b  csql_test 14.0 {
42b0: 0a 20 20 50 52 41 47 4d 41 20 61 75 74 6f 5f 76  .  PRAGMA auto_v
42c0: 61 63 75 75 6d 20 3d 20 30 3b 0a 20 20 43 52 45  acuum = 0;.  CRE
42d0: 41 54 45 20 54 41 42 4c 45 20 74 31 28 78 29 3b  ATE TABLE t1(x);
42e0: 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74  .  INSERT INTO t
42f0: 31 20 56 41 4c 55 45 53 28 72 61 6e 64 6f 6d 62  1 VALUES(randomb
4300: 6c 6f 62 28 33 35 30 30 29 29 3b 0a 20 20 44 45  lob(3500));.  DE
4310: 4c 45 54 45 20 46 52 4f 4d 20 74 31 3b 0a 7d 0a  LETE FROM t1;.}.
4320: 0a 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74  .do_execsql_test
4330: 20 31 34 2e 31 20 7b 0a 20 20 50 52 41 47 4d 41   14.1 {.  PRAGMA
4340: 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b   integrity_check
4350: 3b 0a 20 20 50 52 41 47 4d 41 20 66 72 65 65 6c  ;.  PRAGMA freel
4360: 69 73 74 5f 63 6f 75 6e 74 3b 0a 7d 20 7b 6f 6b  ist_count;.} {ok
4370: 20 33 7d 0a 0a 23 20 54 68 65 72 65 20 61 72 65   3}..# There are
4380: 20 6e 6f 77 20 33 20 66 72 65 65 20 70 61 67 65   now 3 free page
4390: 73 2e 20 4d 6f 64 69 66 79 20 74 68 65 20 68 65  s. Modify the he
43a0: 61 64 65 72 2d 66 69 65 6c 64 20 73 6f 20 74 68  ader-field so th
43b0: 61 74 20 69 74 20 0a 23 20 28 69 6e 63 6f 72 72  at it .# (incorr
43c0: 65 63 74 6c 79 29 20 73 61 79 73 20 74 68 61 74  ectly) says that
43d0: 20 6a 75 73 74 20 32 20 61 72 65 20 66 72 65 65   just 2 are free
43e0: 2e 0a 64 6f 5f 74 65 73 74 20 31 34 2e 32 20 7b  ..do_test 14.2 {
43f0: 0a 20 20 64 62 20 63 6c 6f 73 65 0a 20 20 68 65  .  db close.  he
4400: 78 69 6f 5f 77 72 69 74 65 20 74 65 73 74 2e 64  xio_write test.d
4410: 62 20 33 36 20 5b 68 65 78 69 6f 5f 72 65 6e 64  b 36 [hexio_rend
4420: 65 72 5f 69 6e 74 33 32 20 32 5d 0a 20 20 73 71  er_int32 2].  sq
4430: 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62  lite3 db test.db
4440: 0a 20 20 65 78 65 63 73 71 6c 20 7b 20 50 52 41  .  execsql { PRA
4450: 47 4d 41 20 66 72 65 65 6c 69 73 74 5f 63 6f 75  GMA freelist_cou
4460: 6e 74 20 7d 0a 7d 20 7b 32 7d 0a 0a 64 6f 5f 65  nt }.} {2}..do_e
4470: 78 65 63 73 71 6c 5f 74 65 73 74 20 31 34 2e 33  xecsql_test 14.3
4480: 20 7b 0a 20 20 50 52 41 47 4d 41 20 69 6e 74 65   {.  PRAGMA inte
4490: 67 72 69 74 79 5f 63 68 65 63 6b 3b 0a 7d 20 7b  grity_check;.} {
44a0: 7b 2a 2a 2a 20 69 6e 20 64 61 74 61 62 61 73 65  {*** in database
44b0: 20 6d 61 69 6e 20 2a 2a 2a 0a 4d 61 69 6e 20 66   main ***.Main f
44c0: 72 65 65 6c 69 73 74 3a 20 66 72 65 65 2d 70 61  reelist: free-pa
44d0: 67 65 20 63 6f 75 6e 74 20 69 6e 20 68 65 61 64  ge count in head
44e0: 65 72 20 69 73 20 74 6f 6f 20 73 6d 61 6c 6c 7d  er is too small}
44f0: 7d 0a 0a 23 20 55 73 65 20 32 20 6f 66 20 74 68  }..# Use 2 of th
4500: 65 20 66 72 65 65 20 70 61 67 65 73 20 6f 6e 20  e free pages on 
4510: 74 68 65 20 66 72 65 65 2d 6c 69 73 74 2e 0a 23  the free-list..#
4520: 0a 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74  .do_execsql_test
4530: 20 31 34 2e 34 20 7b 0a 20 20 49 4e 53 45 52 54   14.4 {.  INSERT
4540: 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28   INTO t1 VALUES(
4550: 72 61 6e 64 6f 6d 62 6c 6f 62 28 32 35 30 30 29  randomblob(2500)
4560: 29 3b 0a 20 20 50 52 41 47 4d 41 20 66 72 65 65  );.  PRAGMA free
4570: 6c 69 73 74 5f 63 6f 75 6e 74 3b 0a 7d 20 7b 30  list_count;.} {0
4580: 7d 0a 0a 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65  }..do_execsql_te
4590: 73 74 20 31 34 2e 35 20 7b 0a 20 20 50 52 41 47  st 14.5 {.  PRAG
45a0: 4d 41 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65  MA integrity_che
45b0: 63 6b 3b 0a 7d 20 7b 7b 2a 2a 2a 20 69 6e 20 64  ck;.} {{*** in d
45c0: 61 74 61 62 61 73 65 20 6d 61 69 6e 20 2a 2a 2a  atabase main ***
45d0: 0a 50 61 67 65 20 33 20 69 73 20 6e 65 76 65 72  .Page 3 is never
45e0: 20 75 73 65 64 7d 7d 0a 0a 0a 66 69 6e 69 73 68   used}}...finish
45f0: 5f 74 65 73 74 0a 0a 66 69 6e 69 73 68 5f 74 65  _test..finish_te
4600: 73 74 0a                                         st.