Skip to content

Commit ad60834

Browse files
committed
Ruby: Handle alternative gemspec names
Gemspecs are sometimes named via the first argument to `Gem::Specification.new`: ```rb Gem::Specification.new 'sinatra' do |s| # ... end ```
1 parent 9b998a3 commit ad60834

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

ruby/ql/lib/codeql/ruby/frameworks/core/Gem.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ module Gem {
5757
}
5858

5959
/** Gets the name of the gem */
60-
string getName() { result = this.getSpecProperty("name").getConstantValue().getString() }
60+
string getName() {
61+
result = this.getSpecProperty("name").getConstantValue().getString() or
62+
result = specCall.getArgument(0).getAValueReachingSink().getConstantValue().getString()
63+
}
6164

6265
/** Gets a path that is loaded when the gem is required */
6366
private string getARequirePath() {

ruby/ql/src/utils/modeleditor/ModelEditor.qll

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ private predicate isUninteresting(DataFlow::MethodNode c) {
1515
c.getLocation().getFile() instanceof TestFile
1616
}
1717

18-
private predicate fileStep(Folder folder, File file, int n) {
19-
n = 0 and folder.getAFile() = file
18+
private predicate gemFileStep(Gem::GemSpec gem, Folder folder, int n) {
19+
n = 0 and folder.getAFile() = gem.(File)
2020
or
21-
exists(int m | fileStep(folder.getAFolder(), file, m) | n = m + 1)
22-
}
23-
24-
private predicate gemFileStep(Gem::GemSpec gem, File file, int n) {
25-
fileStep(any(Folder f | f.getAFile() = gem.(File)), file, n)
21+
exists(Folder parent, int m |
22+
gemFileStep(gem, parent, m) and
23+
parent.getAFolder() = folder and
24+
n = m + 1
25+
)
2626
}
2727

2828
/**
@@ -40,11 +40,13 @@ class Endpoint extends DataFlow::MethodNode {
4040
*/
4141
bindingset[this]
4242
string getNamespace() {
43-
// The nearest gemspec to this endpoint, if one exists
44-
result = min(Gem::GemSpec g, int n | gemFileStep(g, this.getFile(), n) | g order by n).getName()
45-
or
46-
not exists(Gem::GemSpec g) and
47-
result = ""
43+
exists(Folder folder | folder = this.getFile().getParentContainer() |
44+
// The nearest gemspec to this endpoint, if one exists
45+
result = min(Gem::GemSpec g, int n | gemFileStep(g, folder, n) | g order by n).getName()
46+
or
47+
not exists(Gem::GemSpec g | gemFileStep(g, folder, _)) and
48+
result = ""
49+
)
4850
}
4951

5052
/**

0 commit comments

Comments
 (0)