xref: /sqlite-3.40.0/test/fuzz.test (revision f75232f7)
1
2# 2001 September 15
3#
4# The author disclaims copyright to this source code.  In place of
5# a legal notice, here is a blessing:
6#
7#    May you do good and not evil.
8#    May you find forgiveness for yourself and forgive others.
9#    May you share freely, never taking more than you give.
10#
11#***********************************************************************
12# This file implements regression tests for SQLite library.  The
13# focus of this file is testing the SELECT statement.
14#
15# $Id: fuzz.test,v 1.2 2007/05/10 17:32:48 danielk1977 Exp $
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20proc fuzz {TemplateList} {
21  set n [llength $TemplateList]
22  set i [expr {int(rand()*$n)}]
23  return [subst -novar [lindex $TemplateList $i]]
24}
25
26# Returns a string representing an SQL literal.
27#
28proc Literal {} {
29  set TemplateList {
30    456 0 -456 1 -1
31    2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649
32    'The' 'first' 'experiments' 'in' 'hardware' 'fault' 'injection'
33    zeroblob(1000)
34    NULL
35    56.1 -56.1
36    123456789.1234567899
37  }
38  fuzz $TemplateList
39}
40
41proc UnaryOp {} {
42  set TemplateList {+ - NOT}
43  fuzz $TemplateList
44}
45
46proc BinaryOp {} {
47  set TemplateList {+ - % * / AND OR LIKE GLOB}
48  fuzz $TemplateList
49}
50
51set ::ExprDepth 0
52proc Expr {} {
53  incr ::ExprDepth
54
55  set TemplateList {[Literal]}
56  if {$::ExprDepth < 100} {
57    lappend TemplateList \
58      {[Expr] [BinaryOp] [Expr]}   \
59      {[UnaryOp] [Expr]}
60  }
61  if {$::SelectDepth < 10} {
62    lappend TemplateList {([Select 1])}
63  }
64  set res [fuzz $TemplateList]
65  incr ::ExprDepth -1
66  return $res
67}
68
69set ::TableList [list]
70proc Table {} {
71  set TemplateList [concat sqlite_master $::TableList]
72  fuzz $TemplateList
73}
74
75set ::SelectDepth 0
76proc Select {{isExpr 0}} {
77  incr ::SelectDepth
78  set TemplateList {
79      {SELECT [Expr]}
80  }
81  if {$::SelectDepth < 5} {
82    lappend TemplateList \
83        {SELECT [Expr] FROM ([Select])}                \
84        {SELECT [Expr] FROM [Table]}
85
86    if {0 == $isExpr} {
87      lappend TemplateList                                         \
88          {SELECT [Expr], [Expr] FROM ([Select]) ORDER BY [Expr]}  \
89          {SELECT * FROM ([Select]) ORDER BY [Expr]}               \
90    }
91  }
92  set res [fuzz $TemplateList]
93  incr ::SelectDepth -1
94  set res
95}
96
97########################################################################
98
99#----------------------------------------------------------------
100# These tests caused errors that were first caught by the tests
101# in this file. They are still here.
102do_test fuzz-1.1 {
103  execsql {
104    SELECT 'abc' LIKE X'ABCD';
105  }
106} {0}
107do_test fuzz-1.2 {
108  execsql {
109    SELECT 'abc' LIKE zeroblob(10);
110  }
111} {0}
112do_test fuzz-1.3 {
113  execsql {
114    SELECT zeroblob(10) LIKE 'abc';
115  }
116} {0}
117do_test fuzz-1.4 {
118  execsql {
119    SELECT (- -21) % NOT (456 LIKE zeroblob(10));
120  }
121} {0}
122do_test fuzz-1.5 {
123  execsql {
124    SELECT (SELECT (
125        SELECT (SELECT -2147483648) FROM (SELECT 1) ORDER BY 1
126    ))
127  }
128} {-2147483648}
129do_test fuzz-1.6 {
130  execsql {
131    SELECT 'abc', zeroblob(1) FROM (SELECT 1) ORDER BY 1
132  }
133} [execsql {SELECT 'abc', zeroblob(1)}]
134
135do_test fuzz-1.7 {
136  execsql {
137SELECT + (SELECT (SELECT 'fault' / + -2147483648 % - 123456789.1234567899 * (SELECT 'experiments' OR NOT 'first' / 'hardware' FROM (SELECT 2147483647, + (SELECT 'injection') FROM (SELECT 2147483649) ORDER BY + NULL AND (SELECT 'hardware') GLOB 2147483648))) FROM (SELECT * FROM (SELECT (SELECT (SELECT + (SELECT 456 * -2147483648)) LIKE (SELECT (SELECT (SELECT 'fault') - -56.1)) AND -2147483648) FROM (SELECT * FROM (SELECT 2147483648) ORDER BY (SELECT 56.1))) ORDER BY zeroblob(1))
138  }
139} {}
140
141#----------------------------------------------------------------
142# Test some fuzzily generated expressions.
143#
144for {set ii 0} {$ii < 2000} {incr ii} {
145  do_test fuzz-2.1.$ii {
146    set ::expr [Expr]
147    set rc [catch {execsql "SELECT $::expr"} msg]
148    set e [expr {
149      $rc == 0 ||
150      $msg eq "parser stack overflow" ||
151      0 == [string first "ORDER BY column number" $msg]
152    }]
153    if {$e == 0} {
154      puts ""
155      puts "SELECT $::expr"
156      puts $msg
157    }
158    set e
159  } {1}
160}
161
162do_test fuzz-3.1 {
163  execsql {
164    CREATE TABLE abc(a, b, c);
165    CREATE TABLE def(d, e, f);
166    CREATE TABLE ghi(g, h, i);
167  }
168} {}
169set ::TableList [list abc def ghi]
170
171#----------------------------------------------------------------
172# Test some fuzzily generated SELECT statements.
173#
174for {set ii 0} {$ii < 2000} {incr ii} {
175  do_test fuzz-2.2.$ii {
176    set ::select [Select]
177    set rc [catch {execsql $::select} msg]
178    set e [expr {$rc == 0 || $msg eq "parser stack overflow"}]
179    set e [expr {
180      $rc == 0 ||
181      $msg eq "parser stack overflow" ||
182      0 == [string first "ORDER BY column number" $msg]
183    }]
184    if {$e == 0} {
185      puts ""
186      puts $::select
187      puts $msg
188    }
189    set e
190  } {1}
191}
192
193finish_test
194
195