@@ -8,17 +8,27 @@ private import codeql.ruby.ApiGraphs
88 * in every Ruby object. In addition, its module methods can be called by
99 * providing a specific receiver as in `Kernel.exit`.
1010 */
11- class KernelMethodCall extends MethodCall {
11+ class KernelMethodCall extends DataFlow:: CallNode {
12+ private MethodCall methodCall ;
13+
1214 KernelMethodCall ( ) {
13- this = API:: getTopLevelMember ( "Kernel" ) .getAMethodCall ( _) .asExpr ( ) .getExpr ( )
14- or
15- this instanceof UnknownMethodCall and
15+ methodCall = this .asExpr ( ) .getExpr ( ) and
1616 (
17- this . getReceiver ( ) instanceof Self and isPrivateKernelMethod ( this . getMethodName ( ) )
17+ this = API :: getTopLevelMember ( "Kernel" ) . getAMethodCall ( _ )
1818 or
19- isPublicKernelMethod ( this .getMethodName ( ) )
19+ methodCall instanceof UnknownMethodCall and
20+ (
21+ this .getReceiver ( ) .asExpr ( ) .getExpr ( ) instanceof Self and
22+ isPrivateKernelMethod ( methodCall .getMethodName ( ) )
23+ or
24+ isPublicKernelMethod ( methodCall .getMethodName ( ) )
25+ )
2026 )
2127 }
28+
29+ string getMethodName ( ) { result = methodCall .getMethodName ( ) }
30+
31+ int getNumberOfArguments ( ) { result = methodCall .getNumberOfArguments ( ) }
2232}
2333
2434/**
@@ -161,19 +171,14 @@ class SubshellHeredocExecution extends SystemCommandExecution::Range {
161171 * ```
162172 * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-system
163173 */
164- class KernelSystemCall extends SystemCommandExecution:: Range {
165- KernelMethodCall methodCall ;
174+ class KernelSystemCall extends SystemCommandExecution:: Range , KernelMethodCall {
175+ KernelSystemCall ( ) { this . getMethodName ( ) = "system" }
166176
167- KernelSystemCall ( ) {
168- methodCall .getMethodName ( ) = "system" and
169- this .asExpr ( ) .getExpr ( ) = methodCall
170- }
171-
172- override DataFlow:: Node getAnArgument ( ) { result .asExpr ( ) .getExpr ( ) = methodCall .getAnArgument ( ) }
177+ override DataFlow:: Node getAnArgument ( ) { result = this .getArgument ( _) }
173178
174179 override predicate isShellInterpreted ( DataFlow:: Node arg ) {
175180 // Kernel.system invokes a subshell if you provide a single string as argument
176- methodCall .getNumberOfArguments ( ) = 1 and arg . asExpr ( ) . getExpr ( ) = methodCall . getAnArgument ( )
181+ this .getNumberOfArguments ( ) = 1 and arg = getAnArgument ( )
177182 }
178183}
179184
@@ -182,19 +187,14 @@ class KernelSystemCall extends SystemCommandExecution::Range {
182187 * `Kernel.exec` takes the same argument forms as `Kernel.system`. See `KernelSystemCall` for details.
183188 * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-exec
184189 */
185- class KernelExecCall extends SystemCommandExecution:: Range {
186- KernelMethodCall methodCall ;
190+ class KernelExecCall extends SystemCommandExecution:: Range , KernelMethodCall {
191+ KernelExecCall ( ) { this . getMethodName ( ) = "exec" }
187192
188- KernelExecCall ( ) {
189- methodCall .getMethodName ( ) = "exec" and
190- this .asExpr ( ) .getExpr ( ) = methodCall
191- }
192-
193- override DataFlow:: Node getAnArgument ( ) { result .asExpr ( ) .getExpr ( ) = methodCall .getAnArgument ( ) }
193+ override DataFlow:: Node getAnArgument ( ) { result = this .getArgument ( _) }
194194
195195 override predicate isShellInterpreted ( DataFlow:: Node arg ) {
196196 // Kernel.exec invokes a subshell if you provide a single string as argument
197- methodCall .getNumberOfArguments ( ) = 1 and arg . asExpr ( ) . getExpr ( ) = methodCall . getAnArgument ( )
197+ this .getNumberOfArguments ( ) = 1 and arg = getAnArgument ( )
198198 }
199199}
200200
@@ -208,19 +208,14 @@ class KernelExecCall extends SystemCommandExecution::Range {
208208 * spawn([env,] command... [,options]) -> pid
209209 * ```
210210 */
211- class KernelSpawnCall extends SystemCommandExecution:: Range {
212- KernelMethodCall methodCall ;
211+ class KernelSpawnCall extends SystemCommandExecution:: Range , KernelMethodCall {
212+ KernelSpawnCall ( ) { this . getMethodName ( ) = "spawn" }
213213
214- KernelSpawnCall ( ) {
215- methodCall .getMethodName ( ) = "spawn" and
216- this .asExpr ( ) .getExpr ( ) = methodCall
217- }
218-
219- override DataFlow:: Node getAnArgument ( ) { result .asExpr ( ) .getExpr ( ) = methodCall .getAnArgument ( ) }
214+ override DataFlow:: Node getAnArgument ( ) { result = this .getArgument ( _) }
220215
221216 override predicate isShellInterpreted ( DataFlow:: Node arg ) {
222217 // Kernel.spawn invokes a subshell if you provide a single string as argument
223- methodCall .getNumberOfArguments ( ) = 1 and arg . asExpr ( ) . getExpr ( ) = methodCall . getAnArgument ( )
218+ this .getNumberOfArguments ( ) = 1 and arg = getAnArgument ( )
224219 }
225220}
226221
@@ -284,14 +279,10 @@ class Open3PipelineCall extends SystemCommandExecution::Range {
284279 * a # => 2
285280 * ```
286281 */
287- class EvalCallCodeExecution extends CodeExecution:: Range {
288- KernelMethodCall methodCall ;
289-
290- EvalCallCodeExecution ( ) {
291- this .asExpr ( ) .getExpr ( ) = methodCall and methodCall .getMethodName ( ) = "eval"
292- }
282+ class EvalCallCodeExecution extends CodeExecution:: Range , KernelMethodCall {
283+ EvalCallCodeExecution ( ) { this .getMethodName ( ) = "eval" }
293284
294- override DataFlow:: Node getCode ( ) { result . asExpr ( ) . getExpr ( ) = methodCall .getArgument ( 0 ) }
285+ override DataFlow:: Node getCode ( ) { result = this .getArgument ( 0 ) }
295286}
296287
297288/**
@@ -302,51 +293,41 @@ class EvalCallCodeExecution extends CodeExecution::Range {
302293 * arr # => [1]
303294 * ```
304295 */
305- class SendCallCodeExecution extends CodeExecution:: Range {
306- KernelMethodCall methodCall ;
296+ class SendCallCodeExecution extends CodeExecution:: Range , KernelMethodCall {
297+ SendCallCodeExecution ( ) { this . getMethodName ( ) = "send" }
307298
308- SendCallCodeExecution ( ) {
309- this .asExpr ( ) .getExpr ( ) = methodCall and methodCall .getMethodName ( ) = "send"
310- }
311-
312- override DataFlow:: Node getCode ( ) { result .asExpr ( ) .getExpr ( ) = methodCall .getArgument ( 0 ) }
299+ override DataFlow:: Node getCode ( ) { result = this .getArgument ( 0 ) }
313300}
314301
315302/**
316303 * A call to `BasicObject#instance_eval`, which executes its first argument as Ruby code.
317304 */
318- class InstanceEvalCallCodeExecution extends CodeExecution:: Range {
319- BasicObjectInstanceMethodCall methodCall ;
320-
305+ class InstanceEvalCallCodeExecution extends CodeExecution:: Range , DataFlow:: CallNode {
321306 InstanceEvalCallCodeExecution ( ) {
322- this .asExpr ( ) .getExpr ( ) = methodCall and methodCall .getMethodName ( ) = "instance_eval"
307+ this .asExpr ( ) .getExpr ( ) . ( UnknownMethodCall ) .getMethodName ( ) = "instance_eval"
323308 }
324309
325- override DataFlow:: Node getCode ( ) { result . asExpr ( ) . getExpr ( ) = methodCall .getArgument ( 0 ) }
310+ override DataFlow:: Node getCode ( ) { result = this .getArgument ( 0 ) }
326311}
327312
328313/**
329314 * A call to `Module#class_eval`, which executes its first argument as Ruby code.
330315 */
331- class ClassEvalCallCodeExecution extends CodeExecution:: Range {
332- UnknownMethodCall methodCall ;
333-
316+ class ClassEvalCallCodeExecution extends CodeExecution:: Range , DataFlow:: CallNode {
334317 ClassEvalCallCodeExecution ( ) {
335- this .asExpr ( ) .getExpr ( ) = methodCall and methodCall .getMethodName ( ) = "class_eval"
318+ this .asExpr ( ) .getExpr ( ) . ( UnknownMethodCall ) .getMethodName ( ) = "class_eval"
336319 }
337320
338- override DataFlow:: Node getCode ( ) { result . asExpr ( ) . getExpr ( ) = methodCall .getArgument ( 0 ) }
321+ override DataFlow:: Node getCode ( ) { result = this .getArgument ( 0 ) }
339322}
340323
341324/**
342325 * A call to `Module#module_eval`, which executes its first argument as Ruby code.
343326 */
344- class ModuleEvalCallCodeExecution extends CodeExecution:: Range {
345- UnknownMethodCall methodCall ;
346-
327+ class ModuleEvalCallCodeExecution extends CodeExecution:: Range , DataFlow:: CallNode {
347328 ModuleEvalCallCodeExecution ( ) {
348- this .asExpr ( ) .getExpr ( ) = methodCall and methodCall .getMethodName ( ) = "module_eval"
329+ this .asExpr ( ) .getExpr ( ) . ( UnknownMethodCall ) .getMethodName ( ) = "module_eval"
349330 }
350331
351- override DataFlow:: Node getCode ( ) { result . asExpr ( ) . getExpr ( ) = methodCall .getArgument ( 0 ) }
332+ override DataFlow:: Node getCode ( ) { result = this .getArgument ( 0 ) }
352333}
0 commit comments