ronin-code-sql 2.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +4 -0
- data/.editorconfig +11 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.gitignore +11 -0
- data/.mailmap +1 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +104 -0
- data/Gemfile +28 -0
- data/README.md +212 -0
- data/Rakefile +30 -0
- data/gemspec.yml +25 -0
- data/lib/ronin/code/sql/binary_expr.rb +53 -0
- data/lib/ronin/code/sql/clause.rb +74 -0
- data/lib/ronin/code/sql/clauses.rb +310 -0
- data/lib/ronin/code/sql/emittable.rb +88 -0
- data/lib/ronin/code/sql/emitter.rb +406 -0
- data/lib/ronin/code/sql/field.rb +110 -0
- data/lib/ronin/code/sql/fields.rb +82 -0
- data/lib/ronin/code/sql/function.rb +53 -0
- data/lib/ronin/code/sql/functions.rb +1265 -0
- data/lib/ronin/code/sql/injection.rb +168 -0
- data/lib/ronin/code/sql/injection_expr.rb +113 -0
- data/lib/ronin/code/sql/literal.rb +40 -0
- data/lib/ronin/code/sql/literals.rb +83 -0
- data/lib/ronin/code/sql/operators.rb +384 -0
- data/lib/ronin/code/sql/statement.rb +72 -0
- data/lib/ronin/code/sql/statement_list.rb +112 -0
- data/lib/ronin/code/sql/statements.rb +117 -0
- data/lib/ronin/code/sql/unary_expr.rb +38 -0
- data/lib/ronin/code/sql/version.rb +28 -0
- data/lib/ronin/code/sql.rb +96 -0
- data/ronin-code-sql.gemspec +62 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/sql/binary_expr_examples.rb +25 -0
- data/spec/sql/binary_expr_spec.rb +5 -0
- data/spec/sql/clause_examples.rb +43 -0
- data/spec/sql/clause_spec.rb +31 -0
- data/spec/sql/clauses_spec.rb +47 -0
- data/spec/sql/emittable_spec.rb +41 -0
- data/spec/sql/emitter_spec.rb +533 -0
- data/spec/sql/field_spec.rb +103 -0
- data/spec/sql/fields_spec.rb +40 -0
- data/spec/sql/function_examples.rb +30 -0
- data/spec/sql/function_spec.rb +25 -0
- data/spec/sql/functions_spec.rb +113 -0
- data/spec/sql/injection_expr_spec.rb +98 -0
- data/spec/sql/injection_spec.rb +172 -0
- data/spec/sql/literal_spec.rb +5 -0
- data/spec/sql/literals_spec.rb +46 -0
- data/spec/sql/operators_spec.rb +44 -0
- data/spec/sql/statement_examples.rb +39 -0
- data/spec/sql/statement_list_spec.rb +48 -0
- data/spec/sql/statement_spec.rb +38 -0
- data/spec/sql/statements_spec.rb +22 -0
- data/spec/sql/unary_expr_examples.rb +20 -0
- data/spec/sql/unary_expr_spec.rb +5 -0
- data/spec/sql_spec.rb +18 -0
- metadata +157 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-sql - A Ruby DSL for crafting SQL Injections.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-sql is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-sql is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/sql/operators'
|
22
|
+
require 'ronin/code/sql/emittable'
|
23
|
+
|
24
|
+
module Ronin
|
25
|
+
module Code
|
26
|
+
module SQL
|
27
|
+
#
|
28
|
+
# Represents a binary expression in SQL.
|
29
|
+
#
|
30
|
+
# @api semipublic
|
31
|
+
#
|
32
|
+
class BinaryExpr < Struct.new(:left,:operator,:right)
|
33
|
+
|
34
|
+
include Operators
|
35
|
+
include Emittable
|
36
|
+
|
37
|
+
#
|
38
|
+
# Converts the binary expression to SQL.
|
39
|
+
#
|
40
|
+
# @param [Hash{Symbol => Object}] kwargs
|
41
|
+
# Additional keyword arguments for {Emitter#initialize}.
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
# The emitted SQL expression.
|
45
|
+
#
|
46
|
+
def to_sql(**kwargs)
|
47
|
+
emitter(**kwargs).emit_expression(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-sql - A Ruby DSL for crafting SQL Injections.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-sql is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-sql is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/sql/literals'
|
22
|
+
require 'ronin/code/sql/fields'
|
23
|
+
require 'ronin/code/sql/functions'
|
24
|
+
require 'ronin/code/sql/statement'
|
25
|
+
require 'ronin/code/sql/statements'
|
26
|
+
require 'ronin/code/sql/emittable'
|
27
|
+
|
28
|
+
module Ronin
|
29
|
+
module Code
|
30
|
+
module SQL
|
31
|
+
#
|
32
|
+
# Represents a SQL Clause.
|
33
|
+
#
|
34
|
+
# @api semipublic
|
35
|
+
#
|
36
|
+
class Clause < Struct.new(:keyword,:argument)
|
37
|
+
|
38
|
+
include Literals
|
39
|
+
include Fields
|
40
|
+
include Functions
|
41
|
+
include Statements
|
42
|
+
include Emittable
|
43
|
+
|
44
|
+
#
|
45
|
+
# Initializes the SQL clause.
|
46
|
+
#
|
47
|
+
# @param [Symbol] keyword
|
48
|
+
# The name of the clause.
|
49
|
+
#
|
50
|
+
# @param [Object] argument
|
51
|
+
# Additional argument for the clause.
|
52
|
+
#
|
53
|
+
# @yield [(clause)]
|
54
|
+
# If a block is given, the return value will be used as the argument.
|
55
|
+
#
|
56
|
+
# @yieldparam [Clause] clause
|
57
|
+
# If the block accepts an argument, it will be passed the new clause.
|
58
|
+
# Otherwise the block will be evaluated within the clause.
|
59
|
+
#
|
60
|
+
def initialize(keyword,argument=nil,&block)
|
61
|
+
super(keyword,argument)
|
62
|
+
|
63
|
+
if block
|
64
|
+
self.argument = case block.arity
|
65
|
+
when 0 then instance_eval(&block)
|
66
|
+
else block.call(self)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-sql - A Ruby DSL for crafting SQL Injections.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-sql is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-sql is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Ronin
|
22
|
+
module Code
|
23
|
+
module SQL
|
24
|
+
#
|
25
|
+
# Methods for creating common SQL {Clause Clauses}.
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
#
|
29
|
+
module Clauses
|
30
|
+
#
|
31
|
+
# The defined clauses of the statement.
|
32
|
+
#
|
33
|
+
# @return [Array<Clause>]
|
34
|
+
# The clauses defined thus far.
|
35
|
+
#
|
36
|
+
def clauses
|
37
|
+
@clauses ||= []
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Appends an arbitrary clause.
|
42
|
+
#
|
43
|
+
# @param [Symbol] keyword
|
44
|
+
# The name of the clause.
|
45
|
+
#
|
46
|
+
# @param [Object] argument
|
47
|
+
# Additional argument for the clause.
|
48
|
+
#
|
49
|
+
# @yield [(clause)]
|
50
|
+
# If a block is given, the return value will be used as the argument.
|
51
|
+
#
|
52
|
+
# @yieldparam [Clause] clause
|
53
|
+
# If the block accepts an argument, it will be passed the new clause.
|
54
|
+
# Otherwise the block will be evaluated within the clause.
|
55
|
+
#
|
56
|
+
# @return [self]
|
57
|
+
#
|
58
|
+
def clause(keyword,argument=nil,&block)
|
59
|
+
clauses << Clause.new(keyword,argument,&block)
|
60
|
+
return self
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Appends a `FROM` clause.
|
65
|
+
#
|
66
|
+
# @param [Field, Symbol] table
|
67
|
+
# The table to select from.
|
68
|
+
#
|
69
|
+
# @return [self]
|
70
|
+
#
|
71
|
+
def from(table=nil,&block)
|
72
|
+
clause(:FROM,table,&block)
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Appends an `INTO` clause.
|
77
|
+
#
|
78
|
+
# @param [Field, Symbol] table
|
79
|
+
# The table to insert into.
|
80
|
+
#
|
81
|
+
# @return [self]
|
82
|
+
#
|
83
|
+
def into(table=nil,&block)
|
84
|
+
clause(:INTO,table,&block)
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Appends a `WHERE` clause.
|
89
|
+
#
|
90
|
+
# @return [self]
|
91
|
+
#
|
92
|
+
def where(&block)
|
93
|
+
clause(:WHERE,&block)
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Appends a `JOIN` clause.
|
98
|
+
#
|
99
|
+
# @param [Field, Symbol] table
|
100
|
+
# The table to join.
|
101
|
+
#
|
102
|
+
# @return [self]
|
103
|
+
#
|
104
|
+
def join(table=nil,&block)
|
105
|
+
clause(:JOIN,table,&block)
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Appends a `INNER JOIN` clause.
|
110
|
+
#
|
111
|
+
# @param [Field, Symbol] table
|
112
|
+
# The table to join.
|
113
|
+
#
|
114
|
+
# @return [self]
|
115
|
+
#
|
116
|
+
def inner_join(table=nil,&block)
|
117
|
+
clause([:INNER, :JOIN],table,&block)
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Appends a `LEFT JOIN` clause.
|
122
|
+
#
|
123
|
+
# @param [Field, Symbol] table
|
124
|
+
# The table to join.
|
125
|
+
#
|
126
|
+
# @return [self]
|
127
|
+
#
|
128
|
+
def left_join(table=nil,&block)
|
129
|
+
clause([:LEFT, :JOIN],table,&block)
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# Appends a `RIGHT JOIN` clause.
|
134
|
+
#
|
135
|
+
# @param [Field, Symbol] table
|
136
|
+
# The table to join.
|
137
|
+
#
|
138
|
+
# @return [self]
|
139
|
+
#
|
140
|
+
def right_join(table=nil,&block)
|
141
|
+
clause([:RIGHT, :JOIN],table,&block)
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# Appends a `FULL JOIN` clause.
|
146
|
+
#
|
147
|
+
# @param [Field, Symbol] table
|
148
|
+
# The table to join.
|
149
|
+
#
|
150
|
+
# @return [self]
|
151
|
+
#
|
152
|
+
def full_join(table=nil,&block)
|
153
|
+
clause([:FULL, :JOIN],table,&block)
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Appends a `ON` clause.
|
158
|
+
#
|
159
|
+
# @return [self]
|
160
|
+
#
|
161
|
+
def on(&block)
|
162
|
+
clause(:ON,&block)
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Appends a `UNION` clause.
|
167
|
+
#
|
168
|
+
# @return [self]
|
169
|
+
#
|
170
|
+
def union(&block)
|
171
|
+
clause(:UNION,&block)
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Appends a `UNION ALL` clause.
|
176
|
+
#
|
177
|
+
# @return [self]
|
178
|
+
#
|
179
|
+
# @since 1.1.0
|
180
|
+
#
|
181
|
+
def union_all(&block)
|
182
|
+
clause([:UNION, :ALL],&block)
|
183
|
+
end
|
184
|
+
|
185
|
+
#
|
186
|
+
# Appends a `GROUP BY` clause.
|
187
|
+
#
|
188
|
+
# @param [Array<Field, Symbol>] columns
|
189
|
+
# The columns for `GROUP BY`.
|
190
|
+
#
|
191
|
+
# @return [self]
|
192
|
+
#
|
193
|
+
def group_by(*columns,&block)
|
194
|
+
clause([:GROUP, :BY],columns,&block)
|
195
|
+
end
|
196
|
+
|
197
|
+
#
|
198
|
+
# Appends a `HAVING` clause.
|
199
|
+
#
|
200
|
+
# @return [self]
|
201
|
+
#
|
202
|
+
def having(&block)
|
203
|
+
clause(:HAVING,&block)
|
204
|
+
end
|
205
|
+
|
206
|
+
#
|
207
|
+
# Appends a `LIMIT` clause.
|
208
|
+
#
|
209
|
+
# @param [Integer] value
|
210
|
+
# The maximum number of rows to select.
|
211
|
+
#
|
212
|
+
# @return [self]
|
213
|
+
#
|
214
|
+
def limit(value,&block)
|
215
|
+
clause(:LIMIT,value,&block)
|
216
|
+
end
|
217
|
+
|
218
|
+
#
|
219
|
+
# Appends a `OFFSET` clause.
|
220
|
+
#
|
221
|
+
# @param [Integer] value
|
222
|
+
# The index to start selecting at within the result set.
|
223
|
+
#
|
224
|
+
# @return [self]
|
225
|
+
#
|
226
|
+
def offset(value,&block)
|
227
|
+
clause(:OFFSET,value,&block)
|
228
|
+
end
|
229
|
+
|
230
|
+
#
|
231
|
+
# Appends a `TOP` clause.
|
232
|
+
#
|
233
|
+
# @param [Integer] value
|
234
|
+
# The number of top rows to select.
|
235
|
+
#
|
236
|
+
# @return [self]
|
237
|
+
#
|
238
|
+
def top(value,&block)
|
239
|
+
clause(:TOP,value,&block)
|
240
|
+
end
|
241
|
+
|
242
|
+
#
|
243
|
+
# Appends a `INTO` clause.
|
244
|
+
#
|
245
|
+
# @param [Field, Symbol] table
|
246
|
+
# The table to insert/replace into.
|
247
|
+
#
|
248
|
+
# @return [self]
|
249
|
+
#
|
250
|
+
def into(table)
|
251
|
+
clause(:INTO,table)
|
252
|
+
end
|
253
|
+
|
254
|
+
#
|
255
|
+
# Appends a `VALUES` clause.
|
256
|
+
#
|
257
|
+
# @param [Array] values
|
258
|
+
# The values to insert.
|
259
|
+
#
|
260
|
+
# @return [self]
|
261
|
+
#
|
262
|
+
def values(*values)
|
263
|
+
clause(:VALUES,values)
|
264
|
+
end
|
265
|
+
|
266
|
+
#
|
267
|
+
# Appends a `DEFAULT VALUES` clause.
|
268
|
+
#
|
269
|
+
# @return [self]
|
270
|
+
#
|
271
|
+
def default_values
|
272
|
+
clause([:DEFAULT, :VALUES])
|
273
|
+
end
|
274
|
+
|
275
|
+
#
|
276
|
+
# Appends a `SET` clause.
|
277
|
+
#
|
278
|
+
# @param [Hash{Field,Symbol => Object}] values
|
279
|
+
# The columns and values to update.
|
280
|
+
#
|
281
|
+
# @return [self]
|
282
|
+
#
|
283
|
+
def set(values={})
|
284
|
+
clause(:SET,values)
|
285
|
+
end
|
286
|
+
|
287
|
+
#
|
288
|
+
# Appends a `INDEXED BY` clause.
|
289
|
+
#
|
290
|
+
# @param [Field, Symbol] name
|
291
|
+
# The name of the index.
|
292
|
+
#
|
293
|
+
# @return [self]
|
294
|
+
#
|
295
|
+
def indexed_by(name,&block)
|
296
|
+
clause([:INDEXED, :BY],name,&block)
|
297
|
+
end
|
298
|
+
|
299
|
+
#
|
300
|
+
# Appends a `NOT INDEXED` clause.
|
301
|
+
#
|
302
|
+
# @return [self]
|
303
|
+
#
|
304
|
+
def not_indexed
|
305
|
+
clause([:NOT, :INDEXED])
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-sql - A Ruby DSL for crafting SQL Injections.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-sql is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-sql is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/sql/emitter'
|
22
|
+
|
23
|
+
module Ronin
|
24
|
+
module Code
|
25
|
+
module SQL
|
26
|
+
#
|
27
|
+
# Allows an object to be converted to raw SQL.
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
#
|
31
|
+
module Emittable
|
32
|
+
#
|
33
|
+
# Creates a new emitter.
|
34
|
+
#
|
35
|
+
# @param [Hash{Symbol => Object}] kwargs
|
36
|
+
# Additional keyword arguments for {Emitter#initialize}.
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
#
|
40
|
+
def emitter(**kwargs)
|
41
|
+
Emitter.new(**kwargs)
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# The default `to_sql` method.
|
46
|
+
#
|
47
|
+
# @param [Hash{Symbol => Object}] kwargs
|
48
|
+
# Additional keyword arguments for {Emitter#initialize}.
|
49
|
+
#
|
50
|
+
# @option kwargs [:lower, :upper, :random, nil] :case
|
51
|
+
# Case for keywords.
|
52
|
+
#
|
53
|
+
# @option kwargs [String] :space (' ')
|
54
|
+
# String to use for white-space.
|
55
|
+
#
|
56
|
+
# @option kwargs [:single, :double] :quotes (:single)
|
57
|
+
# Type of quotes to use for Strings.
|
58
|
+
#
|
59
|
+
# @return [String]
|
60
|
+
# The raw SQL.
|
61
|
+
#
|
62
|
+
# @raise [ArgumentError]
|
63
|
+
# Could not emit an unknown SQL object.
|
64
|
+
#
|
65
|
+
def to_sql(**kwargs)
|
66
|
+
emitter(**kwargs).emit(self)
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# @see #to_sql
|
71
|
+
#
|
72
|
+
def to_s
|
73
|
+
to_sql
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Inspects the object.
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
# The inspected object.
|
81
|
+
#
|
82
|
+
def inspect
|
83
|
+
"#<#{self.class}: #{to_sql}>"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|