ronin-code-sql 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.editorconfig +11 -0
  4. data/.github/workflows/ruby.yml +27 -0
  5. data/.gitignore +11 -0
  6. data/.mailmap +1 -0
  7. data/.rspec +1 -0
  8. data/.ruby-version +1 -0
  9. data/.yardopts +1 -0
  10. data/COPYING.txt +165 -0
  11. data/ChangeLog.md +104 -0
  12. data/Gemfile +28 -0
  13. data/README.md +212 -0
  14. data/Rakefile +30 -0
  15. data/gemspec.yml +25 -0
  16. data/lib/ronin/code/sql/binary_expr.rb +53 -0
  17. data/lib/ronin/code/sql/clause.rb +74 -0
  18. data/lib/ronin/code/sql/clauses.rb +310 -0
  19. data/lib/ronin/code/sql/emittable.rb +88 -0
  20. data/lib/ronin/code/sql/emitter.rb +406 -0
  21. data/lib/ronin/code/sql/field.rb +110 -0
  22. data/lib/ronin/code/sql/fields.rb +82 -0
  23. data/lib/ronin/code/sql/function.rb +53 -0
  24. data/lib/ronin/code/sql/functions.rb +1265 -0
  25. data/lib/ronin/code/sql/injection.rb +168 -0
  26. data/lib/ronin/code/sql/injection_expr.rb +113 -0
  27. data/lib/ronin/code/sql/literal.rb +40 -0
  28. data/lib/ronin/code/sql/literals.rb +83 -0
  29. data/lib/ronin/code/sql/operators.rb +384 -0
  30. data/lib/ronin/code/sql/statement.rb +72 -0
  31. data/lib/ronin/code/sql/statement_list.rb +112 -0
  32. data/lib/ronin/code/sql/statements.rb +117 -0
  33. data/lib/ronin/code/sql/unary_expr.rb +38 -0
  34. data/lib/ronin/code/sql/version.rb +28 -0
  35. data/lib/ronin/code/sql.rb +96 -0
  36. data/ronin-code-sql.gemspec +62 -0
  37. data/spec/spec_helper.rb +3 -0
  38. data/spec/sql/binary_expr_examples.rb +25 -0
  39. data/spec/sql/binary_expr_spec.rb +5 -0
  40. data/spec/sql/clause_examples.rb +43 -0
  41. data/spec/sql/clause_spec.rb +31 -0
  42. data/spec/sql/clauses_spec.rb +47 -0
  43. data/spec/sql/emittable_spec.rb +41 -0
  44. data/spec/sql/emitter_spec.rb +533 -0
  45. data/spec/sql/field_spec.rb +103 -0
  46. data/spec/sql/fields_spec.rb +40 -0
  47. data/spec/sql/function_examples.rb +30 -0
  48. data/spec/sql/function_spec.rb +25 -0
  49. data/spec/sql/functions_spec.rb +113 -0
  50. data/spec/sql/injection_expr_spec.rb +98 -0
  51. data/spec/sql/injection_spec.rb +172 -0
  52. data/spec/sql/literal_spec.rb +5 -0
  53. data/spec/sql/literals_spec.rb +46 -0
  54. data/spec/sql/operators_spec.rb +44 -0
  55. data/spec/sql/statement_examples.rb +39 -0
  56. data/spec/sql/statement_list_spec.rb +48 -0
  57. data/spec/sql/statement_spec.rb +38 -0
  58. data/spec/sql/statements_spec.rb +22 -0
  59. data/spec/sql/unary_expr_examples.rb +20 -0
  60. data/spec/sql/unary_expr_spec.rb +5 -0
  61. data/spec/sql_spec.rb +18 -0
  62. 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