Skip to content

Commit e321657

Browse files
committed
Ruby: model rails/globalid
1 parent c779b8f commit e321657

File tree

4 files changed

+200
-0
lines changed

4 files changed

+200
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* Provides modeling for `GlobalID`, a library for identifying model instances by URI.
3+
* Version: 1.0.0
4+
* https://github.com/rails/globalid
5+
*/
6+
7+
private import codeql.ruby.ApiGraphs
8+
private import codeql.ruby.Concepts
9+
private import codeql.ruby.DataFlow
10+
private import codeql.ruby.frameworks.ActiveRecord
11+
12+
/**
13+
* Provides modeling for `GlobalID`, a library for identifying model instances by URI.
14+
* Version: 1.0.0
15+
* https://github.com/rails/globalid
16+
*/
17+
module GlobalId {
18+
/** A call to `GlobalID::parse` */
19+
class ParseCall extends DataFlow::CallNode {
20+
ParseCall() { this = API::getTopLevelMember("GlobalID").getAMethodCall("parse") }
21+
}
22+
23+
/** A call to `GlobalID::find` */
24+
class FindCall extends DataFlow::CallNode, OrmInstantiation::Range {
25+
FindCall() { this = API::getTopLevelMember("GlobalID").getAMethodCall("find") }
26+
27+
override predicate methodCallMayAccessField(string methodName) { none() }
28+
}
29+
30+
/** `GlobalID::Locator` */
31+
module Locator {
32+
/** A call to `GlobalID::Locator.locate` */
33+
class LocateCall extends DataFlow::CallNode, OrmInstantiation::Range {
34+
LocateCall() {
35+
this = API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate")
36+
}
37+
38+
override predicate methodCallMayAccessField(string methodName) { none() }
39+
}
40+
41+
/** A call to `GlobalID::Locator.locate_signed` */
42+
class LocateSignedCall extends DataFlow::CallNode, OrmInstantiation::Range {
43+
LocateSignedCall() {
44+
this =
45+
API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate_signed")
46+
}
47+
48+
override predicate methodCallMayAccessField(string methodName) { none() }
49+
}
50+
51+
/** A call to `GlobalID::Locator.locate_many` */
52+
class LocateManyCall extends DataFlow::CallNode, OrmInstantiation::Range {
53+
LocateManyCall() {
54+
this = API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate_many")
55+
}
56+
57+
override predicate methodCallMayAccessField(string methodName) { none() }
58+
}
59+
60+
/** A call to `GlobalID::Locator.locate_many_signed` */
61+
class LocateManySignedCall extends DataFlow::CallNode, OrmInstantiation::Range {
62+
LocateManySignedCall() {
63+
this =
64+
API::getTopLevelMember("GlobalID")
65+
.getMember("Locator")
66+
.getAMethodCall("locate_many_signed")
67+
}
68+
69+
override predicate methodCallMayAccessField(string methodName) { none() }
70+
}
71+
}
72+
73+
// TODO: methods in this module are available to any class that includes it, not just ActiveRecord models
74+
/** `GlobalID::Identification` */
75+
module Identification {
76+
/** A call to `GlobalID::Identification.to_global_id` */
77+
class ToGlobalIdCall extends ActiveRecordInstanceMethodCall {
78+
ToGlobalIdCall() { this.getMethodName() = ["to_global_id", "to_gid"] }
79+
}
80+
81+
/** A call to `GlobalID::Identification.to_gid_param` */
82+
class ToGidParamCall extends ActiveRecordInstanceMethodCall {
83+
ToGidParamCall() { this.getMethodName() = "to_gid_param" }
84+
}
85+
86+
/** A call to `GlobalID::Identification.to_signed_global_id` */
87+
class ToSignedGlobalIdCall extends ActiveRecordInstanceMethodCall {
88+
ToSignedGlobalIdCall() { this.getMethodName() = ["to_signed_global_id", "to_sgid"] }
89+
}
90+
91+
/** A call to `GlobalID::Identification.to_sgid_param` */
92+
class ToSgidParamCall extends ActiveRecordInstanceMethodCall {
93+
ToSgidParamCall() { this.getMethodName() = "to_sgid_param" }
94+
}
95+
}
96+
}
97+
98+
/** Provides modeling for `SignedGlobalID`, a module of the `rails/globalid` library. */
99+
module SignedGlobalId {
100+
/** A call to `SignedGlobalID::parse` */
101+
class ParseCall extends DataFlow::CallNode {
102+
ParseCall() { this = API::getTopLevelMember("SignedGlobalID").getAMethodCall("parse") }
103+
}
104+
105+
/** A call to `SignedGlobalID::find` */
106+
class FindCall extends DataFlow::CallNode, OrmInstantiation::Range {
107+
FindCall() { this = API::getTopLevelMember("SignedGlobalID").getAMethodCall("find") }
108+
109+
override predicate methodCallMayAccessField(string methodName) { none() }
110+
}
111+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
locateCalls
2+
| globalid.rb:6:3:6:30 | call to locate |
3+
| globalid.rb:11:3:11:30 | call to locate |
4+
locateSignedCalls
5+
| globalid.rb:16:3:16:38 | call to locate_signed |
6+
| globalid.rb:21:3:21:38 | call to locate_signed |
7+
toGlobalIdCalls
8+
| globalid.rb:5:9:5:33 | call to to_global_id |
9+
| globalid.rb:10:9:10:27 | call to to_gid |
10+
toGidParamCalls
11+
| globalid.rb:35:10:35:34 | call to to_gid_param |
12+
toSignedGlobalIdCalls
13+
| globalid.rb:15:10:15:41 | call to to_signed_global_id |
14+
| globalid.rb:20:10:20:29 | call to to_sgid |
15+
toSgidParamCalls
16+
| globalid.rb:41:11:41:36 | call to to_sgid_param |
17+
globalIdParseCalls
18+
| globalid.rb:36:9:36:27 | call to parse |
19+
globalIdFindCalls
20+
| globalid.rb:37:3:37:19 | call to find |
21+
signedGlobalIdParseCalls
22+
| globalid.rb:42:10:42:35 | call to parse |
23+
signedGlobalIdFindCalls
24+
| globalid.rb:43:3:43:26 | call to find |
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import codeql.ruby.frameworks.GlobalId
2+
3+
query predicate locateCalls(GlobalId::Locator::LocateCall c) { any() }
4+
5+
query predicate locateSignedCalls(GlobalId::Locator::LocateSignedCall c) { any() }
6+
7+
query predicate toGlobalIdCalls(GlobalId::Identification::ToGlobalIdCall c) { any() }
8+
9+
query predicate toGidParamCalls(GlobalId::Identification::ToGidParamCall c) { any() }
10+
11+
query predicate toSignedGlobalIdCalls(GlobalId::Identification::ToSignedGlobalIdCall c) { any() }
12+
13+
query predicate toSgidParamCalls(GlobalId::Identification::ToSgidParamCall c) { any() }
14+
15+
query predicate globalIdParseCalls(GlobalId::ParseCall c) { any() }
16+
17+
query predicate globalIdFindCalls(GlobalId::FindCall c) { any() }
18+
19+
query predicate signedGlobalIdParseCalls(SignedGlobalId::ParseCall c) { any() }
20+
21+
query predicate signedGlobalIdFindCalls(SignedGlobalId::FindCall c) { any() }
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
class User < ActiveRecord::Base
2+
end
3+
4+
def m1
5+
gid = User.find(1).to_global_id
6+
GlobalID::Locator.locate gid
7+
end
8+
9+
def m2
10+
gid = User.find(1).to_gid
11+
GlobalID::Locator.locate gid
12+
end
13+
14+
def m3
15+
sgid = User.find(1).to_signed_global_id
16+
GlobalID::Locator.locate_signed sgid
17+
end
18+
19+
def m4
20+
sgid = User.find(1).to_sgid
21+
GlobalID::Locator.locate_signed sgid
22+
end
23+
24+
def m5
25+
gids = User.all.map(&:to_gid)
26+
GlobalID::Locator.locate_many gids
27+
end
28+
29+
def m6
30+
sgids = User.all.map(&:to_sgid)
31+
GlobalID::Locator.locate_many_signed sgids
32+
end
33+
34+
def m7
35+
gidp = User.find(1).to_gid_param
36+
gid = GlobalID.parse gidp
37+
GlobalID.find gid
38+
end
39+
40+
def m8
41+
sgidp = User.find(1).to_sgid_param
42+
sgid = SignedGlobalID.parse sgidp
43+
SignedGlobalID.find sgid
44+
end

0 commit comments

Comments
 (0)