blob: c92d037913d8df86796fc4a2a4f06d4065fd7fcf [file] [log] [blame]
drhdb83f822007-05-11 00:20:08 +00001# 2007 May 10
danielk1977def0fec2007-05-10 15:37:52 +00002#
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. The
drhdb83f822007-05-11 00:20:08 +000012# focus of this file is generating semi-random strings of SQL
13# (a.k.a. "fuzz") and sending it into the parser to try to generate
14# errors.
danielk1977def0fec2007-05-10 15:37:52 +000015#
drhdb83f822007-05-11 00:20:08 +000016# $Id: fuzz.test,v 1.4 2007/05/11 00:20:08 drh Exp $
danielk1977def0fec2007-05-10 15:37:52 +000017
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
21proc fuzz {TemplateList} {
22 set n [llength $TemplateList]
23 set i [expr {int(rand()*$n)}]
24 return [subst -novar [lindex $TemplateList $i]]
25}
26
danielk1977f75232f2007-05-10 17:32:48 +000027# Returns a string representing an SQL literal.
28#
29proc Literal {} {
danielk1977def0fec2007-05-10 15:37:52 +000030 set TemplateList {
31 456 0 -456 1 -1
32 2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649
33 'The' 'first' 'experiments' 'in' 'hardware' 'fault' 'injection'
34 zeroblob(1000)
35 NULL
36 56.1 -56.1
37 123456789.1234567899
38 }
39 fuzz $TemplateList
40}
41
42proc UnaryOp {} {
43 set TemplateList {+ - NOT}
44 fuzz $TemplateList
45}
46
47proc BinaryOp {} {
48 set TemplateList {+ - % * / AND OR LIKE GLOB}
49 fuzz $TemplateList
50}
51
52set ::ExprDepth 0
53proc Expr {} {
54 incr ::ExprDepth
55
danielk1977f75232f2007-05-10 17:32:48 +000056 set TemplateList {[Literal]}
danielk1977def0fec2007-05-10 15:37:52 +000057 if {$::ExprDepth < 100} {
58 lappend TemplateList \
59 {[Expr] [BinaryOp] [Expr]} \
danielk1977f75232f2007-05-10 17:32:48 +000060 {[UnaryOp] [Expr]}
danielk1977def0fec2007-05-10 15:37:52 +000061 }
62 if {$::SelectDepth < 10} {
danielk1977f75232f2007-05-10 17:32:48 +000063 lappend TemplateList {([Select 1])}
danielk1977def0fec2007-05-10 15:37:52 +000064 }
65 set res [fuzz $TemplateList]
66 incr ::ExprDepth -1
67 return $res
68}
69
danielk1977f75232f2007-05-10 17:32:48 +000070set ::TableList [list]
71proc Table {} {
72 set TemplateList [concat sqlite_master $::TableList]
73 fuzz $TemplateList
74}
75
danielk1977def0fec2007-05-10 15:37:52 +000076set ::SelectDepth 0
danielk1977f75232f2007-05-10 17:32:48 +000077proc Select {{isExpr 0}} {
danielk1977def0fec2007-05-10 15:37:52 +000078 incr ::SelectDepth
79 set TemplateList {
80 {SELECT [Expr]}
81 }
danielk1977f75232f2007-05-10 17:32:48 +000082 if {$::SelectDepth < 5} {
83 lappend TemplateList \
84 {SELECT [Expr] FROM ([Select])} \
85 {SELECT [Expr] FROM [Table]}
86
87 if {0 == $isExpr} {
88 lappend TemplateList \
89 {SELECT [Expr], [Expr] FROM ([Select]) ORDER BY [Expr]} \
90 {SELECT * FROM ([Select]) ORDER BY [Expr]} \
91 }
92 }
danielk1977def0fec2007-05-10 15:37:52 +000093 set res [fuzz $TemplateList]
94 incr ::SelectDepth -1
95 set res
96}
97
danielk1977f75232f2007-05-10 17:32:48 +000098########################################################################
99
100#----------------------------------------------------------------
101# These tests caused errors that were first caught by the tests
102# in this file. They are still here.
danielk1977def0fec2007-05-10 15:37:52 +0000103do_test fuzz-1.1 {
104 execsql {
105 SELECT 'abc' LIKE X'ABCD';
106 }
107} {0}
108do_test fuzz-1.2 {
109 execsql {
110 SELECT 'abc' LIKE zeroblob(10);
111 }
112} {0}
113do_test fuzz-1.3 {
114 execsql {
115 SELECT zeroblob(10) LIKE 'abc';
116 }
117} {0}
118do_test fuzz-1.4 {
119 execsql {
120 SELECT (- -21) % NOT (456 LIKE zeroblob(10));
121 }
122} {0}
danielk1977f75232f2007-05-10 17:32:48 +0000123do_test fuzz-1.5 {
124 execsql {
125 SELECT (SELECT (
126 SELECT (SELECT -2147483648) FROM (SELECT 1) ORDER BY 1
127 ))
danielk1977def0fec2007-05-10 15:37:52 +0000128 }
danielk1977f75232f2007-05-10 17:32:48 +0000129} {-2147483648}
130do_test fuzz-1.6 {
131 execsql {
132 SELECT 'abc', zeroblob(1) FROM (SELECT 1) ORDER BY 1
133 }
134} [execsql {SELECT 'abc', zeroblob(1)}]
135
136do_test fuzz-1.7 {
137 execsql {
danielk1977639f45f2007-05-10 17:38:57 +0000138 SELECT (
139 SELECT zeroblob(1000) FROM (
140 SELECT * FROM (SELECT 'first') ORDER BY NOT 'in'
141 )
142 )
danielk1977f75232f2007-05-10 17:32:48 +0000143 }
danielk1977def0fec2007-05-10 15:37:52 +0000144} {}
145
danielk1977f75232f2007-05-10 17:32:48 +0000146#----------------------------------------------------------------
147# Test some fuzzily generated expressions.
148#
149for {set ii 0} {$ii < 2000} {incr ii} {
150 do_test fuzz-2.1.$ii {
151 set ::expr [Expr]
152 set rc [catch {execsql "SELECT $::expr"} msg]
153 set e [expr {
154 $rc == 0 ||
155 $msg eq "parser stack overflow" ||
156 0 == [string first "ORDER BY column number" $msg]
157 }]
158 if {$e == 0} {
159 puts ""
160 puts "SELECT $::expr"
161 puts $msg
162 }
163 set e
164 } {1}
165}
166
167do_test fuzz-3.1 {
168 execsql {
169 CREATE TABLE abc(a, b, c);
170 CREATE TABLE def(d, e, f);
171 CREATE TABLE ghi(g, h, i);
172 }
173} {}
174set ::TableList [list abc def ghi]
175
176#----------------------------------------------------------------
177# Test some fuzzily generated SELECT statements.
178#
179for {set ii 0} {$ii < 2000} {incr ii} {
180 do_test fuzz-2.2.$ii {
181 set ::select [Select]
182 set rc [catch {execsql $::select} msg]
183 set e [expr {$rc == 0 || $msg eq "parser stack overflow"}]
184 set e [expr {
185 $rc == 0 ||
186 $msg eq "parser stack overflow" ||
187 0 == [string first "ORDER BY column number" $msg]
188 }]
189 if {$e == 0} {
190 puts ""
191 puts $::select
192 puts $msg
193 }
194 set e
195 } {1}
196}
197
danielk1977def0fec2007-05-10 15:37:52 +0000198finish_test