corruptB.test 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. # 2008 Sep 10
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library.
  12. #
  13. # This file implements tests to make sure SQLite does not crash or
  14. # segfault if it sees a corrupt database file. It specifically focuses
  15. # on loops in the B-Tree structure. A loop is formed in a B-Tree structure
  16. # when there exists a page that is both an a descendent or ancestor of
  17. # itself.
  18. #
  19. # Also test that an SQLITE_CORRUPT error is returned if a B-Tree page
  20. # contains a (corrupt) reference to a page greater than the configured
  21. # maximum page number.
  22. #
  23. # $Id: corruptB.test,v 1.4 2009/07/21 19:25:24 danielk1977 Exp $
  24. set testdir [file dirname $argv0]
  25. source $testdir/tester.tcl
  26. # Do not use a codec for tests in this file, as the database file is
  27. # manipulated directly using tcl scripts (using the [hexio_write] command).
  28. #
  29. do_not_use_codec
  30. do_test corruptB-1.1 {
  31. execsql {
  32. PRAGMA auto_vacuum = 1;
  33. CREATE TABLE t1(x);
  34. INSERT INTO t1 VALUES(randomblob(200));
  35. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  36. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  37. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  38. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  39. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  40. }
  41. expr {[file size test.db] > (1024*9)}
  42. } {1}
  43. integrity_check corruptB-1.2
  44. forcecopy test.db bak.db
  45. # Set the right-child of a B-Tree rootpage to refer to the root-page itself.
  46. #
  47. do_test corruptB-1.3.1 {
  48. set ::root [execsql {SELECT rootpage FROM sqlite_master}]
  49. set ::offset [expr {($::root-1)*1024}]
  50. hexio_write test.db [expr $offset+8] [hexio_render_int32 $::root]
  51. } {4}
  52. do_test corruptB-1.3.2 {
  53. sqlite3 db test.db
  54. catchsql { SELECT * FROM t1 }
  55. } {1 {database disk image is malformed}}
  56. # Set the left-child of a cell in a B-Tree rootpage to refer to the
  57. # root-page itself.
  58. #
  59. do_test corruptB-1.4.1 {
  60. db close
  61. forcecopy bak.db test.db
  62. set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]]
  63. hexio_write test.db [expr $offset+$cell_offset] [hexio_render_int32 $::root]
  64. } {4}
  65. do_test corruptB-1.4.2 {
  66. sqlite3 db test.db
  67. catchsql { SELECT * FROM t1 }
  68. } {1 {database disk image is malformed}}
  69. # Now grow the table B-Tree so that it is more than 2 levels high.
  70. #
  71. do_test corruptB-1.5.1 {
  72. db close
  73. forcecopy bak.db test.db
  74. sqlite3 db test.db
  75. execsql {
  76. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  77. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  78. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  79. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  80. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  81. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  82. INSERT INTO t1 SELECT randomblob(200) FROM t1;
  83. }
  84. } {}
  85. forcecopy test.db bak.db
  86. # Set the right-child pointer of the right-child of the root page to point
  87. # back to the root page.
  88. #
  89. do_test corruptB-1.6.1 {
  90. db close
  91. set iRightChild [hexio_get_int [hexio_read test.db [expr $offset+8] 4]]
  92. set c_offset [expr ($iRightChild-1)*1024]
  93. hexio_write test.db [expr $c_offset+8] [hexio_render_int32 $::root]
  94. } {4}
  95. do_test corruptB-1.6.2 {
  96. sqlite3 db test.db
  97. catchsql { SELECT * FROM t1 }
  98. } {1 {database disk image is malformed}}
  99. # Set the left-child pointer of a cell of the right-child of the root page to
  100. # point back to the root page.
  101. #
  102. do_test corruptB-1.7.1 {
  103. db close
  104. forcecopy bak.db test.db
  105. set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]]
  106. hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root]
  107. } {4}
  108. do_test corruptB-1.7.2 {
  109. sqlite3 db test.db
  110. catchsql { SELECT * FROM t1 }
  111. } {1 {database disk image is malformed}}
  112. do_test corruptB-1.8.1 {
  113. db close
  114. set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]]
  115. set iLeftChild [
  116. hexio_get_int [hexio_read test.db [expr $offset+$cell_offset] 4]
  117. ]
  118. set c_offset [expr ($iLeftChild-1)*1024]
  119. hexio_write test.db [expr $c_offset+8] [hexio_render_int32 $::root]
  120. } {4}
  121. do_test corruptB-1.8.2 {
  122. sqlite3 db test.db
  123. catchsql { SELECT * FROM t1 }
  124. } {1 {database disk image is malformed}}
  125. # Set the left-child pointer of a cell of the right-child of the root page to
  126. # point back to the root page.
  127. #
  128. do_test corruptB-1.9.1 {
  129. db close
  130. forcecopy bak.db test.db
  131. set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]]
  132. hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root]
  133. } {4}
  134. do_test corruptB-1.9.2 {
  135. sqlite3 db test.db
  136. catchsql { SELECT * FROM t1 }
  137. } {1 {database disk image is malformed}}
  138. #---------------------------------------------------------------------------
  139. do_test corruptB-2.1.1 {
  140. db close
  141. forcecopy bak.db test.db
  142. hexio_write test.db [expr $offset+8] [hexio_render_int32 0x6FFFFFFF]
  143. } {4}
  144. do_test corruptB-2.1.2 {
  145. sqlite3 db test.db
  146. catchsql { SELECT * FROM t1 }
  147. } {1 {database disk image is malformed}}
  148. #---------------------------------------------------------------------------
  149. # Corrupt the header-size field of a database record.
  150. #
  151. do_test corruptB-3.1.1 {
  152. db close
  153. forcecopy bak.db test.db
  154. sqlite3 db test.db
  155. set v [string repeat abcdefghij 200]
  156. execsql {
  157. CREATE TABLE t2(a);
  158. INSERT INTO t2 VALUES($v);
  159. }
  160. set t2_root [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't2'}]
  161. set iPage [expr ($t2_root-1)*1024]
  162. set iCellarray [expr $iPage + 8]
  163. set iRecord [hexio_get_int [hexio_read test.db $iCellarray 2]]
  164. db close
  165. hexio_write test.db [expr $iPage+$iRecord+3] FF00
  166. } {2}
  167. do_test corruptB-3.1.2 {
  168. sqlite3 db test.db
  169. catchsql { SELECT * FROM t2 }
  170. } {1 {database disk image is malformed}}
  171. finish_test