Skip to content

Commit e7649fc

Browse files
committed
Ruby: Fix ModuleBase::get(A)Method for private methods
1 parent 37a2b7d commit e7649fc

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

ruby/ql/lib/codeql/ruby/ast/Module.qll

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
private import codeql.ruby.AST
2+
private import codeql.ruby.CFG
23
private import internal.AST
34
private import internal.Module
45
private import internal.TreeSitter
@@ -49,24 +50,54 @@ class Module extends TModule {
4950
}
5051
}
5152

53+
/**
54+
* Gets the enclosing module of `s`, but only if `s` and the module are in the
55+
* same CFG scope. For example, in
56+
*
57+
* ```rb
58+
* module M
59+
* def pub; end
60+
* private def priv; end
61+
* end
62+
* ```
63+
*
64+
* `M` is the enclosing module of `pub` and `priv`, in the same CFG scope, while
65+
* in
66+
*
67+
* ```rb
68+
* module M
69+
* def m
70+
* def nested; end
71+
* end
72+
* end
73+
* ```
74+
*
75+
* `M` is the enclosing module of `m`, in the same CFG scope, while `nested` is not.
76+
*/
77+
pragma[nomagic]
78+
private ModuleBase getEnclosingModuleInSameCfgScope(Stmt s) {
79+
result = s.getEnclosingModule() and
80+
s.getCfgScope() = [result.(CfgScope), result.getCfgScope()]
81+
}
82+
5283
/**
5384
* The base class for classes, singleton classes, and modules.
5485
*/
5586
class ModuleBase extends BodyStmt, Scope, TModuleBase {
5687
/** Gets a method defined in this module/class. */
57-
MethodBase getAMethod() { result = this.getAStmt() }
88+
MethodBase getAMethod() { this = getEnclosingModuleInSameCfgScope(result) }
5889

5990
/** Gets the method named `name` in this module/class, if any. */
6091
MethodBase getMethod(string name) { result = this.getAMethod() and result.getName() = name }
6192

6293
/** Gets a class defined in this module/class. */
63-
ClassDeclaration getAClass() { result = this.getAStmt() }
94+
ClassDeclaration getAClass() { this = getEnclosingModuleInSameCfgScope(result) }
6495

6596
/** Gets the class named `name` in this module/class, if any. */
6697
ClassDeclaration getClass(string name) { result = this.getAClass() and result.getName() = name }
6798

6899
/** Gets a module defined in this module/class. */
69-
ModuleDeclaration getAModule() { result = this.getAStmt() }
100+
ModuleDeclaration getAModule() { this = getEnclosingModuleInSameCfgScope(result) }
70101

71102
/** Gets the module named `name` in this module/class, if any. */
72103
ModuleDeclaration getModule(string name) {

ruby/ql/test/library-tests/modules/callgraph.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,10 @@ getTarget
190190
| private.rb:64:7:64:32 | call to puts | calls.rb:102:5:102:30 | puts |
191191
| private.rb:67:3:69:5 | call to private | calls.rb:109:5:109:20 | private |
192192
| private.rb:68:7:68:32 | call to puts | calls.rb:102:5:102:30 | puts |
193+
| private.rb:72:7:72:8 | call to m1 | private.rb:63:11:65:5 | m1 |
193194
| private.rb:77:3:81:5 | call to private | calls.rb:109:5:109:20 | private |
194195
| private.rb:78:7:78:32 | call to puts | calls.rb:102:5:102:30 | puts |
196+
| private.rb:79:7:79:8 | call to m2 | private.rb:67:11:69:5 | m2 |
195197
| private.rb:80:7:80:26 | call to new | calls.rb:114:5:114:16 | new |
196198
| private.rb:84:1:84:20 | call to new | calls.rb:114:5:114:16 | new |
197199
| private.rb:84:1:84:28 | call to call_m1 | private.rb:71:3:73:5 | call_m1 |
@@ -240,8 +242,6 @@ unresolvedCall
240242
| private.rb:35:1:35:14 | call to private2 |
241243
| private.rb:36:1:36:14 | call to private3 |
242244
| private.rb:37:1:37:14 | call to private4 |
243-
| private.rb:72:7:72:8 | call to m1 |
244-
| private.rb:79:7:79:8 | call to m2 |
245245
| private.rb:80:7:80:29 | call to m1 |
246246
| private.rb:85:1:85:23 | call to m1 |
247247
privateMethod

ruby/ql/test/library-tests/modules/methods.expected

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,20 @@ getMethod
4646
| modules.rb:5:3:14:5 | Foo::Bar | method_in_foo_bar | modules.rb:9:5:10:7 | method_in_foo_bar |
4747
| modules.rb:37:1:46:3 | Bar | method_a | modules.rb:38:3:39:5 | method_a |
4848
| modules.rb:37:1:46:3 | Bar | method_b | modules.rb:41:3:42:5 | method_b |
49+
| private.rb:1:1:29:3 | E | private1 | private.rb:2:11:3:5 | private1 |
4950
| private.rb:1:1:29:3 | E | private2 | private.rb:8:3:9:5 | private2 |
5051
| private.rb:1:1:29:3 | E | private3 | private.rb:14:3:15:5 | private3 |
5152
| private.rb:1:1:29:3 | E | private4 | private.rb:17:3:18:5 | private4 |
5253
| private.rb:1:1:29:3 | E | public | private.rb:5:3:6:5 | public |
54+
| private.rb:42:1:60:3 | F | private1 | private.rb:43:11:44:5 | private1 |
5355
| private.rb:42:1:60:3 | F | private2 | private.rb:49:3:50:5 | private2 |
5456
| private.rb:42:1:60:3 | F | private3 | private.rb:55:3:56:5 | private3 |
5557
| private.rb:42:1:60:3 | F | private4 | private.rb:58:3:59:5 | private4 |
5658
| private.rb:42:1:60:3 | F | public | private.rb:46:3:47:5 | public |
5759
| private.rb:62:1:74:3 | PrivateOverride1 | call_m1 | private.rb:71:3:73:5 | call_m1 |
60+
| private.rb:62:1:74:3 | PrivateOverride1 | m1 | private.rb:63:11:65:5 | m1 |
61+
| private.rb:62:1:74:3 | PrivateOverride1 | m2 | private.rb:67:11:69:5 | m2 |
62+
| private.rb:76:1:82:3 | PrivateOverride2 | m1 | private.rb:77:11:81:5 | m1 |
5863
lookupMethod
5964
| calls.rb:21:1:34:3 | M | instance_m | calls.rb:22:5:24:7 | instance_m |
6065
| calls.rb:43:1:58:3 | C | add_singleton | calls.rb:364:1:368:3 | add_singleton |
@@ -406,23 +411,29 @@ lookupMethod
406411
| modules_rec.rb:4:1:5:3 | A::B | puts | calls.rb:102:5:102:30 | puts |
407412
| modules_rec.rb:4:1:5:3 | A::B | to_s | calls.rb:169:5:170:7 | to_s |
408413
| private.rb:1:1:29:3 | E | new | calls.rb:114:5:114:16 | new |
414+
| private.rb:1:1:29:3 | E | private1 | private.rb:2:11:3:5 | private1 |
409415
| private.rb:1:1:29:3 | E | private2 | private.rb:8:3:9:5 | private2 |
410416
| private.rb:1:1:29:3 | E | private3 | private.rb:14:3:15:5 | private3 |
411417
| private.rb:1:1:29:3 | E | private4 | private.rb:17:3:18:5 | private4 |
412418
| private.rb:1:1:29:3 | E | private_on_main | private.rb:31:1:32:3 | private_on_main |
413419
| private.rb:1:1:29:3 | E | public | private.rb:5:3:6:5 | public |
414420
| private.rb:1:1:29:3 | E | puts | calls.rb:102:5:102:30 | puts |
415421
| private.rb:1:1:29:3 | E | to_s | calls.rb:169:5:170:7 | to_s |
422+
| private.rb:42:1:60:3 | F | private1 | private.rb:43:11:44:5 | private1 |
416423
| private.rb:42:1:60:3 | F | private2 | private.rb:49:3:50:5 | private2 |
417424
| private.rb:42:1:60:3 | F | private3 | private.rb:55:3:56:5 | private3 |
418425
| private.rb:42:1:60:3 | F | private4 | private.rb:58:3:59:5 | private4 |
419426
| private.rb:42:1:60:3 | F | public | private.rb:46:3:47:5 | public |
420427
| private.rb:62:1:74:3 | PrivateOverride1 | call_m1 | private.rb:71:3:73:5 | call_m1 |
428+
| private.rb:62:1:74:3 | PrivateOverride1 | m1 | private.rb:63:11:65:5 | m1 |
429+
| private.rb:62:1:74:3 | PrivateOverride1 | m2 | private.rb:67:11:69:5 | m2 |
421430
| private.rb:62:1:74:3 | PrivateOverride1 | new | calls.rb:114:5:114:16 | new |
422431
| private.rb:62:1:74:3 | PrivateOverride1 | private_on_main | private.rb:31:1:32:3 | private_on_main |
423432
| private.rb:62:1:74:3 | PrivateOverride1 | puts | calls.rb:102:5:102:30 | puts |
424433
| private.rb:62:1:74:3 | PrivateOverride1 | to_s | calls.rb:169:5:170:7 | to_s |
425434
| private.rb:76:1:82:3 | PrivateOverride2 | call_m1 | private.rb:71:3:73:5 | call_m1 |
435+
| private.rb:76:1:82:3 | PrivateOverride2 | m1 | private.rb:77:11:81:5 | m1 |
436+
| private.rb:76:1:82:3 | PrivateOverride2 | m2 | private.rb:67:11:69:5 | m2 |
426437
| private.rb:76:1:82:3 | PrivateOverride2 | new | calls.rb:114:5:114:16 | new |
427438
| private.rb:76:1:82:3 | PrivateOverride2 | private_on_main | private.rb:31:1:32:3 | private_on_main |
428439
| private.rb:76:1:82:3 | PrivateOverride2 | puts | calls.rb:102:5:102:30 | puts |

0 commit comments

Comments
 (0)