CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
fuzz3.test176 linesDownload Raw Back to test
1# 2007 May 102#3# The author disclaims copyright to this source code.  In place of4# 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.  The focus12# of this file is checking the libraries response to subtly corrupting13# the database file by changing the values of pseudo-randomly selected14# bytes.15#16# $Id: fuzz3.test,v 1.3 2009/01/05 17:19:03 drh Exp $17 18set testdir [file dirname $argv0]19source $testdir/tester.tcl20 21# These tests deal with corrupt database files22#23database_may_be_corrupt24test_set_config_pagecache 0 025 26 27expr srand(123)28 29proc rstring {n} {30  set str s31  while {[string length $str] < $n} {32    append str [expr rand()]33  }34  return [string range $str 0 $n]35}36 37# Return a randomly generated SQL literal.38#39proc rvalue {} {40  switch -- [expr int(rand()*5)] {41    0 { # SQL NULL value.42      return NULL 43    }44    1 { # Integer value.45      return [expr int(rand()*1024)] 46    }47    2 { # Real value.48      return [expr rand()] 49    }50    3 { # String value.51      set n [expr int(rand()*2500)]52      return "'[rstring $n]'"53    }54    4 { # Blob value.55      set n [expr int(rand()*2500)]56      return "CAST('[rstring $n]' AS BLOB)"57    }58  }59}60 61proc db_checksum {} {62  set    cksum [execsql { SELECT md5sum(a, b, c) FROM t1 }]63  append cksum [execsql { SELECT md5sum(d, e, f) FROM t2 }]64  set cksum65}66 67# Modify a single byte in the file 'test.db' using tcl IO commands. The68# argument value, which must be an integer, determines both the offset of69# the byte that is modified, and the value that it is set to. The lower70# 8 bits of iMod determine the new byte value. The offset of the byte71# modified is the value of ($iMod >> 8).72#73# The return value is the iMod value required to restore the file74# to its original state. The command:75#76#   modify_database [modify_database $x]77#78# leaves the file in the same state as it was in at the start of the79# command (assuming that the file is at least ($x>>8) bytes in size).80#81proc modify_database {iMod} {82  set blob [binary format c [expr {$iMod&0xFF}]]83  set offset [expr {$iMod>>8}]84 85  set fd [open test.db r+]86  fconfigure $fd -translation binary87  seek $fd $offset88  set old_blob [read $fd 1]89  seek $fd $offset90  puts -nonewline $fd $blob91  close $fd92 93  binary scan $old_blob c iOld94  return [expr {($offset<<8) + ($iOld&0xFF)}]95}96 97proc purge_pcache {} {98  ifcapable !memorymanage {99    db close100    sqlite3 db test.db101  } else {102    sqlite3_release_memory 10000000103  }104  if {[lindex [pcache_stats] 1] != 0} {105    error "purge_pcache failed: [pcache_stats]"106  }107}108 109# This block creates a database to work with. 110#111do_test fuzz3-1 {112  execsql {113    BEGIN;114    CREATE TABLE t1(a, b, c);115    CREATE TABLE t2(d, e, f);116    CREATE INDEX i1 ON t1(a, b, c);117    CREATE INDEX i2 ON t2(d, e, f);118  }119  for {set i 0} {$i < 50} {incr i} {120    execsql "INSERT INTO t1 VALUES([rvalue], [rvalue], [rvalue])"121    execsql "INSERT INTO t2 VALUES([rvalue], [rvalue], [rvalue])"122  }123  execsql COMMIT124} {}125 126set ::cksum [db_checksum]127do_test fuzz3-2 {128  db_checksum129} $::cksum130 131for {set ii 0} {$ii < 5000} {incr ii} {132  purge_pcache133 134  # Randomly modify a single byte of the database file somewhere within135  # the first 100KB of the file.136  set iNew [expr int(rand()*5*1024*256)]137  set iOld [modify_database $iNew]138 139  set iTest 0140  foreach sql {141    {SELECT * FROM t2 ORDER BY d}      142    {SELECT * FROM t1}                 143    {SELECT * FROM t2}                 144    {SELECT * FROM t1 ORDER BY a}      145    {SELECT * FROM t1 WHERE a = (SELECT a FROM t1 WHERE rowid=25)} 146    {SELECT * FROM t2 WHERE d = (SELECT d FROM t2 WHERE rowid=1)}  147    {SELECT * FROM t2 WHERE d = (SELECT d FROM t2 WHERE rowid=50)} 148    {PRAGMA integrity_check}           149  } {150    do_test fuzz3-$ii.$iNew.[incr iTest] {151      foreach {rc msg} [catchsql $sql] {}152      if {$rc == 0 153       || $msg eq "database or disk is full"154       || $msg eq "database disk image is malformed"155       || $msg eq "file is not a database"156       || [string match "malformed database schema*" $msg]157      } {158        set msg ok159      }160      set msg161    } {ok}162  }163 164  # Restore the original database file content. Test that the correct 165  # checksum is now returned.166  #167  purge_pcache168  modify_database $iOld169  do_test fuzz3-$ii.$iNew.[incr iTest] {170    db_checksum171  } $::cksum172}173 174test_restore_config_pagecache175finish_test176