/ Hex Artifact Content
Login

Artifact b6281ceadd6114d55e89b25e01c617af930dda71567f6a0996a719c385ac142e:


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: 6e 6f 74 20 61 20 64 61 74 61 62 61 73 65 7d 7d  not a database}}
0680: 0a 0a 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70  ..do_test corrup
0690: 74 32 2d 31 2e 33 20 7b 0a 20 20 64 62 32 20 63  t2-1.3 {.  db2 c
06a0: 6c 6f 73 65 0a 0a 20 20 23 20 43 6f 72 72 75 70  lose..  # Corrup
06b0: 74 20 74 68 65 20 70 61 67 65 2d 73 69 7a 65 20  t the page-size 
06c0: 28 62 79 74 65 73 20 31 36 20 61 6e 64 20 31 37  (bytes 16 and 17
06d0: 20 6f 66 20 70 61 67 65 20 31 29 2e 0a 20 20 66   of page 1)..  f
06e0: 6f 72 63 65 64 65 6c 65 74 65 20 63 6f 72 72 75  orcedelete corru
06f0: 70 74 2e 64 62 0a 20 20 66 6f 72 63 65 64 65 6c  pt.db.  forcedel
0700: 65 74 65 20 63 6f 72 72 75 70 74 2e 64 62 2d 6a  ete corrupt.db-j
0710: 6f 75 72 6e 61 6c 0a 20 20 66 6f 72 63 65 63 6f  ournal.  forceco
0720: 70 79 20 74 65 73 74 2e 64 62 20 63 6f 72 72 75  py test.db corru
0730: 70 74 2e 64 62 0a 20 20 73 65 74 20 66 20 5b 6f  pt.db.  set f [o
0740: 70 65 6e 20 63 6f 72 72 75 70 74 2e 64 62 20 52  pen corrupt.db R
0750: 44 57 52 5d 0a 20 20 66 63 6f 6e 66 69 67 75 72  DWR].  fconfigur
0760: 65 20 24 66 20 2d 65 6e 63 6f 64 69 6e 67 20 62  e $f -encoding b
0770: 69 6e 61 72 79 0a 20 20 73 65 65 6b 20 24 66 20  inary.  seek $f 
0780: 31 36 20 73 74 61 72 74 0a 20 20 70 75 74 73 20  16 start.  puts 
0790: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66 20 22 5c  -nonewline $f "\
07a0: 78 30 30 5c 78 46 46 22 0a 20 20 63 6c 6f 73 65  x00\xFF".  close
07b0: 20 24 66 0a 0a 20 20 73 71 6c 69 74 65 33 20 64   $f..  sqlite3 d
07c0: 62 32 20 63 6f 72 72 75 70 74 2e 64 62 0a 20 20  b2 corrupt.db.  
07d0: 63 61 74 63 68 73 71 6c 20 22 0a 20 20 20 20 24  catchsql ".    $
07e0: 3a 3a 70 72 65 73 71 6c 0a 20 20 20 20 53 45 4c  ::presql.    SEL
07f0: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
0800: 65 5f 6d 61 73 74 65 72 3b 0a 20 20 22 20 64 62  e_master;.  " db
0810: 32 0a 7d 20 7b 31 20 7b 66 69 6c 65 20 69 73 20  2.} {1 {file is 
0820: 6e 6f 74 20 61 20 64 61 74 61 62 61 73 65 7d 7d  not a database}}
0830: 0a 0a 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70  ..do_test corrup
0840: 74 32 2d 31 2e 34 20 7b 0a 20 20 64 62 32 20 63  t2-1.4 {.  db2 c
0850: 6c 6f 73 65 0a 0a 20 20 23 20 43 6f 72 72 75 70  lose..  # Corrup
0860: 74 20 74 68 65 20 66 72 65 65 2d 62 6c 6f 63 6b  t the free-block
0870: 20 6c 69 73 74 20 6f 6e 20 70 61 67 65 20 31 2e   list on page 1.
0880: 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63  .  forcedelete c
0890: 6f 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63  orrupt.db.  forc
08a0: 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e  edelete corrupt.
08b0: 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72  db-journal.  for
08c0: 63 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63  cecopy test.db c
08d0: 6f 72 72 75 70 74 2e 64 62 0a 20 20 73 65 74 20  orrupt.db.  set 
08e0: 66 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e  f [open corrupt.
08f0: 64 62 20 52 44 57 52 5d 0a 20 20 66 63 6f 6e 66  db RDWR].  fconf
0900: 69 67 75 72 65 20 24 66 20 2d 65 6e 63 6f 64 69  igure $f -encodi
0910: 6e 67 20 62 69 6e 61 72 79 0a 20 20 73 65 65 6b  ng binary.  seek
0920: 20 24 66 20 31 30 31 20 73 74 61 72 74 0a 20 20   $f 101 start.  
0930: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
0940: 24 66 20 22 5c 78 46 46 5c 78 46 46 22 0a 20 20  $f "\xFF\xFF".  
0950: 63 6c 6f 73 65 20 24 66 0a 0a 20 20 73 71 6c 69  close $f..  sqli
0960: 74 65 33 20 64 62 32 20 63 6f 72 72 75 70 74 2e  te3 db2 corrupt.
0970: 64 62 0a 20 20 63 61 74 63 68 73 71 6c 20 22 0a  db.  catchsql ".
0980: 20 20 20 20 24 3a 3a 70 72 65 73 71 6c 0a 20 20      $::presql.  
0990: 20 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20    SELECT * FROM 
09a0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 0a 20  sqlite_master;. 
09b0: 20 22 20 64 62 32 0a 7d 20 7b 31 20 7b 64 61 74   " db2.} {1 {dat
09c0: 61 62 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65  abase disk image
09d0: 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a   is malformed}}.
09e0: 0a 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74  .do_test corrupt
09f0: 32 2d 31 2e 35 20 7b 0a 20 20 64 62 32 20 63 6c  2-1.5 {.  db2 cl
0a00: 6f 73 65 0a 0a 20 20 23 20 43 6f 72 72 75 70 74  ose..  # Corrupt
0a10: 20 74 68 65 20 66 72 65 65 2d 62 6c 6f 63 6b 20   the free-block 
0a20: 6c 69 73 74 20 6f 6e 20 70 61 67 65 20 31 2e 0a  list on page 1..
0a30: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63 6f    forcedelete co
0a40: 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63 65  rrupt.db.  force
0a50: 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e 64  delete corrupt.d
0a60: 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72 63  b-journal.  forc
0a70: 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63 6f  ecopy test.db co
0a80: 72 72 75 70 74 2e 64 62 0a 20 20 73 65 74 20 66  rrupt.db.  set f
0a90: 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e 64   [open corrupt.d
0aa0: 62 20 52 44 57 52 5d 0a 20 20 66 63 6f 6e 66 69  b RDWR].  fconfi
0ab0: 67 75 72 65 20 24 66 20 2d 65 6e 63 6f 64 69 6e  gure $f -encodin
0ac0: 67 20 62 69 6e 61 72 79 0a 20 20 73 65 65 6b 20  g binary.  seek 
0ad0: 24 66 20 31 30 31 20 73 74 61 72 74 0a 20 20 70  $f 101 start.  p
0ae0: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24  uts -nonewline $
0af0: 66 20 22 5c 78 30 30 5c 78 43 38 22 0a 20 20 73  f "\x00\xC8".  s
0b00: 65 65 6b 20 24 66 20 32 30 30 20 73 74 61 72 74  eek $f 200 start
0b10: 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69  .  puts -nonewli
0b20: 6e 65 20 24 66 20 22 5c 78 30 30 5c 78 30 30 22  ne $f "\x00\x00"
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 31 30 5c 78 30 30 22  ne $f "\x10\x00"
0b50: 0a 20 20 63 6c 6f 73 65 20 24 66 0a 0a 20 20 73  .  close $f..  s
0b60: 71 6c 69 74 65 33 20 64 62 32 20 63 6f 72 72 75  qlite3 db2 corru
0b70: 70 74 2e 64 62 0a 20 20 63 61 74 63 68 73 71 6c  pt.db.  catchsql
0b80: 20 22 0a 20 20 20 20 24 3a 3a 70 72 65 73 71 6c   ".    $::presql
0b90: 0a 20 20 20 20 53 45 4c 45 43 54 20 2a 20 46 52  .    SELECT * FR
0ba0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
0bb0: 3b 0a 20 20 22 20 64 62 32 0a 7d 20 7b 31 20 7b  ;.  " db2.} {1 {
0bc0: 64 61 74 61 62 61 73 65 20 64 69 73 6b 20 69 6d  database disk im
0bd0: 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64  age is malformed
0be0: 7d 7d 0a 64 62 32 20 63 6c 6f 73 65 0a 0a 23 20  }}.db2 close..# 
0bf0: 43 6f 72 72 75 70 74 20 61 20 64 61 74 61 62 61  Corrupt a databa
0c00: 73 65 20 62 79 20 68 61 76 69 6e 67 20 32 20 69  se by having 2 i
0c10: 6e 64 69 63 65 73 20 6f 66 20 74 68 65 20 73 61  ndices of the sa
0c20: 6d 65 20 6e 61 6d 65 3a 0a 64 6f 5f 74 65 73 74  me name:.do_test
0c30: 20 63 6f 72 72 75 70 74 32 2d 32 2e 31 20 7b 0a   corrupt2-2.1 {.
0c40: 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63  .  forcedelete c
0c50: 6f 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63  orrupt.db.  forc
0c60: 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e  edelete corrupt.
0c70: 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 6f 72  db-journal.  for
0c80: 63 65 63 6f 70 79 20 74 65 73 74 2e 64 62 20 63  cecopy test.db c
0c90: 6f 72 72 75 70 74 2e 64 62 0a 0a 20 20 73 71 6c  orrupt.db..  sql
0ca0: 69 74 65 33 20 64 62 32 20 63 6f 72 72 75 70 74  ite3 db2 corrupt
0cb0: 2e 64 62 20 0a 20 20 65 78 65 63 73 71 6c 20 22  .db .  execsql "
0cc0: 0a 20 20 20 20 24 3a 3a 70 72 65 73 71 6c 0a 20  .    $::presql. 
0cd0: 20 20 20 43 52 45 41 54 45 20 49 4e 44 45 58 20     CREATE INDEX 
0ce0: 61 31 20 4f 4e 20 61 62 63 28 61 29 3b 0a 20 20  a1 ON abc(a);.  
0cf0: 20 20 43 52 45 41 54 45 20 49 4e 44 45 58 20 61    CREATE INDEX a
0d00: 32 20 4f 4e 20 61 62 63 28 62 29 3b 0a 20 20 20  2 ON abc(b);.   
0d10: 20 50 52 41 47 4d 41 20 77 72 69 74 61 62 6c 65   PRAGMA writable
0d20: 5f 73 63 68 65 6d 61 20 3d 20 31 3b 0a 20 20 20  _schema = 1;.   
0d30: 20 55 50 44 41 54 45 20 73 71 6c 69 74 65 5f 6d   UPDATE sqlite_m
0d40: 61 73 74 65 72 20 0a 20 20 20 20 20 20 53 45 54  aster .      SET
0d50: 20 6e 61 6d 65 20 3d 20 27 61 33 27 2c 20 73 71   name = 'a3', sq
0d60: 6c 20 3d 20 27 43 52 45 41 54 45 20 49 4e 44 45  l = 'CREATE INDE
0d70: 58 20 61 33 27 20 7c 7c 20 73 75 62 73 74 72 28  X a3' || substr(
0d80: 73 71 6c 2c 20 31 36 2c 20 31 30 30 30 30 29 0a  sql, 16, 10000).
0d90: 20 20 20 20 20 20 57 48 45 52 45 20 74 79 70 65        WHERE type
0da0: 20 3d 20 27 69 6e 64 65 78 27 3b 0a 20 20 20 20   = 'index';.    
0db0: 50 52 41 47 4d 41 20 77 72 69 74 61 62 6c 65 5f  PRAGMA writable_
0dc0: 73 63 68 65 6d 61 20 3d 20 30 3b 0a 20 20 22 20  schema = 0;.  " 
0dd0: 64 62 32 0a 0a 20 20 64 62 32 20 63 6c 6f 73 65  db2..  db2 close
0de0: 0a 20 20 73 71 6c 69 74 65 33 20 64 62 32 20 63  .  sqlite3 db2 c
0df0: 6f 72 72 75 70 74 2e 64 62 20 0a 20 20 63 61 74  orrupt.db .  cat
0e00: 63 68 73 71 6c 20 22 0a 20 20 20 20 24 3a 3a 70  chsql ".    $::p
0e10: 72 65 73 71 6c 0a 20 20 20 20 53 45 4c 45 43 54  resql.    SELECT
0e20: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
0e30: 61 73 74 65 72 3b 0a 20 20 22 20 64 62 32 0a 7d  aster;.  " db2.}
0e40: 20 7b 31 20 7b 6d 61 6c 66 6f 72 6d 65 64 20 64   {1 {malformed d
0e50: 61 74 61 62 61 73 65 20 73 63 68 65 6d 61 20 28  atabase schema (
0e60: 61 33 29 20 2d 20 69 6e 64 65 78 20 61 33 20 61  a3) - index a3 a
0e70: 6c 72 65 61 64 79 20 65 78 69 73 74 73 7d 7d 0a  lready exists}}.
0e80: 0a 64 62 32 20 63 6c 6f 73 65 0a 0a 64 6f 5f 74  .db2 close..do_t
0e90: 65 73 74 20 63 6f 72 72 75 70 74 32 2d 33 2e 31  est corrupt2-3.1
0ea0: 20 7b 0a 20 20 66 6f 72 63 65 64 65 6c 65 74 65   {.  forcedelete
0eb0: 20 63 6f 72 72 75 70 74 2e 64 62 0a 20 20 66 6f   corrupt.db.  fo
0ec0: 72 63 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70  rcedelete corrup
0ed0: 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 73  t.db-journal.  s
0ee0: 71 6c 69 74 65 33 20 64 62 32 20 63 6f 72 72 75  qlite3 db2 corru
0ef0: 70 74 2e 64 62 20 0a 0a 20 20 65 78 65 63 73 71  pt.db ..  execsq
0f00: 6c 20 22 0a 20 20 20 20 24 3a 3a 70 72 65 73 71  l ".    $::presq
0f10: 6c 0a 20 20 20 20 50 52 41 47 4d 41 20 61 75 74  l.    PRAGMA aut
0f20: 6f 5f 76 61 63 75 75 6d 20 3d 20 31 3b 0a 20 20  o_vacuum = 1;.  
0f30: 20 20 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69    PRAGMA page_si
0f40: 7a 65 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 43  ze = 1024;.    C
0f50: 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61  REATE TABLE t1(a
0f60: 2c 20 62 2c 20 63 29 3b 0a 20 20 20 20 43 52 45  , b, c);.    CRE
0f70: 41 54 45 20 54 41 42 4c 45 20 74 32 28 61 2c 20  ATE TABLE t2(a, 
0f80: 62 2c 20 63 29 3b 0a 20 20 20 20 49 4e 53 45 52  b, c);.    INSER
0f90: 54 20 49 4e 54 4f 20 74 32 20 56 41 4c 55 45 53  T INTO t2 VALUES
0fa0: 28 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29  (randomblob(100)
0fb0: 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30  , randomblob(100
0fc0: 29 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30  ), randomblob(10
0fd0: 30 29 29 3b 0a 20 20 20 20 49 4e 53 45 52 54 20  0));.    INSERT 
0fe0: 49 4e 54 4f 20 74 32 20 53 45 4c 45 43 54 20 2a  INTO t2 SELECT *
0ff0: 20 46 52 4f 4d 20 74 32 3b 0a 20 20 20 20 49 4e   FROM t2;.    IN
1000: 53 45 52 54 20 49 4e 54 4f 20 74 32 20 53 45 4c  SERT INTO t2 SEL
1010: 45 43 54 20 2a 20 46 52 4f 4d 20 74 32 3b 0a 20  ECT * FROM t2;. 
1020: 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74     INSERT INTO t
1030: 32 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20  2 SELECT * FROM 
1040: 74 32 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49  t2;.    INSERT I
1050: 4e 54 4f 20 74 32 20 53 45 4c 45 43 54 20 2a 20  NTO t2 SELECT * 
1060: 46 52 4f 4d 20 74 32 3b 0a 20 20 22 20 64 62 32  FROM t2;.  " db2
1070: 0a 0a 20 20 64 62 32 20 63 6c 6f 73 65 0a 0a 20  ..  db2 close.. 
1080: 20 23 20 4f 6e 20 74 68 65 20 72 6f 6f 74 20 70   # On the root p
1090: 61 67 65 20 6f 66 20 74 61 62 6c 65 20 74 32 20  age of table t2 
10a0: 28 70 61 67 65 20 34 29 2c 20 73 65 74 20 6f 6e  (page 4), set on
10b0: 65 20 6f 66 20 74 68 65 20 63 68 69 6c 64 20 70  e of the child p
10c0: 61 67 65 2d 6e 75 6d 62 65 72 73 0a 20 20 23 20  age-numbers.  # 
10d0: 74 6f 20 30 2e 20 54 68 69 73 20 63 6f 72 72 75  to 0. This corru
10e0: 70 74 69 6f 6e 20 77 69 6c 6c 20 62 65 20 64 65  ption will be de
10f0: 74 65 63 74 65 64 20 77 68 65 6e 20 53 51 4c 69  tected when SQLi
1100: 74 65 20 61 74 74 65 6d 70 74 73 20 74 6f 20 75  te attempts to u
1110: 70 64 61 74 65 0a 20 20 23 20 74 68 65 20 70 6f  pdate.  # the po
1120: 69 6e 74 65 72 2d 6d 61 70 20 61 66 74 65 72 20  inter-map after 
1130: 6d 6f 76 69 6e 67 20 74 68 65 20 63 6f 6e 74 65  moving the conte
1140: 6e 74 20 6f 66 20 70 61 67 65 20 34 20 74 6f 20  nt of page 4 to 
1150: 70 61 67 65 20 33 20 61 73 20 70 61 72 74 0a 20  page 3 as part. 
1160: 20 23 20 6f 66 20 74 68 65 20 44 52 4f 50 20 54   # of the DROP T
1170: 41 42 4c 45 20 6f 70 65 72 61 74 69 6f 6e 20 62  ABLE operation b
1180: 65 6c 6f 77 2e 0a 20 20 23 0a 20 20 73 65 74 20  elow..  #.  set 
1190: 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74  fd [open corrupt
11a0: 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e 66 69  .db r+].  fconfi
11b0: 67 75 72 65 20 24 66 64 20 2d 65 6e 63 6f 64 69  gure $fd -encodi
11c0: 6e 67 20 62 69 6e 61 72 79 20 2d 74 72 61 6e 73  ng binary -trans
11d0: 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20  lation binary.  
11e0: 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20 31  seek $fd [expr 1
11f0: 30 32 34 2a 33 20 2b 20 31 32 5d 0a 20 20 73 65  024*3 + 12].  se
1200: 74 20 7a 43 65 6c 6c 6f 66 66 73 65 74 20 5b 72  t zCelloffset [r
1210: 65 61 64 20 24 66 64 20 32 5d 0a 20 20 62 69 6e  ead $fd 2].  bin
1220: 61 72 79 20 73 63 61 6e 20 24 7a 43 65 6c 6c 6f  ary scan $zCello
1230: 66 66 73 65 74 20 53 20 69 43 65 6c 6c 6f 66 66  ffset S iCelloff
1240: 73 65 74 0a 20 20 73 65 65 6b 20 24 66 64 20 5b  set.  seek $fd [
1250: 65 78 70 72 20 31 30 32 34 2a 33 20 2b 20 24 69  expr 1024*3 + $i
1260: 43 65 6c 6c 6f 66 66 73 65 74 5d 0a 20 20 70 75  Celloffset].  pu
1270: 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66  ts -nonewline $f
1280: 64 20 22 5c 30 30 5c 30 30 5c 30 30 5c 30 30 22  d "\00\00\00\00"
1290: 20 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 0a 20   .  close $fd.. 
12a0: 20 73 71 6c 69 74 65 33 20 64 62 32 20 63 6f 72   sqlite3 db2 cor
12b0: 72 75 70 74 2e 64 62 20 0a 20 20 63 61 74 63 68  rupt.db .  catch
12c0: 73 71 6c 20 22 0a 20 20 20 20 24 3a 3a 70 72 65  sql ".    $::pre
12d0: 73 71 6c 0a 20 20 20 20 44 52 4f 50 20 54 41 42  sql.    DROP TAB
12e0: 4c 45 20 74 31 3b 0a 20 20 22 20 64 62 32 0a 7d  LE t1;.  " db2.}
12f0: 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20 64 69   {1 {database di
1300: 73 6b 20 69 6d 61 67 65 20 69 73 20 6d 61 6c 66  sk image is malf
1310: 6f 72 6d 65 64 7d 7d 0a 0a 64 6f 5f 74 65 73 74  ormed}}..do_test
1320: 20 63 6f 72 72 75 70 74 32 2d 34 2e 31 20 7b 0a   corrupt2-4.1 {.
1330: 20 20 63 61 74 63 68 73 71 6c 20 7b 0a 20 20 20    catchsql {.   
1340: 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74   SELECT * FROM t
1350: 32 3b 0a 20 20 7d 20 64 62 32 0a 7d 20 7b 31 20  2;.  } db2.} {1 
1360: 7b 64 61 74 61 62 61 73 65 20 64 69 73 6b 20 69  {database disk i
1370: 6d 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65  mage is malforme
1380: 64 7d 7d 0a 0a 64 62 32 20 63 6c 6f 73 65 0a 0a  d}}..db2 close..
1390: 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69  unset -nocomplai
13a0: 6e 20 72 65 73 75 6c 74 0a 64 6f 5f 74 65 73 74  n result.do_test
13b0: 20 63 6f 72 72 75 70 74 32 2d 35 2e 31 20 7b 0a   corrupt2-5.1 {.
13c0: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 63 6f    forcedelete co
13d0: 72 72 75 70 74 2e 64 62 0a 20 20 66 6f 72 63 65  rrupt.db.  force
13e0: 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74 2e 64  delete corrupt.d
13f0: 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 73 71 6c 69  b-journal.  sqli
1400: 74 65 33 20 64 62 32 20 63 6f 72 72 75 70 74 2e  te3 db2 corrupt.
1410: 64 62 20 0a 0a 20 20 65 78 65 63 73 71 6c 20 22  db ..  execsql "
1420: 0a 20 20 20 20 24 3a 3a 70 72 65 73 71 6c 0a 20  .    $::presql. 
1430: 20 20 20 50 52 41 47 4d 41 20 61 75 74 6f 5f 76     PRAGMA auto_v
1440: 61 63 75 75 6d 20 3d 20 30 3b 0a 20 20 20 20 50  acuum = 0;.    P
1450: 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65 20  RAGMA page_size 
1460: 3d 20 31 30 32 34 3b 0a 20 20 20 20 43 52 45 41  = 1024;.    CREA
1470: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 20 62  TE TABLE t1(a, b
1480: 2c 20 63 29 3b 0a 20 20 20 20 43 52 45 41 54 45  , c);.    CREATE
1490: 20 54 41 42 4c 45 20 74 32 28 61 2c 20 62 2c 20   TABLE t2(a, b, 
14a0: 63 29 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49  c);.    INSERT I
14b0: 4e 54 4f 20 74 32 20 56 41 4c 55 45 53 28 72 61  NTO t2 VALUES(ra
14c0: 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 2c 20 72  ndomblob(100), r
14d0: 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 2c 20  andomblob(100), 
14e0: 72 61 6e 64 6f 6d 62 6c 6f 62 28 31 30 30 29 29  randomblob(100))
14f0: 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  ;.    INSERT INT
1500: 4f 20 74 32 20 53 45 4c 45 43 54 20 2a 20 46 52  O t2 SELECT * FR
1510: 4f 4d 20 74 32 3b 0a 20 20 20 20 49 4e 53 45 52  OM t2;.    INSER
1520: 54 20 49 4e 54 4f 20 74 32 20 53 45 4c 45 43 54  T INTO t2 SELECT
1530: 20 2a 20 46 52 4f 4d 20 74 32 3b 0a 20 20 20 20   * FROM t2;.    
1540: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 32 20 53  INSERT INTO t2 S
1550: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 32 3b  ELECT * FROM t2;
1560: 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  .    INSERT INTO
1570: 20 74 32 20 53 45 4c 45 43 54 20 2a 20 46 52 4f   t2 SELECT * FRO
1580: 4d 20 74 32 3b 0a 20 20 20 20 49 4e 53 45 52 54  M t2;.    INSERT
1590: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
15a0: 2a 20 46 52 4f 4d 20 74 32 3b 0a 20 20 22 20 64  * FROM t2;.  " d
15b0: 62 32 0a 0a 20 20 64 62 32 20 63 6c 6f 73 65 0a  b2..  db2 close.
15c0: 0a 20 20 23 20 54 68 69 73 20 62 6c 6f 63 6b 20  .  # This block 
15d0: 6c 69 6e 6b 73 20 61 20 70 61 67 65 20 66 72 6f  links a page fro
15e0: 6d 20 74 61 62 6c 65 20 74 32 20 69 6e 74 6f 20  m table t2 into 
15f0: 74 68 65 20 74 31 20 74 61 62 6c 65 20 73 74 72  the t1 table str
1600: 75 63 74 75 72 65 2e 0a 20 20 23 0a 20 20 73 65  ucture..  #.  se
1610: 74 20 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75  t fd [open corru
1620: 70 74 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e  pt.db r+].  fcon
1630: 66 69 67 75 72 65 20 24 66 64 20 2d 65 6e 63 6f  figure $fd -enco
1640: 64 69 6e 67 20 62 69 6e 61 72 79 20 2d 74 72 61  ding binary -tra
1650: 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a  nslation binary.
1660: 20 20 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72    seek $fd [expr
1670: 20 31 30 32 34 20 2b 20 31 32 5d 0a 20 20 73 65   1024 + 12].  se
1680: 74 20 7a 43 65 6c 6c 6f 66 66 73 65 74 20 5b 72  t zCelloffset [r
1690: 65 61 64 20 24 66 64 20 32 5d 0a 20 20 62 69 6e  ead $fd 2].  bin
16a0: 61 72 79 20 73 63 61 6e 20 24 7a 43 65 6c 6c 6f  ary scan $zCello
16b0: 66 66 73 65 74 20 53 20 69 43 65 6c 6c 6f 66 66  ffset S iCelloff
16c0: 73 65 74 0a 20 20 73 65 65 6b 20 24 66 64 20 5b  set.  seek $fd [
16d0: 65 78 70 72 20 31 30 32 34 20 2b 20 24 69 43 65  expr 1024 + $iCe
16e0: 6c 6c 6f 66 66 73 65 74 5d 0a 20 20 73 65 74 20  lloffset].  set 
16f0: 7a 43 68 69 6c 64 50 61 67 65 20 5b 72 65 61 64  zChildPage [read
1700: 20 24 66 64 20 34 5d 0a 20 20 73 65 65 6b 20 24   $fd 4].  seek $
1710: 66 64 20 5b 65 78 70 72 20 32 2a 31 30 32 34 20  fd [expr 2*1024 
1720: 2b 20 31 32 5d 0a 20 20 73 65 74 20 7a 43 65 6c  + 12].  set zCel
1730: 6c 6f 66 66 73 65 74 20 5b 72 65 61 64 20 24 66  loffset [read $f
1740: 64 20 32 5d 0a 20 20 62 69 6e 61 72 79 20 73 63  d 2].  binary sc
1750: 61 6e 20 24 7a 43 65 6c 6c 6f 66 66 73 65 74 20  an $zCelloffset 
1760: 53 20 69 43 65 6c 6c 6f 66 66 73 65 74 0a 20 20  S iCelloffset.  
1770: 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20 32  seek $fd [expr 2
1780: 2a 31 30 32 34 20 2b 20 24 69 43 65 6c 6c 6f 66  *1024 + $iCellof
1790: 66 73 65 74 5d 0a 20 20 70 75 74 73 20 2d 6e 6f  fset].  puts -no
17a0: 6e 65 77 6c 69 6e 65 20 24 66 64 20 24 7a 43 68  newline $fd $zCh
17b0: 69 6c 64 50 61 67 65 0a 20 20 63 6c 6f 73 65 20  ildPage.  close 
17c0: 24 66 64 0a 0a 20 20 73 71 6c 69 74 65 33 20 64  $fd..  sqlite3 d
17d0: 62 32 20 63 6f 72 72 75 70 74 2e 64 62 20 0a 20  b2 corrupt.db . 
17e0: 20 64 62 32 20 65 76 61 6c 20 24 3a 3a 70 72 65   db2 eval $::pre
17f0: 73 71 6c 0a 20 20 64 62 32 20 65 76 61 6c 20 7b  sql.  db2 eval {
1800: 53 45 4c 45 43 54 20 72 6f 77 69 64 20 46 52 4f  SELECT rowid FRO
1810: 4d 20 74 31 7d 20 7b 0a 20 20 20 20 73 65 74 20  M t1} {.    set 
1820: 72 65 73 75 6c 74 20 5b 64 62 32 20 65 76 61 6c  result [db2 eval
1830: 20 7b 70 72 61 67 6d 61 20 69 6e 74 65 67 72 69   {pragma integri
1840: 74 79 5f 63 68 65 63 6b 7d 5d 0a 20 20 20 20 62  ty_check}].    b
1850: 72 65 61 6b 0a 20 20 7d 0a 20 20 73 65 74 20 72  reak.  }.  set r
1860: 65 73 75 6c 74 0a 7d 20 7b 7b 2a 2a 2a 20 69 6e  esult.} {{*** in
1870: 20 64 61 74 61 62 61 73 65 20 6d 61 69 6e 20 2a   database main *
1880: 2a 2a 0a 4f 6e 20 74 72 65 65 20 70 61 67 65 20  **.On tree page 
1890: 32 20 63 65 6c 6c 20 30 3a 20 32 6e 64 20 72 65  2 cell 0: 2nd re
18a0: 66 65 72 65 6e 63 65 20 74 6f 20 70 61 67 65 20  ference to page 
18b0: 31 30 0a 50 61 67 65 20 34 20 69 73 20 6e 65 76  10.Page 4 is nev
18c0: 65 72 20 75 73 65 64 7d 7d 0a 0a 64 62 32 20 63  er used}}..db2 c
18d0: 6c 6f 73 65 0a 0a 70 72 6f 63 20 63 6f 72 72 75  lose..proc corru
18e0: 70 74 69 6f 6e 5f 74 65 73 74 20 7b 61 72 67 73  ption_test {args
18f0: 7d 20 7b 0a 20 20 73 65 74 20 41 28 2d 63 6f 72  } {.  set A(-cor
1900: 72 75 70 74 29 20 7b 7d 0a 20 20 73 65 74 20 41  rupt) {}.  set A
1910: 28 2d 73 71 6c 70 72 65 70 29 20 7b 7d 0a 20 20  (-sqlprep) {}.  
1920: 73 65 74 20 41 28 2d 74 63 6c 70 72 65 70 29 20  set A(-tclprep) 
1930: 7b 7d 0a 20 20 61 72 72 61 79 20 73 65 74 20 41  {}.  array set A
1940: 20 24 61 72 67 73 0a 0a 20 20 63 61 74 63 68 20   $args..  catch 
1950: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66 6f 72  {db close}.  for
1960: 63 65 64 65 6c 65 74 65 20 63 6f 72 72 75 70 74  cedelete corrupt
1970: 2e 64 62 0a 20 20 66 6f 72 63 65 64 65 6c 65 74  .db.  forcedelet
1980: 65 20 63 6f 72 72 75 70 74 2e 64 62 2d 6a 6f 75  e corrupt.db-jou
1990: 72 6e 61 6c 0a 0a 20 20 73 71 6c 69 74 65 33 20  rnal..  sqlite3 
19a0: 64 62 20 63 6f 72 72 75 70 74 2e 64 62 20 0a 20  db corrupt.db . 
19b0: 20 64 62 20 65 76 61 6c 20 24 3a 3a 70 72 65 73   db eval $::pres
19c0: 71 6c 0a 20 20 65 76 61 6c 20 24 41 28 2d 74 63  ql.  eval $A(-tc
19d0: 6c 70 72 65 70 29 0a 20 20 64 62 20 65 76 61 6c  lprep).  db eval
19e0: 20 24 41 28 2d 73 71 6c 70 72 65 70 29 0a 20 20   $A(-sqlprep).  
19f0: 64 62 20 63 6c 6f 73 65 0a 0a 20 20 65 76 61 6c  db close..  eval
1a00: 20 24 41 28 2d 63 6f 72 72 75 70 74 29 0a 0a 20   $A(-corrupt).. 
1a10: 20 73 71 6c 69 74 65 33 20 64 62 20 63 6f 72 72   sqlite3 db corr
1a20: 75 70 74 2e 64 62 0a 20 20 65 76 61 6c 20 24 41  upt.db.  eval $A
1a30: 28 2d 74 65 73 74 29 0a 7d 0a 0a 69 66 63 61 70  (-test).}..ifcap
1a40: 61 62 6c 65 20 61 75 74 6f 76 61 63 75 75 6d 20  able autovacuum 
1a50: 7b 0a 20 20 23 20 54 68 65 20 74 65 73 74 73 20  {.  # The tests 
1a60: 77 69 74 68 69 6e 20 74 68 69 73 20 62 6c 6f 63  within this bloc
1a70: 6b 20 2d 20 63 6f 72 72 75 70 74 32 2d 36 2e 2a  k - corrupt2-6.*
1a80: 20 2d 20 61 69 6d 20 74 6f 20 74 65 73 74 20 63   - aim to test c
1a90: 6f 72 72 75 70 74 69 6f 6e 0a 20 20 23 20 64 65  orruption.  # de
1aa0: 74 65 63 74 69 6f 6e 20 77 69 74 68 69 6e 20 61  tection within a
1ab0: 6e 20 69 6e 63 72 65 6d 65 6e 74 61 6c 2d 76 61  n incremental-va
1ac0: 63 75 75 6d 2e 20 57 68 65 6e 20 61 6e 20 69 6e  cuum. When an in
1ad0: 63 72 65 6d 65 6e 74 61 6c 2d 76 61 63 75 75 6d  cremental-vacuum
1ae0: 0a 20 20 23 20 73 74 65 70 20 69 73 20 65 78 65  .  # step is exe
1af0: 63 75 74 65 64 2c 20 74 68 65 20 6c 61 73 74 20  cuted, the last 
1b00: 6e 6f 6e 2d 66 72 65 65 20 70 61 67 65 20 6f 66  non-free page of
1b10: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
1b20: 6c 65 20 69 73 20 0a 20 20 23 20 6d 6f 76 65 64  le is .  # moved
1b30: 20 69 6e 74 6f 20 61 20 66 72 65 65 20 73 70 61   into a free spa
1b40: 63 65 20 69 6e 20 74 68 65 20 62 6f 64 79 20 6f  ce in the body o
1b50: 66 20 74 68 65 20 66 69 6c 65 2e 20 41 66 74 65  f the file. Afte
1b60: 72 20 64 6f 69 6e 67 20 73 6f 2c 0a 20 20 23 20  r doing so,.  # 
1b70: 74 68 65 20 70 61 67 65 20 72 65 66 65 72 65 6e  the page referen
1b80: 63 65 20 69 6e 20 74 68 65 20 70 61 72 65 6e 74  ce in the parent
1b90: 20 70 61 67 65 20 6d 75 73 74 20 62 65 20 75 70   page must be up
1ba0: 64 61 74 65 64 20 74 6f 20 72 65 66 65 72 0a 20  dated to refer. 
1bb0: 20 23 20 74 6f 20 74 68 65 20 6e 65 77 20 6c 6f   # to the new lo
1bc0: 63 61 74 69 6f 6e 2e 20 54 68 65 73 65 20 74 65  cation. These te
1bd0: 73 74 73 20 74 65 73 74 20 74 68 65 20 6f 75 74  sts test the out
1be0: 63 6f 6d 65 20 6f 66 20 63 6f 72 72 75 70 74 69  come of corrupti
1bf0: 6e 67 0a 20 20 23 20 74 68 61 74 20 70 61 67 65  ng.  # that page
1c00: 20 72 65 66 65 72 65 6e 63 65 20 62 65 66 6f 72   reference befor
1c10: 65 20 70 65 72 66 6f 72 6d 69 6e 67 20 74 68 65  e performing the
1c20: 20 69 6e 63 72 65 6d 65 6e 74 61 6c 20 76 61 63   incremental vac
1c30: 75 75 6d 2e 0a 20 20 23 0a 0a 20 20 23 20 54 68  uum..  #..  # Th
1c40: 65 20 6c 61 73 74 20 70 61 67 65 20 69 6e 20 74  e last page in t
1c50: 68 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65  he database page
1c60: 20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20 70   is the second p
1c70: 61 67 65 20 0a 20 20 23 20 69 6e 20 61 6e 20 6f  age .  # in an o
1c80: 76 65 72 66 6c 6f 77 20 63 68 61 69 6e 2e 0a 20  verflow chain.. 
1c90: 20 23 0a 20 20 63 6f 72 72 75 70 74 69 6f 6e 5f   #.  corruption_
1ca0: 74 65 73 74 20 2d 73 71 6c 70 72 65 70 20 7b 0a  test -sqlprep {.
1cb0: 20 20 20 20 50 52 41 47 4d 41 20 61 75 74 6f 5f      PRAGMA auto_
1cc0: 76 61 63 75 75 6d 20 3d 20 69 6e 63 72 65 6d 65  vacuum = increme
1cd0: 6e 74 61 6c 3b 0a 20 20 20 20 50 52 41 47 4d 41  ntal;.    PRAGMA
1ce0: 20 70 61 67 65 5f 73 69 7a 65 20 3d 20 31 30 32   page_size = 102
1cf0: 34 3b 0a 20 20 20 20 43 52 45 41 54 45 20 54 41  4;.    CREATE TA
1d00: 42 4c 45 20 74 31 28 61 2c 20 62 29 3b 0a 20 20  BLE t1(a, b);.  
1d10: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
1d20: 20 56 41 4c 55 45 53 28 31 2c 20 72 61 6e 64 6f   VALUES(1, rando
1d30: 6d 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20  mblob(2500));.  
1d40: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
1d50: 20 56 41 4c 55 45 53 28 32 2c 20 72 61 6e 64 6f   VALUES(2, rando
1d60: 6d 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20  mblob(2500));.  
1d70: 20 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31    DELETE FROM t1
1d80: 20 57 48 45 52 45 20 61 20 3d 20 31 3b 0a 20 20   WHERE a = 1;.  
1d90: 7d 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 20  } -corrupt {.   
1da0: 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63 6f 72   hexio_write cor
1db0: 72 75 70 74 2e 64 62 20 5b 65 78 70 72 20 31 30  rupt.db [expr 10
1dc0: 32 34 2a 35 5d 20 30 30 30 30 30 30 30 38 0a 20  24*5] 00000008. 
1dd0: 20 7d 20 2d 74 65 73 74 20 7b 0a 20 20 20 20 64   } -test {.    d
1de0: 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d  o_test corrupt2-
1df0: 36 2e 31 20 7b 0a 20 20 20 20 20 20 63 61 74 63  6.1 {.      catc
1e00: 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c  hsql " $::presql
1e10: 20 70 72 61 67 6d 61 20 69 6e 63 72 65 6d 65 6e   pragma incremen
1e20: 74 61 6c 5f 76 61 63 75 75 6d 20 3d 20 31 20 22  tal_vacuum = 1 "
1e30: 0a 20 20 20 20 7d 20 7b 31 20 7b 64 61 74 61 62  .    } {1 {datab
1e40: 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69  ase disk image i
1e50: 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20  s malformed}}.  
1e60: 7d 0a 0a 20 20 23 20 54 68 65 20 6c 61 73 74 20  }..  # The last 
1e70: 70 61 67 65 20 69 6e 20 74 68 65 20 64 61 74 61  page in the data
1e80: 62 61 73 65 20 70 61 67 65 20 69 73 20 61 20 6e  base page is a n
1e90: 6f 6e 2d 72 6f 6f 74 20 62 2d 74 72 65 65 20 70  on-root b-tree p
1ea0: 61 67 65 2e 0a 20 20 23 0a 20 20 63 6f 72 72 75  age..  #.  corru
1eb0: 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c 70  ption_test -sqlp
1ec0: 72 65 70 20 7b 0a 20 20 20 20 50 52 41 47 4d 41  rep {.    PRAGMA
1ed0: 20 61 75 74 6f 5f 76 61 63 75 75 6d 20 3d 20 69   auto_vacuum = i
1ee0: 6e 63 72 65 6d 65 6e 74 61 6c 3b 0a 20 20 20 20  ncremental;.    
1ef0: 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65  PRAGMA page_size
1f00: 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 43 52 45   = 1024;.    CRE
1f10: 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49  ATE TABLE t1(a I
1f20: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b  NTEGER PRIMARY K
1f30: 45 59 2c 20 62 29 3b 0a 20 20 20 20 49 4e 53 45  EY, b);.    INSE
1f40: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
1f50: 53 28 31 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  S(1, randomblob(
1f60: 32 35 30 30 29 29 3b 0a 20 20 20 20 49 4e 53 45  2500));.    INSE
1f70: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
1f80: 53 28 32 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  S(2, randomblob(
1f90: 35 30 29 29 3b 0a 20 20 20 20 49 4e 53 45 52 54  50));.    INSERT
1fa0: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
1fb0: 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  NULL, randomblob
1fc0: 28 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20  (50) FROM t1;.  
1fd0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
1fe0: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
1ff0: 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f  ndomblob(50) FRO
2000: 4d 20 74 31 3b 0a 20 20 20 20 49 4e 53 45 52 54  M t1;.    INSERT
2010: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
2020: 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  NULL, randomblob
2030: 28 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20  (50) FROM t1;.  
2040: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
2050: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
2060: 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f  ndomblob(50) FRO
2070: 4d 20 74 31 3b 0a 20 20 20 20 44 45 4c 45 54 45  M t1;.    DELETE
2080: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 61   FROM t1 WHERE a
2090: 20 3d 20 31 3b 0a 20 20 7d 20 2d 63 6f 72 72 75   = 1;.  } -corru
20a0: 70 74 20 7b 0a 20 20 20 20 68 65 78 69 6f 5f 77  pt {.    hexio_w
20b0: 72 69 74 65 20 63 6f 72 72 75 70 74 2e 64 62 20  rite corrupt.db 
20c0: 5b 65 78 70 72 20 31 30 32 34 2a 32 20 2b 20 38  [expr 1024*2 + 8
20d0: 5d 20 30 30 30 30 30 30 30 39 0a 20 20 7d 20 2d  ] 00000009.  } -
20e0: 74 65 73 74 20 7b 0a 20 20 20 20 64 6f 5f 74 65  test {.    do_te
20f0: 73 74 20 63 6f 72 72 75 70 74 32 2d 36 2e 32 20  st corrupt2-6.2 
2100: 7b 0a 20 20 20 20 20 20 63 61 74 63 68 73 71 6c  {.      catchsql
2110: 20 22 20 24 3a 3a 70 72 65 73 71 6c 20 70 72 61   " $::presql pra
2120: 67 6d 61 20 69 6e 63 72 65 6d 65 6e 74 61 6c 5f  gma incremental_
2130: 76 61 63 75 75 6d 20 3d 20 31 20 22 0a 20 20 20  vacuum = 1 ".   
2140: 20 7d 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20   } {1 {database 
2150: 64 69 73 6b 20 69 6d 61 67 65 20 69 73 20 6d 61  disk image is ma
2160: 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20 7d 0a 0a 20  lformed}}.  }.. 
2170: 20 23 20 53 65 74 20 75 70 20 61 20 70 6f 69 6e   # Set up a poin
2180: 74 65 72 2d 6d 61 70 20 65 6e 74 72 79 20 73 6f  ter-map entry so
2190: 20 74 68 61 74 20 74 68 65 20 6c 61 73 74 20 70   that the last p
21a0: 61 67 65 20 6f 66 20 74 68 65 20 64 61 74 61 62  age of the datab
21b0: 61 73 65 0a 20 20 23 20 66 69 6c 65 20 61 70 70  ase.  # file app
21c0: 65 61 72 73 20 74 6f 20 62 65 20 61 20 62 2d 74  ears to be a b-t
21d0: 72 65 65 20 72 6f 6f 74 20 70 61 67 65 2e 20 54  ree root page. T
21e0: 68 69 73 20 73 68 6f 75 6c 64 20 62 65 20 64 65  his should be de
21f0: 74 65 63 74 65 64 0a 20 20 23 20 61 73 20 63 6f  tected.  # as co
2200: 72 72 75 70 74 69 6f 6e 2e 0a 20 20 23 0a 20 20  rruption..  #.  
2210: 63 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20  corruption_test 
2220: 2d 73 71 6c 70 72 65 70 20 7b 0a 20 20 20 20 50  -sqlprep {.    P
2230: 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75  RAGMA auto_vacuu
2240: 6d 20 3d 20 69 6e 63 72 65 6d 65 6e 74 61 6c 3b  m = incremental;
2250: 0a 20 20 20 20 50 52 41 47 4d 41 20 70 61 67 65  .    PRAGMA page
2260: 5f 73 69 7a 65 20 3d 20 31 30 32 34 3b 0a 20 20  _size = 1024;.  
2270: 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74    CREATE TABLE t
2280: 31 28 61 20 49 4e 54 45 47 45 52 20 50 52 49 4d  1(a INTEGER PRIM
2290: 41 52 59 20 4b 45 59 2c 20 62 29 3b 0a 20 20 20  ARY KEY, b);.   
22a0: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
22b0: 56 41 4c 55 45 53 28 31 2c 20 72 61 6e 64 6f 6d  VALUES(1, random
22c0: 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20 20  blob(2500));.   
22d0: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
22e0: 56 41 4c 55 45 53 28 32 2c 20 72 61 6e 64 6f 6d  VALUES(2, random
22f0: 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20 20  blob(2500));.   
2300: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20   INSERT INTO t1 
2310: 56 41 4c 55 45 53 28 33 2c 20 72 61 6e 64 6f 6d  VALUES(3, random
2320: 62 6c 6f 62 28 32 35 30 30 29 29 3b 0a 20 20 20  blob(2500));.   
2330: 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31 20   DELETE FROM t1 
2340: 57 48 45 52 45 20 61 20 3d 20 31 3b 0a 20 20 7d  WHERE a = 1;.  }
2350: 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 20 20   -corrupt {.    
2360: 73 65 74 20 6e 50 61 67 65 20 5b 65 78 70 72 20  set nPage [expr 
2370: 5b 66 69 6c 65 20 73 69 7a 65 20 63 6f 72 72 75  [file size corru
2380: 70 74 2e 64 62 5d 20 2f 20 31 30 32 34 5d 0a 20  pt.db] / 1024]. 
2390: 20 20 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63     hexio_write c
23a0: 6f 72 72 75 70 74 2e 64 62 20 5b 65 78 70 72 20  orrupt.db [expr 
23b0: 31 30 32 34 20 2b 20 28 24 6e 50 61 67 65 2d 33  1024 + ($nPage-3
23c0: 29 2a 35 5d 20 30 31 30 30 30 30 30 30 30 0a 20  )*5] 010000000. 
23d0: 20 7d 20 2d 74 65 73 74 20 7b 0a 20 20 20 20 64   } -test {.    d
23e0: 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d  o_test corrupt2-
23f0: 36 2e 33 20 7b 0a 20 20 20 20 20 20 63 61 74 63  6.3 {.      catc
2400: 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c  hsql " $::presql
2410: 20 70 72 61 67 6d 61 20 69 6e 63 72 65 6d 65 6e   pragma incremen
2420: 74 61 6c 5f 76 61 63 75 75 6d 20 3d 20 31 20 22  tal_vacuum = 1 "
2430: 0a 20 20 20 20 7d 20 7b 31 20 7b 64 61 74 61 62  .    } {1 {datab
2440: 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69  ase disk image i
2450: 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20  s malformed}}.  
2460: 7d 0a 0a 20 20 69 66 20 7b 21 5b 6e 6f 6e 7a 65  }..  if {![nonze
2470: 72 6f 5f 72 65 73 65 72 76 65 64 5f 62 79 74 65  ro_reserved_byte
2480: 73 5d 7d 20 7b 0a 20 20 20 20 63 6f 72 72 75 70  s]} {.    corrup
2490: 74 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c 70 72  tion_test -sqlpr
24a0: 65 70 20 7b 0a 20 20 20 20 20 20 50 52 41 47 4d  ep {.      PRAGM
24b0: 41 20 61 75 74 6f 5f 76 61 63 75 75 6d 20 3d 20  A auto_vacuum = 
24c0: 31 3b 0a 20 20 20 20 20 20 50 52 41 47 4d 41 20  1;.      PRAGMA 
24d0: 70 61 67 65 5f 73 69 7a 65 20 3d 20 31 30 32 34  page_size = 1024
24e0: 3b 0a 20 20 20 20 20 20 43 52 45 41 54 45 20 54  ;.      CREATE T
24f0: 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47 45  ABLE t1(a INTEGE
2500: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62  R PRIMARY KEY, b
2510: 29 3b 0a 20 20 20 20 20 20 49 4e 53 45 52 54 20  );.      INSERT 
2520: 49 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 31  INTO t1 VALUES(1
2530: 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 32 35 30  , randomblob(250
2540: 30 29 29 3b 0a 20 20 20 20 20 20 44 45 4c 45 54  0));.      DELET
2550: 45 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20  E FROM t1 WHERE 
2560: 61 20 3d 20 31 3b 0a 20 20 20 20 7d 20 2d 63 6f  a = 1;.    } -co
2570: 72 72 75 70 74 20 7b 0a 20 20 20 20 20 20 73 65  rrupt {.      se
2580: 74 20 6e 41 70 70 65 6e 64 20 5b 65 78 70 72 20  t nAppend [expr 
2590: 31 30 32 34 2a 32 30 37 20 2d 20 5b 66 69 6c 65  1024*207 - [file
25a0: 20 73 69 7a 65 20 63 6f 72 72 75 70 74 2e 64 62   size corrupt.db
25b0: 5d 5d 0a 20 20 20 20 20 20 73 65 74 20 66 64 20  ]].      set fd 
25c0: 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e 64 62  [open corrupt.db
25d0: 20 72 2b 5d 0a 20 20 20 20 20 20 73 65 65 6b 20   r+].      seek 
25e0: 24 66 64 20 30 20 65 6e 64 0a 20 20 20 20 20 20  $fd 0 end.      
25f0: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
2600: 24 66 64 20 5b 73 74 72 69 6e 67 20 72 65 70 65  $fd [string repe
2610: 61 74 20 78 20 24 6e 41 70 70 65 6e 64 5d 0a 20  at x $nAppend]. 
2620: 20 20 20 20 20 63 6c 6f 73 65 20 24 66 64 0a 20       close $fd. 
2630: 20 20 20 20 20 68 65 78 69 6f 5f 77 72 69 74 65       hexio_write
2640: 20 63 6f 72 72 75 70 74 2e 64 62 20 32 38 20 30   corrupt.db 28 0
2650: 30 30 30 30 30 30 30 0a 20 20 20 20 7d 20 2d 74  0000000.    } -t
2660: 65 73 74 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74  est {.      do_t
2670: 65 73 74 20 63 6f 72 72 75 70 74 32 2d 36 2e 34  est corrupt2-6.4
2680: 20 7b 0a 20 20 20 20 20 20 20 20 63 61 74 63 68   {.        catch
2690: 73 71 6c 20 22 20 0a 20 20 20 20 20 20 20 20 20  sql " .         
26a0: 20 24 3a 3a 70 72 65 73 71 6c 20 0a 20 20 20 20   $::presql .    
26b0: 20 20 20 20 20 20 42 45 47 49 4e 20 45 58 43 4c        BEGIN EXCL
26c0: 55 53 49 56 45 3b 0a 20 20 20 20 20 20 20 20 20  USIVE;.         
26d0: 20 43 4f 4d 4d 49 54 3b 0a 20 20 20 20 20 20 20   COMMIT;.       
26e0: 20 22 0a 20 20 20 20 20 20 7d 20 7b 31 20 7b 64   ".      } {1 {d
26f0: 61 74 61 62 61 73 65 20 64 69 73 6b 20 69 6d 61  atabase disk ima
2700: 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d  ge is malformed}
2710: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 0a  }.    }.  }.}...
2720: 73 65 74 20 73 71 6c 70 72 65 70 20 7b 0a 20 20  set sqlprep {.  
2730: 50 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75  PRAGMA auto_vacu
2740: 75 6d 20 3d 20 30 3b 0a 20 20 50 52 41 47 4d 41  um = 0;.  PRAGMA
2750: 20 70 61 67 65 5f 73 69 7a 65 20 3d 20 31 30 32   page_size = 102
2760: 34 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c  4;.  CREATE TABL
2770: 45 20 74 31 28 61 20 49 4e 54 45 47 45 52 20 50  E t1(a INTEGER P
2780: 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 29 3b 0a  RIMARY KEY, b);.
2790: 20 20 43 52 45 41 54 45 20 49 4e 44 45 58 20 69    CREATE INDEX i
27a0: 31 20 4f 4e 20 74 31 28 62 29 3b 0a 20 20 49 4e  1 ON t1(b);.  IN
27b0: 53 45 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c  SERT INTO t1 VAL
27c0: 55 45 53 28 31 2c 20 72 61 6e 64 6f 6d 62 6c 6f  UES(1, randomblo
27d0: 62 28 35 30 29 29 3b 0a 20 20 49 4e 53 45 52 54  b(50));.  INSERT
27e0: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
27f0: 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62  NULL, randomblob
2800: 28 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20  (50) FROM t1;.  
2810: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 53  INSERT INTO t1 S
2820: 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64  ELECT NULL, rand
2830: 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f 4d 20  omblob(50) FROM 
2840: 74 31 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54  t1;.  INSERT INT
2850: 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c  O t1 SELECT NULL
2860: 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 35 30 29  , randomblob(50)
2870: 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45   FROM t1;.  INSE
2880: 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43  RT INTO t1 SELEC
2890: 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c  T NULL, randombl
28a0: 6f 62 28 35 30 29 20 46 52 4f 4d 20 74 31 3b 0a  ob(50) FROM t1;.
28b0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
28c0: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
28d0: 6e 64 6f 6d 62 6c 6f 62 28 35 30 29 20 46 52 4f  ndomblob(50) FRO
28e0: 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54 20 49  M t1;.  INSERT I
28f0: 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e 55  NTO t1 SELECT NU
2900: 4c 4c 2c 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 35  LL, randomblob(5
2910: 30 29 20 46 52 4f 4d 20 74 31 3b 0a 7d 0a 0a 63  0) FROM t1;.}..c
2920: 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d  orruption_test -
2930: 73 71 6c 70 72 65 70 20 24 73 71 6c 70 72 65 70  sqlprep $sqlprep
2940: 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 23 20   -corrupt {.  # 
2950: 53 65 74 20 74 68 65 20 70 61 67 65 2d 66 6c 61  Set the page-fla
2960: 67 73 20 6f 66 20 6f 6e 65 20 6f 66 20 74 68 65  gs of one of the
2970: 20 6c 65 61 66 20 70 61 67 65 73 20 6f 66 20 74   leaf pages of t
2980: 68 65 20 69 6e 64 65 78 20 42 2d 54 72 65 65 20  he index B-Tree 
2990: 74 6f 0a 20 20 23 20 30 78 30 44 20 28 69 6e 74  to.  # 0x0D (int
29a0: 65 72 70 72 65 74 65 64 20 62 79 20 53 51 4c 69  erpreted by SQLi
29b0: 74 65 20 61 73 20 22 6c 65 61 66 20 70 61 67 65  te as "leaf page
29c0: 20 6f 66 20 61 20 74 61 62 6c 65 20 42 2d 54 72   of a table B-Tr
29d0: 65 65 22 29 2e 0a 20 20 23 0a 20 20 73 65 74 20  ee")..  #.  set 
29e0: 66 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74  fd [open corrupt
29f0: 2e 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e 66 69  .db r+].  fconfi
2a00: 67 75 72 65 20 24 66 64 20 2d 74 72 61 6e 73 6c  gure $fd -transl
2a10: 61 74 69 6f 6e 20 62 69 6e 61 72 79 20 2d 65 6e  ation binary -en
2a20: 63 6f 64 69 6e 67 20 62 69 6e 61 72 79 0a 20 20  coding binary.  
2a30: 73 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20 31  seek $fd [expr 1
2a40: 30 32 34 2a 32 20 2b 20 38 5d 20 0a 20 20 73 65  024*2 + 8] .  se
2a50: 74 20 7a 52 69 67 68 74 43 68 69 6c 64 20 5b 72  t zRightChild [r
2a60: 65 61 64 20 24 66 64 20 34 5d 0a 20 20 62 69 6e  ead $fd 4].  bin
2a70: 61 72 79 20 73 63 61 6e 20 24 7a 52 69 67 68 74  ary scan $zRight
2a80: 43 68 69 6c 64 20 49 20 69 52 69 67 68 74 43 68  Child I iRightCh
2a90: 69 6c 64 0a 20 20 73 65 65 6b 20 24 66 64 20 5b  ild.  seek $fd [
2aa0: 65 78 70 72 20 31 30 32 34 2a 28 24 69 52 69 67  expr 1024*($iRig
2ab0: 68 74 43 68 69 6c 64 2d 31 29 5d 0a 20 20 70 75  htChild-1)].  pu
2ac0: 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66  ts -nonewline $f
2ad0: 64 20 22 5c 78 30 44 22 0a 20 20 63 6c 6f 73 65  d "\x0D".  close
2ae0: 20 24 66 64 0a 7d 20 2d 74 65 73 74 20 7b 0a 20   $fd.} -test {. 
2af0: 20 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74   do_test corrupt
2b00: 32 2d 37 2e 31 20 7b 0a 20 20 20 20 63 61 74 63  2-7.1 {.    catc
2b10: 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c  hsql " $::presql
2b20: 20 53 45 4c 45 43 54 20 62 20 46 52 4f 4d 20 74   SELECT b FROM t
2b30: 31 20 4f 52 44 45 52 20 42 59 20 62 20 41 53 43  1 ORDER BY b ASC
2b40: 20 22 0a 20 20 7d 20 7b 31 20 7b 64 61 74 61 62   ".  } {1 {datab
2b50: 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20 69  ase disk image i
2b60: 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d 0a  s malformed}}.}.
2b70: 0a 63 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74  .corruption_test
2b80: 20 2d 73 71 6c 70 72 65 70 20 24 73 71 6c 70 72   -sqlprep $sqlpr
2b90: 65 70 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20  ep -corrupt {.  
2ba0: 23 20 4d 65 73 73 20 75 70 20 74 68 65 20 70 61  # Mess up the pa
2bb0: 67 65 2d 68 65 61 64 65 72 20 6f 66 20 6f 6e 65  ge-header of one
2bc0: 20 6f 66 20 74 68 65 20 6c 65 61 66 20 70 61 67   of the leaf pag
2bd0: 65 73 20 6f 66 20 74 68 65 20 69 6e 64 65 78 20  es of the index 
2be0: 42 2d 54 72 65 65 2e 0a 20 20 23 20 54 68 65 20  B-Tree..  # The 
2bf0: 63 6f 72 72 75 70 74 69 6f 6e 20 69 73 20 64 65  corruption is de
2c00: 74 65 63 74 65 64 20 61 73 20 70 61 72 74 20 6f  tected as part o
2c10: 66 20 61 6e 20 4f 50 5f 50 72 65 76 20 6f 70 63  f an OP_Prev opc
2c20: 6f 64 65 2e 0a 20 20 23 0a 20 20 73 65 74 20 66  ode..  #.  set f
2c30: 64 20 5b 6f 70 65 6e 20 63 6f 72 72 75 70 74 2e  d [open corrupt.
2c40: 64 62 20 72 2b 5d 0a 20 20 66 63 6f 6e 66 69 67  db r+].  fconfig
2c50: 75 72 65 20 24 66 64 20 2d 74 72 61 6e 73 6c 61  ure $fd -transla
2c60: 74 69 6f 6e 20 62 69 6e 61 72 79 20 2d 65 6e 63  tion binary -enc
2c70: 6f 64 69 6e 67 20 62 69 6e 61 72 79 0a 20 20 73  oding binary.  s
2c80: 65 65 6b 20 24 66 64 20 5b 65 78 70 72 20 31 30  eek $fd [expr 10
2c90: 32 34 2a 32 20 2b 20 31 32 5d 20 0a 20 20 73 65  24*2 + 12] .  se
2ca0: 74 20 7a 43 65 6c 6c 4f 66 66 73 65 74 20 5b 72  t zCellOffset [r
2cb0: 65 61 64 20 24 66 64 20 32 5d 0a 20 20 62 69 6e  ead $fd 2].  bin
2cc0: 61 72 79 20 73 63 61 6e 20 24 7a 43 65 6c 6c 4f  ary scan $zCellO
2cd0: 66 66 73 65 74 20 53 20 69 43 65 6c 6c 4f 66 66  ffset S iCellOff
2ce0: 73 65 74 0a 20 20 73 65 65 6b 20 24 66 64 20 5b  set.  seek $fd [
2cf0: 65 78 70 72 20 31 30 32 34 2a 32 20 2b 20 24 69  expr 1024*2 + $i
2d00: 43 65 6c 6c 4f 66 66 73 65 74 5d 0a 20 20 73 65  CellOffset].  se
2d10: 74 20 7a 43 68 69 6c 64 20 5b 72 65 61 64 20 24  t zChild [read $
2d20: 66 64 20 34 5d 0a 20 20 62 69 6e 61 72 79 20 73  fd 4].  binary s
2d30: 63 61 6e 20 24 7a 43 68 69 6c 64 20 49 20 69 43  can $zChild I iC
2d40: 68 69 6c 64 0a 20 20 73 65 65 6b 20 24 66 64 20  hild.  seek $fd 
2d50: 5b 65 78 70 72 20 31 30 32 34 2a 28 24 69 43 68  [expr 1024*($iCh
2d60: 69 6c 64 2d 31 29 2b 33 5d 0a 20 20 70 75 74 73  ild-1)+3].  puts
2d70: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 66 64 20   -nonewline $fd 
2d80: 22 5c 78 46 46 46 46 22 0a 20 20 63 6c 6f 73 65  "\xFFFF".  close
2d90: 20 24 66 64 0a 7d 20 2d 74 65 73 74 20 7b 0a 20   $fd.} -test {. 
2da0: 20 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74   do_test corrupt
2db0: 32 2d 37 2e 31 20 7b 0a 20 20 20 20 63 61 74 63  2-7.1 {.    catc
2dc0: 68 73 71 6c 20 22 20 24 3a 3a 70 72 65 73 71 6c  hsql " $::presql
2dd0: 20 53 45 4c 45 43 54 20 62 20 46 52 4f 4d 20 74   SELECT b FROM t
2de0: 31 20 4f 52 44 45 52 20 42 59 20 62 20 44 45 53  1 ORDER BY b DES
2df0: 43 20 22 0a 20 20 7d 20 7b 31 20 7b 64 61 74 61  C ".  } {1 {data
2e00: 62 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20  base disk image 
2e10: 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d  is malformed}}.}
2e20: 0a 0a 63 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73  ..corruption_tes
2e30: 74 20 2d 73 71 6c 70 72 65 70 20 24 73 71 6c 70  t -sqlprep $sqlp
2e40: 72 65 70 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20  rep -corrupt {. 
2e50: 20 23 20 53 65 74 20 74 68 65 20 70 61 67 65 2d   # Set the page-
2e60: 66 6c 61 67 73 20 6f 66 20 6f 6e 65 20 6f 66 20  flags of one of 
2e70: 74 68 65 20 6c 65 61 66 20 70 61 67 65 73 20 6f  the leaf pages o
2e80: 66 20 74 68 65 20 74 61 62 6c 65 20 42 2d 54 72  f the table B-Tr
2e90: 65 65 20 74 6f 0a 20 20 23 20 30 78 30 41 20 28  ee to.  # 0x0A (
2ea0: 69 6e 74 65 72 70 72 65 74 65 64 20 62 79 20 53  interpreted by S
2eb0: 51 4c 69 74 65 20 61 73 20 22 6c 65 61 66 20 70  QLite as "leaf p
2ec0: 61 67 65 20 6f 66 20 61 6e 20 69 6e 64 65 78 20  age of an index 
2ed0: 42 2d 54 72 65 65 22 29 2e 0a 20 20 23 0a 20 20  B-Tree")..  #.  
2ee0: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 63 6f 72  set fd [open cor
2ef0: 72 75 70 74 2e 64 62 20 72 2b 5d 0a 20 20 66 63  rupt.db r+].  fc
2f00: 6f 6e 66 69 67 75 72 65 20 24 66 64 20 2d 74 72  onfigure $fd -tr
2f10: 61 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79  anslation binary
2f20: 20 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72   -encoding binar
2f30: 79 0a 20 20 73 65 65 6b 20 24 66 64 20 5b 65 78  y.  seek $fd [ex
2f40: 70 72 20 31 30 32 34 2a 31 20 2b 20 38 5d 20 0a  pr 1024*1 + 8] .
2f50: 20 20 73 65 74 20 7a 52 69 67 68 74 43 68 69 6c    set zRightChil
2f60: 64 20 5b 72 65 61 64 20 24 66 64 20 34 5d 0a 20  d [read $fd 4]. 
2f70: 20 62 69 6e 61 72 79 20 73 63 61 6e 20 24 7a 52   binary scan $zR
2f80: 69 67 68 74 43 68 69 6c 64 20 49 20 69 52 69 67  ightChild I iRig
2f90: 68 74 43 68 69 6c 64 0a 20 20 73 65 65 6b 20 24  htChild.  seek $
2fa0: 66 64 20 5b 65 78 70 72 20 31 30 32 34 2a 28 24  fd [expr 1024*($
2fb0: 69 52 69 67 68 74 43 68 69 6c 64 2d 31 29 5d 0a  iRightChild-1)].
2fc0: 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e    puts -nonewlin
2fd0: 65 20 24 66 64 20 22 5c 78 30 41 22 0a 20 20 63  e $fd "\x0A".  c
2fe0: 6c 6f 73 65 20 24 66 64 0a 7d 20 2d 74 65 73 74  lose $fd.} -test
2ff0: 20 7b 0a 20 20 64 6f 5f 74 65 73 74 20 63 6f 72   {.  do_test cor
3000: 72 75 70 74 32 2d 38 2e 31 20 7b 0a 20 20 20 20  rupt2-8.1 {.    
3010: 63 61 74 63 68 73 71 6c 20 22 20 24 3a 3a 70 72  catchsql " $::pr
3020: 65 73 71 6c 20 53 45 4c 45 43 54 20 2a 20 46 52  esql SELECT * FR
3030: 4f 4d 20 74 31 20 57 48 45 52 45 20 72 6f 77 69  OM t1 WHERE rowi
3040: 64 3d 31 30 30 30 20 22 0a 20 20 7d 20 7b 31 20  d=1000 ".  } {1 
3050: 7b 64 61 74 61 62 61 73 65 20 64 69 73 6b 20 69  {database disk i
3060: 6d 61 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65  mage is malforme
3070: 64 7d 7d 0a 7d 0a 0a 63 6f 72 72 75 70 74 69 6f  d}}.}..corruptio
3080: 6e 5f 74 65 73 74 20 2d 73 71 6c 70 72 65 70 20  n_test -sqlprep 
3090: 7b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  {.  CREATE TABLE
30a0: 20 74 31 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   t1(a, b, c); CR
30b0: 45 41 54 45 20 54 41 42 4c 45 20 74 38 28 61 2c  EATE TABLE t8(a,
30c0: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
30d0: 41 42 4c 45 20 74 45 28 61 2c 20 62 2c 20 63 29  ABLE tE(a, b, c)
30e0: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
30f0: 20 74 32 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   t2(a, b, c); CR
3100: 45 41 54 45 20 54 41 42 4c 45 20 74 39 28 61 2c  EATE TABLE t9(a,
3110: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3120: 41 42 4c 45 20 74 46 28 61 2c 20 62 2c 20 63 29  ABLE tF(a, b, c)
3130: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3140: 20 74 33 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   t3(a, b, c); CR
3150: 45 41 54 45 20 54 41 42 4c 45 20 74 41 28 61 2c  EATE TABLE tA(a,
3160: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3170: 41 42 4c 45 20 74 47 28 61 2c 20 62 2c 20 63 29  ABLE tG(a, b, c)
3180: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3190: 20 74 34 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   t4(a, b, c); CR
31a0: 45 41 54 45 20 54 41 42 4c 45 20 74 42 28 61 2c  EATE TABLE tB(a,
31b0: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
31c0: 41 42 4c 45 20 74 48 28 61 2c 20 62 2c 20 63 29  ABLE tH(a, b, c)
31d0: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
31e0: 20 74 35 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   t5(a, b, c); CR
31f0: 45 41 54 45 20 54 41 42 4c 45 20 74 43 28 61 2c  EATE TABLE tC(a,
3200: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3210: 41 42 4c 45 20 74 49 28 61 2c 20 62 2c 20 63 29  ABLE tI(a, b, c)
3220: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3230: 20 74 36 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   t6(a, b, c); CR
3240: 45 41 54 45 20 54 41 42 4c 45 20 74 44 28 61 2c  EATE TABLE tD(a,
3250: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3260: 41 42 4c 45 20 74 4a 28 61 2c 20 62 2c 20 63 29  ABLE tJ(a, b, c)
3270: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3280: 20 78 31 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   x1(a, b, c); CR
3290: 45 41 54 45 20 54 41 42 4c 45 20 78 38 28 61 2c  EATE TABLE x8(a,
32a0: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
32b0: 41 42 4c 45 20 78 45 28 61 2c 20 62 2c 20 63 29  ABLE xE(a, b, c)
32c0: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
32d0: 20 78 32 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   x2(a, b, c); CR
32e0: 45 41 54 45 20 54 41 42 4c 45 20 78 39 28 61 2c  EATE TABLE x9(a,
32f0: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3300: 41 42 4c 45 20 78 46 28 61 2c 20 62 2c 20 63 29  ABLE xF(a, b, c)
3310: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3320: 20 78 33 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   x3(a, b, c); CR
3330: 45 41 54 45 20 54 41 42 4c 45 20 78 41 28 61 2c  EATE TABLE xA(a,
3340: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3350: 41 42 4c 45 20 78 47 28 61 2c 20 62 2c 20 63 29  ABLE xG(a, b, c)
3360: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3370: 20 78 34 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   x4(a, b, c); CR
3380: 45 41 54 45 20 54 41 42 4c 45 20 78 42 28 61 2c  EATE TABLE xB(a,
3390: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
33a0: 41 42 4c 45 20 78 48 28 61 2c 20 62 2c 20 63 29  ABLE xH(a, b, c)
33b0: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
33c0: 20 78 35 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   x5(a, b, c); CR
33d0: 45 41 54 45 20 54 41 42 4c 45 20 78 43 28 61 2c  EATE TABLE xC(a,
33e0: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
33f0: 41 42 4c 45 20 78 49 28 61 2c 20 62 2c 20 63 29  ABLE xI(a, b, c)
3400: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3410: 20 78 36 28 61 2c 20 62 2c 20 63 29 3b 20 43 52   x6(a, b, c); CR
3420: 45 41 54 45 20 54 41 42 4c 45 20 78 44 28 61 2c  EATE TABLE xD(a,
3430: 20 62 2c 20 63 29 3b 20 43 52 45 41 54 45 20 54   b, c); CREATE T
3440: 41 42 4c 45 20 78 4a 28 61 2c 20 62 2c 20 63 29  ABLE xJ(a, b, c)
3450: 3b 0a 7d 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20  ;.} -corrupt {. 
3460: 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 63 6f   set fd [open co
3470: 72 72 75 70 74 2e 64 62 20 72 2b 5d 0a 20 20 66  rrupt.db r+].  f
3480: 63 6f 6e 66 69 67 75 72 65 20 24 66 64 20 2d 74  configure $fd -t
3490: 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72  ranslation binar
34a0: 79 20 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61  y -encoding bina
34b0: 72 79 0a 20 20 73 65 65 6b 20 24 66 64 20 31 30  ry.  seek $fd 10
34c0: 38 0a 20 20 73 65 74 20 7a 52 69 67 68 74 43 68  8.  set zRightCh
34d0: 69 6c 64 20 5b 72 65 61 64 20 24 66 64 20 34 5d  ild [read $fd 4]
34e0: 0a 20 20 62 69 6e 61 72 79 20 73 63 61 6e 20 24  .  binary scan $
34f0: 7a 52 69 67 68 74 43 68 69 6c 64 20 49 20 69 52  zRightChild I iR
3500: 69 67 68 74 43 68 69 6c 64 0a 20 20 73 65 65 6b  ightChild.  seek
3510: 20 24 66 64 20 5b 65 78 70 72 20 31 30 32 34 2a   $fd [expr 1024*
3520: 28 24 69 52 69 67 68 74 43 68 69 6c 64 2d 31 29  ($iRightChild-1)
3530: 2b 33 5d 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65  +3].  puts -none
3540: 77 6c 69 6e 65 20 24 66 64 20 22 5c 78 30 30 5c  wline $fd "\x00\
3550: 78 30 30 22 0a 20 20 63 6c 6f 73 65 20 24 66 64  x00".  close $fd
3560: 0a 7d 20 2d 74 65 73 74 20 7b 0a 20 20 64 6f 5f  .} -test {.  do_
3570: 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d 39 2e  test corrupt2-9.
3580: 31 20 7b 0a 20 20 20 20 63 61 74 63 68 73 71 6c  1 {.    catchsql
3590: 20 22 20 24 3a 3a 70 72 65 73 71 6c 20 53 45 4c   " $::presql SEL
35a0: 45 43 54 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c  ECT sql FROM sql
35b0: 69 74 65 5f 6d 61 73 74 65 72 20 22 0a 20 20 7d  ite_master ".  }
35c0: 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20 64 69   {1 {database di
35d0: 73 6b 20 69 6d 61 67 65 20 69 73 20 6d 61 6c 66  sk image is malf
35e0: 6f 72 6d 65 64 7d 7d 0a 7d 0a 0a 63 6f 72 72 75  ormed}}.}..corru
35f0: 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c 70  ption_test -sqlp
3600: 72 65 70 20 7b 0a 20 20 43 52 45 41 54 45 20 54  rep {.  CREATE T
3610: 41 42 4c 45 20 74 31 28 61 2c 20 62 2c 20 63 29  ABLE t1(a, b, c)
3620: 3b 0a 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  ;.  CREATE TABLE
3630: 20 74 32 28 61 2c 20 62 2c 20 63 29 3b 0a 20 20   t2(a, b, c);.  
3640: 50 52 41 47 4d 41 20 77 72 69 74 61 62 6c 65 5f  PRAGMA writable_
3650: 73 63 68 65 6d 61 20 3d 20 31 3b 0a 20 20 55 50  schema = 1;.  UP
3660: 44 41 54 45 20 73 71 6c 69 74 65 5f 6d 61 73 74  DATE sqlite_mast
3670: 65 72 20 53 45 54 20 72 6f 6f 74 70 61 67 65 20  er SET rootpage 
3680: 3d 20 4e 55 4c 4c 20 57 48 45 52 45 20 6e 61 6d  = NULL WHERE nam
3690: 65 20 3d 20 27 74 32 27 3b 0a 7d 20 2d 74 65 73  e = 't2';.} -tes
36a0: 74 20 7b 0a 20 20 64 6f 5f 74 65 73 74 20 63 6f  t {.  do_test co
36b0: 72 72 75 70 74 32 2d 31 30 2e 31 20 7b 0a 20 20  rrupt2-10.1 {.  
36c0: 20 20 63 61 74 63 68 73 71 6c 20 22 20 24 3a 3a    catchsql " $::
36d0: 70 72 65 73 71 6c 20 53 45 4c 45 43 54 20 2a 20  presql SELECT * 
36e0: 46 52 4f 4d 20 74 32 20 22 0a 20 20 7d 20 7b 31  FROM t2 ".  } {1
36f0: 20 7b 6d 61 6c 66 6f 72 6d 65 64 20 64 61 74 61   {malformed data
3700: 62 61 73 65 20 73 63 68 65 6d 61 20 28 74 32 29  base schema (t2)
3710: 7d 7d 0a 20 20 64 6f 5f 74 65 73 74 20 63 6f 72  }}.  do_test cor
3720: 72 75 70 74 32 2d 31 30 2e 32 20 7b 0a 20 20 20  rupt2-10.2 {.   
3730: 20 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65   sqlite3_errcode
3740: 20 64 62 0a 20 20 7d 20 7b 53 51 4c 49 54 45 5f   db.  } {SQLITE_
3750: 43 4f 52 52 55 50 54 7d 0a 7d 0a 0a 63 6f 72 72  CORRUPT}.}..corr
3760: 75 70 74 69 6f 6e 5f 74 65 73 74 20 2d 73 71 6c  uption_test -sql
3770: 70 72 65 70 20 7b 0a 20 20 50 52 41 47 4d 41 20  prep {.  PRAGMA 
3780: 61 75 74 6f 5f 76 61 63 75 75 6d 20 3d 20 69 6e  auto_vacuum = in
3790: 63 72 65 6d 65 6e 74 61 6c 3b 0a 20 20 43 52 45  cremental;.  CRE
37a0: 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49  ATE TABLE t1(a I
37b0: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b  NTEGER PRIMARY K
37c0: 45 59 2c 20 62 29 3b 0a 20 20 43 52 45 41 54 45  EY, b);.  CREATE
37d0: 20 54 41 42 4c 45 20 74 32 28 61 20 49 4e 54 45   TABLE t2(a INTE
37e0: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c  GER PRIMARY KEY,
37f0: 20 62 29 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e   b);.  INSERT IN
3800: 54 4f 20 74 31 20 56 41 4c 55 45 53 28 31 2c 20  TO t1 VALUES(1, 
3810: 72 61 6e 64 73 74 72 28 31 30 30 2c 31 30 30 29  randstr(100,100)
3820: 29 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  );.  INSERT INTO
3830: 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c   t1 SELECT NULL,
3840: 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31 30 30   randstr(100,100
3850: 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53  ) FROM t1;.  INS
3860: 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45  ERT INTO t1 SELE
3870: 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72  CT NULL, randstr
3880: 28 31 30 30 2c 31 30 30 29 20 46 52 4f 4d 20 74  (100,100) FROM t
3890: 31 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  1;.  INSERT INTO
38a0: 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c   t1 SELECT NULL,
38b0: 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31 30 30   randstr(100,100
38c0: 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53  ) FROM t1;.  INS
38d0: 45 52 54 20 49 4e 54 4f 20 74 31 20 53 45 4c 45  ERT INTO t1 SELE
38e0: 43 54 20 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72  CT NULL, randstr
38f0: 28 31 30 30 2c 31 30 30 29 20 46 52 4f 4d 20 74  (100,100) FROM t
3900: 31 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  1;.  INSERT INTO
3910: 20 74 31 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c   t1 SELECT NULL,
3920: 20 72 61 6e 64 73 74 72 28 31 30 30 2c 31 30 30   randstr(100,100
3930: 29 20 46 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53  ) FROM t1;.  INS
3940: 45 52 54 20 49 4e 54 4f 20 74 32 20 53 45 4c 45  ERT INTO t2 SELE
3950: 43 54 20 2a 20 46 52 4f 4d 20 74 31 3b 0a 20 20  CT * FROM t1;.  
3960: 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31 3b 0a  DELETE FROM t1;.
3970: 7d 20 2d 63 6f 72 72 75 70 74 20 7b 0a 20 20 73  } -corrupt {.  s
3980: 65 74 20 6f 66 66 73 65 74 20 5b 65 78 70 72 20  et offset [expr 
3990: 5b 66 69 6c 65 20 73 69 7a 65 20 63 6f 72 72 75  [file size corru
39a0: 70 74 2e 64 62 5d 20 2d 20 31 30 32 34 5d 0a 20  pt.db] - 1024]. 
39b0: 20 68 65 78 69 6f 5f 77 72 69 74 65 20 63 6f 72   hexio_write cor
39c0: 72 75 70 74 2e 64 62 20 24 6f 66 66 73 65 74 20  rupt.db $offset 
39d0: 46 46 20 0a 20 20 68 65 78 69 6f 5f 77 72 69 74  FF .  hexio_writ
39e0: 65 20 63 6f 72 72 75 70 74 2e 64 62 20 32 34 20  e corrupt.db 24 
39f0: 20 20 31 32 33 34 35 36 37 38 0a 7d 20 2d 74 65    12345678.} -te
3a00: 73 74 20 7b 0a 20 20 64 6f 5f 74 65 73 74 20 63  st {.  do_test c
3a10: 6f 72 72 75 70 74 32 2d 31 31 2e 31 20 7b 0a 20  orrupt2-11.1 {. 
3a20: 20 20 20 63 61 74 63 68 73 71 6c 20 22 20 24 3a     catchsql " $:
3a30: 3a 70 72 65 73 71 6c 20 50 52 41 47 4d 41 20 69  :presql PRAGMA i
3a40: 6e 63 72 65 6d 65 6e 74 61 6c 5f 76 61 63 75 75  ncremental_vacuu
3a50: 6d 20 22 0a 20 20 7d 20 7b 31 20 7b 64 61 74 61  m ".  } {1 {data
3a60: 62 61 73 65 20 64 69 73 6b 20 69 6d 61 67 65 20  base disk image 
3a70: 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d 7d 0a 7d  is malformed}}.}
3a80: 0a 63 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74  .corruption_test
3a90: 20 2d 73 71 6c 70 72 65 70 20 7b 0a 20 20 50 52   -sqlprep {.  PR
3aa0: 41 47 4d 41 20 61 75 74 6f 5f 76 61 63 75 75 6d  AGMA auto_vacuum
3ab0: 20 3d 20 69 6e 63 72 65 6d 65 6e 74 61 6c 3b 0a   = incremental;.
3ac0: 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74    CREATE TABLE t
3ad0: 31 28 61 20 49 4e 54 45 47 45 52 20 50 52 49 4d  1(a INTEGER PRIM
3ae0: 41 52 59 20 4b 45 59 2c 20 62 29 3b 0a 20 20 43  ARY KEY, b);.  C
3af0: 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 61  REATE TABLE t2(a
3b00: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59   INTEGER PRIMARY
3b10: 20 4b 45 59 2c 20 62 29 3b 0a 20 20 49 4e 53 45   KEY, b);.  INSE
3b20: 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55 45  RT INTO t1 VALUE
3b30: 53 28 31 2c 20 72 61 6e 64 73 74 72 28 31 30 30  S(1, randstr(100
3b40: 2c 31 30 30 29 29 3b 0a 20 20 49 4e 53 45 52 54  ,100));.  INSERT
3b50: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
3b60: 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72 28 31 30  NULL, randstr(10
3b70: 30 2c 31 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a  0,100) FROM t1;.
3b80: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3b90: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
3ba0: 6e 64 73 74 72 28 31 30 30 2c 31 30 30 29 20 46  ndstr(100,100) F
3bb0: 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54  ROM t1;.  INSERT
3bc0: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
3bd0: 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72 28 31 30  NULL, randstr(10
3be0: 30 2c 31 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a  0,100) FROM t1;.
3bf0: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3c00: 20 53 45 4c 45 43 54 20 4e 55 4c 4c 2c 20 72 61   SELECT NULL, ra
3c10: 6e 64 73 74 72 28 31 30 30 2c 31 30 30 29 20 46  ndstr(100,100) F
3c20: 52 4f 4d 20 74 31 3b 0a 20 20 49 4e 53 45 52 54  ROM t1;.  INSERT
3c30: 20 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20   INTO t1 SELECT 
3c40: 4e 55 4c 4c 2c 20 72 61 6e 64 73 74 72 28 31 30  NULL, randstr(10
3c50: 30 2c 31 30 30 29 20 46 52 4f 4d 20 74 31 3b 0a  0,100) FROM t1;.
3c60: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 32    INSERT INTO t2
3c70: 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74   SELECT * FROM t
3c80: 31 3b 0a 20 20 44 45 4c 45 54 45 20 46 52 4f 4d  1;.  DELETE FROM
3c90: 20 74 31 3b 0a 7d 20 2d 63 6f 72 72 75 70 74 20   t1;.} -corrupt 
3ca0: 7b 0a 20 20 73 65 74 20 70 67 6e 6f 20 5b 65 78  {.  set pgno [ex
3cb0: 70 72 20 5b 66 69 6c 65 20 73 69 7a 65 20 63 6f  pr [file size co
3cc0: 72 72 75 70 74 2e 64 62 5d 20 2f 20 31 30 32 34  rrupt.db] / 1024
3cd0: 5d 0a 20 20 68 65 78 69 6f 5f 77 72 69 74 65 20  ].  hexio_write 
3ce0: 63 6f 72 72 75 70 74 2e 64 62 20 5b 65 78 70 72  corrupt.db [expr
3cf0: 20 31 30 32 34 2b 35 2a 28 24 70 67 6e 6f 2d 33   1024+5*($pgno-3
3d00: 29 5d 20 30 33 20 0a 20 20 68 65 78 69 6f 5f 77  )] 03 .  hexio_w
3d10: 72 69 74 65 20 63 6f 72 72 75 70 74 2e 64 62 20  rite corrupt.db 
3d20: 32 34 20 20 20 31 32 33 34 35 36 37 38 0a 7d 20  24   12345678.} 
3d30: 2d 74 65 73 74 20 7b 0a 20 20 64 6f 5f 74 65 73  -test {.  do_tes
3d40: 74 20 63 6f 72 72 75 70 74 32 2d 31 32 2e 31 20  t corrupt2-12.1 
3d50: 7b 0a 20 20 20 20 63 61 74 63 68 73 71 6c 20 22  {.    catchsql "
3d60: 20 24 3a 3a 70 72 65 73 71 6c 20 50 52 41 47 4d   $::presql PRAGM
3d70: 41 20 69 6e 63 72 65 6d 65 6e 74 61 6c 5f 76 61  A incremental_va
3d80: 63 75 75 6d 20 22 0a 20 20 7d 20 7b 31 20 7b 64  cuum ".  } {1 {d
3d90: 61 74 61 62 61 73 65 20 64 69 73 6b 20 69 6d 61  atabase disk ima
3da0: 67 65 20 69 73 20 6d 61 6c 66 6f 72 6d 65 64 7d  ge is malformed}
3db0: 7d 0a 7d 0a 0a 69 66 63 61 70 61 62 6c 65 20 61  }.}..ifcapable a
3dc0: 75 74 6f 76 61 63 75 75 6d 20 7b 0a 20 20 23 20  utovacuum {.  # 
3dd0: 49 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62  It is not possib
3de0: 6c 65 20 66 6f 72 20 74 68 65 20 6c 61 73 74 20  le for the last 
3df0: 70 61 67 65 20 69 6e 20 61 20 64 61 74 61 62 61  page in a databa
3e00: 73 65 20 66 69 6c 65 20 74 6f 20 62 65 20 74 68  se file to be th
3e10: 65 0a 20 20 23 20 70 65 6e 64 69 6e 67 2d 62 79  e.  # pending-by
3e20: 74 65 20 70 61 67 65 20 28 41 4b 41 20 74 68 65  te page (AKA the
3e30: 20 6c 6f 63 6b 69 6e 67 20 70 61 67 65 29 2e 20   locking page). 
3e40: 54 68 69 73 20 74 65 73 74 20 76 65 72 69 66 69  This test verifi
3e50: 65 73 20 74 68 61 74 20 69 66 0a 20 20 23 20 61  es that if.  # a
3e60: 6e 20 61 74 74 65 6d 70 74 20 69 73 20 6d 61 64  n attempt is mad
3e70: 65 20 74 6f 20 63 6f 6d 6d 69 74 20 61 20 74 72  e to commit a tr
3e80: 61 6e 73 61 63 74 69 6f 6e 20 74 6f 20 73 75 63  ansaction to suc
3e90: 68 20 61 6e 20 61 75 74 6f 2d 76 61 63 75 75 6d  h an auto-vacuum
3ea0: 20 0a 20 20 23 20 64 61 74 61 62 61 73 65 20 53   .  # database S
3eb0: 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 20 69 73  QLITE_CORRUPT is
3ec0: 20 72 65 74 75 72 6e 65 64 2e 0a 20 20 23 0a 20   returned..  #. 
3ed0: 20 63 6f 72 72 75 70 74 69 6f 6e 5f 74 65 73 74   corruption_test
3ee0: 20 2d 74 63 6c 70 72 65 70 20 7b 0a 20 20 20 20   -tclprep {.    
3ef0: 64 62 20 65 76 61 6c 20 7b 20 0a 20 20 20 20 20  db eval { .     
3f00: 20 50 52 41 47 4d 41 20 61 75 74 6f 5f 76 61 63   PRAGMA auto_vac
3f10: 75 75 6d 20 3d 20 66 75 6c 6c 3b 0a 20 20 20 20  uum = full;.    
3f20: 20 20 50 52 41 47 4d 41 20 70 61 67 65 5f 73 69    PRAGMA page_si
3f30: 7a 65 20 3d 20 31 30 32 34 3b 0a 20 20 20 20 20  ze = 1024;.     
3f40: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31   CREATE TABLE t1
3f50: 28 61 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41  (a INTEGER PRIMA
3f60: 52 59 20 4b 45 59 2c 20 62 29 3b 0a 20 20 20 20  RY KEY, b);.    
3f70: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31    INSERT INTO t1
3f80: 20 56 41 4c 55 45 53 28 4e 55 4c 4c 2c 20 72 61   VALUES(NULL, ra
3f90: 6e 64 73 74 72 28 35 30 2c 35 30 29 29 3b 0a 20  ndstr(50,50));. 
3fa0: 20 20 20 7d 0a 20 20 20 20 66 6f 72 20 7b 73 65     }.    for {se
3fb0: 74 20 69 69 20 30 7d 20 7b 24 69 69 20 3c 20 31  t ii 0} {$ii < 1
3fc0: 30 7d 20 7b 69 6e 63 72 20 69 69 7d 20 7b 0a 20  0} {incr ii} {. 
3fd0: 20 20 20 20 20 64 62 20 65 76 61 6c 20 22 20 24       db eval " $
3fe0: 3a 3a 70 72 65 73 71 6c 20 49 4e 53 45 52 54 20  ::presql INSERT 
3ff0: 49 4e 54 4f 20 74 31 20 53 45 4c 45 43 54 20 4e  INTO t1 SELECT N
4000: 55 4c 4c 2c 20 72 61 6e 64 73 74 72 28 35 30 2c  ULL, randstr(50,
4010: 35 30 29 20 46 52 4f 4d 20 74 31 20 22 0a 20 20  50) FROM t1 ".  
4020: 20 20 7d 0a 20 20 7d 20 2d 63 6f 72 72 75 70 74    }.  } -corrupt
4030: 20 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 63   {.    do_test c
4040: 6f 72 72 75 70 74 32 2d 31 33 2e 31 20 7b 0a 20  orrupt2-13.1 {. 
4050: 20 20 20 20 20 66 69 6c 65 20 73 69 7a 65 20 63       file size c
4060: 6f 72 72 75 70 74 2e 64 62 0a 20 20 20 20 7d 20  orrupt.db.    } 
4070: 24 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e  $::sqlite_pendin
4080: 67 5f 62 79 74 65 0a 20 20 20 20 68 65 78 69 6f  g_byte.    hexio
4090: 5f 77 72 69 74 65 20 63 6f 72 72 75 70 74 2e 64  _write corrupt.d
40a0: 62 20 5b 65 78 70 72 20 24 3a 3a 73 71 6c 69 74  b [expr $::sqlit
40b0: 65 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 2b 31  e_pending_byte+1
40c0: 30 32 33 5d 20 30 30 0a 20 20 20 20 68 65 78 69  023] 00.    hexi
40d0: 6f 5f 77 72 69 74 65 20 63 6f 72 72 75 70 74 2e  o_write corrupt.
40e0: 64 62 20 32 38 20 30 30 30 30 30 30 30 30 0a 20  db 28 00000000. 
40f0: 20 7d 20 2d 74 65 73 74 20 7b 0a 20 20 20 20 64   } -test {.    d
4100: 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74 32 2d  o_test corrupt2-
4110: 31 33 2e 32 20 7b 0a 20 20 20 20 20 20 66 69 6c  13.2 {.      fil
4120: 65 20 73 69 7a 65 20 63 6f 72 72 75 70 74 2e 64  e size corrupt.d
4130: 62 0a 20 20 20 20 7d 20 5b 65 78 70 72 20 24 3a  b.    } [expr $:
4140: 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f  :sqlite_pending_
4150: 62 79 74 65 20 2b 20 31 30 32 34 5d 0a 20 20 20  byte + 1024].   
4160: 20 64 6f 5f 74 65 73 74 20 63 6f 72 72 75 70 74   do_test corrupt
4170: 32 2d 31 33 2e 33 20 7b 0a 20 20 20 20 20 20 63  2-13.3 {.      c
4180: 61 74 63 68 73 71 6c 20 7b 20 44 45 4c 45 54 45  atchsql { DELETE
4190: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 72   FROM t1 WHERE r
41a0: 6f 77 69 64 20 3c 20 33 30 3b 20 7d 0a 20 20 20  owid < 30; }.   
41b0: 20 7d 20 7b 31 20 7b 64 61 74 61 62 61 73 65 20   } {1 {database 
41c0: 64 69 73 6b 20 69 6d 61 67 65 20 69 73 20 6d 61  disk image is ma
41d0: 6c 66 6f 72 6d 65 64 7d 7d 0a 20 20 7d 0a 7d 0a  lformed}}.  }.}.
41e0: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
41f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4200: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 54 65  -----------.# Te
4230: 73 74 20 74 68 61 74 20 50 52 41 47 4d 41 20 69  st that PRAGMA i
4240: 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20 64  ntegrity_check d
4250: 65 74 65 63 74 73 20 63 61 73 65 73 20 77 68 65  etects cases whe
4260: 72 65 20 74 68 65 20 66 72 65 65 6c 69 73 74 2d  re the freelist-
4270: 63 6f 75 6e 74 0a 23 20 68 65 61 64 65 72 20 66  count.# header f
4280: 69 65 6c 64 20 69 73 20 73 6d 61 6c 6c 65 72 20  ield is smaller 
4290: 74 68 61 6e 20 74 68 65 20 61 63 74 75 61 6c 20  than the actual 
42a0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
42b0: 6f 6e 20 74 68 65 20 66 72 65 65 6c 69 73 74 2e  on the freelist.
42c0: 0a 23 0a 0a 72 65 73 65 74 5f 64 62 0a 64 6f 5f  .#..reset_db.do_
42d0: 65 78 65 63 73 71 6c 5f 74 65 73 74 20 31 34 2e  execsql_test 14.
42e0: 30 20 7b 0a 20 20 50 52 41 47 4d 41 20 61 75 74  0 {.  PRAGMA aut
42f0: 6f 5f 76 61 63 75 75 6d 20 3d 20 30 3b 0a 20 20  o_vacuum = 0;.  
4300: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28  CREATE TABLE t1(
4310: 78 29 3b 0a 20 20 49 4e 53 45 52 54 20 49 4e 54  x);.  INSERT INT
4320: 4f 20 74 31 20 56 41 4c 55 45 53 28 72 61 6e 64  O t1 VALUES(rand
4330: 6f 6d 62 6c 6f 62 28 33 35 30 30 29 29 3b 0a 20  omblob(3500));. 
4340: 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74 31 3b   DELETE FROM t1;
4350: 0a 7d 0a 0a 64 6f 5f 65 78 65 63 73 71 6c 5f 74  .}..do_execsql_t
4360: 65 73 74 20 31 34 2e 31 20 7b 0a 20 20 50 52 41  est 14.1 {.  PRA
4370: 47 4d 41 20 69 6e 74 65 67 72 69 74 79 5f 63 68  GMA integrity_ch
4380: 65 63 6b 3b 0a 20 20 50 52 41 47 4d 41 20 66 72  eck;.  PRAGMA fr
4390: 65 65 6c 69 73 74 5f 63 6f 75 6e 74 3b 0a 7d 20  eelist_count;.} 
43a0: 7b 6f 6b 20 33 7d 0a 0a 23 20 54 68 65 72 65 20  {ok 3}..# There 
43b0: 61 72 65 20 6e 6f 77 20 33 20 66 72 65 65 20 70  are now 3 free p
43c0: 61 67 65 73 2e 20 4d 6f 64 69 66 79 20 74 68 65  ages. Modify the
43d0: 20 68 65 61 64 65 72 2d 66 69 65 6c 64 20 73 6f   header-field so
43e0: 20 74 68 61 74 20 69 74 20 0a 23 20 28 69 6e 63   that it .# (inc
43f0: 6f 72 72 65 63 74 6c 79 29 20 73 61 79 73 20 74  orrectly) says t
4400: 68 61 74 20 6a 75 73 74 20 32 20 61 72 65 20 66  hat just 2 are f
4410: 72 65 65 2e 0a 64 6f 5f 74 65 73 74 20 31 34 2e  ree..do_test 14.
4420: 32 20 7b 0a 20 20 64 62 20 63 6c 6f 73 65 0a 20  2 {.  db close. 
4430: 20 68 65 78 69 6f 5f 77 72 69 74 65 20 74 65 73   hexio_write tes
4440: 74 2e 64 62 20 33 36 20 5b 68 65 78 69 6f 5f 72  t.db 36 [hexio_r
4450: 65 6e 64 65 72 5f 69 6e 74 33 32 20 32 5d 0a 20  ender_int32 2]. 
4460: 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74   sqlite3 db test
4470: 2e 64 62 0a 20 20 65 78 65 63 73 71 6c 20 7b 20  .db.  execsql { 
4480: 50 52 41 47 4d 41 20 66 72 65 65 6c 69 73 74 5f  PRAGMA freelist_
4490: 63 6f 75 6e 74 20 7d 0a 7d 20 7b 32 7d 0a 0a 64  count }.} {2}..d
44a0: 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 31  o_execsql_test 1
44b0: 34 2e 33 20 7b 0a 20 20 50 52 41 47 4d 41 20 69  4.3 {.  PRAGMA i
44c0: 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 3b 0a  ntegrity_check;.
44d0: 7d 20 7b 7b 2a 2a 2a 20 69 6e 20 64 61 74 61 62  } {{*** in datab
44e0: 61 73 65 20 6d 61 69 6e 20 2a 2a 2a 0a 4d 61 69  ase main ***.Mai
44f0: 6e 20 66 72 65 65 6c 69 73 74 3a 20 66 72 65 65  n freelist: free
4500: 2d 70 61 67 65 20 63 6f 75 6e 74 20 69 6e 20 68  -page count in h
4510: 65 61 64 65 72 20 69 73 20 74 6f 6f 20 73 6d 61  eader is too sma
4520: 6c 6c 7d 7d 0a 0a 23 20 55 73 65 20 32 20 6f 66  ll}}..# Use 2 of
4530: 20 74 68 65 20 66 72 65 65 20 70 61 67 65 73 20   the free pages 
4540: 6f 6e 20 74 68 65 20 66 72 65 65 2d 6c 69 73 74  on the free-list
4550: 2e 0a 23 0a 64 6f 5f 65 78 65 63 73 71 6c 5f 74  ..#.do_execsql_t
4560: 65 73 74 20 31 34 2e 34 20 7b 0a 20 20 49 4e 53  est 14.4 {.  INS
4570: 45 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55  ERT INTO t1 VALU
4580: 45 53 28 72 61 6e 64 6f 6d 62 6c 6f 62 28 32 35  ES(randomblob(25
4590: 30 30 29 29 3b 0a 20 20 50 52 41 47 4d 41 20 66  00));.  PRAGMA f
45a0: 72 65 65 6c 69 73 74 5f 63 6f 75 6e 74 3b 0a 7d  reelist_count;.}
45b0: 20 7b 30 7d 0a 0a 64 6f 5f 65 78 65 63 73 71 6c   {0}..do_execsql
45c0: 5f 74 65 73 74 20 31 34 2e 35 20 7b 0a 20 20 50  _test 14.5 {.  P
45d0: 52 41 47 4d 41 20 69 6e 74 65 67 72 69 74 79 5f  RAGMA integrity_
45e0: 63 68 65 63 6b 3b 0a 7d 20 7b 7b 2a 2a 2a 20 69  check;.} {{*** i
45f0: 6e 20 64 61 74 61 62 61 73 65 20 6d 61 69 6e 20  n database main 
4600: 2a 2a 2a 0a 50 61 67 65 20 33 20 69 73 20 6e 65  ***.Page 3 is ne
4610: 76 65 72 20 75 73 65 64 7d 7d 0a 0a 0a 66 69 6e  ver used}}...fin
4620: 69 73 68 5f 74 65 73 74 0a 0a 66 69 6e 69 73 68  ish_test..finish
4630: 5f 74 65 73 74 0a                                _test.