Skip to content

Commit f645ecc

Browse files
committed
Rename normalizeSemVer to padSemVer and adopt Ruby implementation
1 parent 9207c4b commit f645ecc

5 files changed

Lines changed: 59 additions & 66 deletions

File tree

go/ql/lib/semmle/go/dependencies/SemVer.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,35 @@ class DependencySemVer extends string {
1818

1919
DependencySemVer() {
2020
this = dep.getDepVersion() and
21-
normalized = normalizeSemVer(this)
21+
normalized = padSemVer(this)
2222
}
2323

2424
/**
2525
* Holds if this version may be before `last`.
2626
*/
2727
bindingset[last]
28-
predicate maybeBefore(string last) { normalized < normalizeSemVer(last) }
28+
predicate maybeBefore(string last) { normalized < padSemVer(last) }
2929

3030
/**
3131
* Holds if this version may be after `first`.
3232
*/
3333
bindingset[first]
34-
predicate maybeAfter(string first) { normalizeSemVer(first) < normalized }
34+
predicate maybeAfter(string first) { padSemVer(first) < normalized }
3535

3636
/**
3737
* Holds if this version may be between `first` (inclusive) and `last` (exclusive).
3838
*/
3939
bindingset[first, last]
4040
predicate maybeBetween(string first, string last) {
41-
normalizeSemVer(first) <= normalized and
42-
normalized < normalizeSemVer(last)
41+
padSemVer(first) <= normalized and
42+
normalized < padSemVer(last)
4343
}
4444

4545
/**
4646
* Holds if this version is equivalent to `other`.
4747
*/
4848
bindingset[other]
49-
predicate is(string other) { normalized = normalizeSemVer(other) }
49+
predicate is(string other) { normalized = padSemVer(other) }
5050

5151
/**
5252
* Gets the dependency that uses this string.

javascript/ql/lib/semmle/javascript/dependencies/SemVer.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,35 @@ class DependencySemVer extends string {
1616

1717
DependencySemVer() {
1818
dep.info(_, this) and
19-
normalized = normalizeSemVer(this)
19+
normalized = padSemVer(this)
2020
}
2121

2222
/**
2323
* Holds if this version may be before `last`.
2424
*/
2525
bindingset[last]
26-
predicate maybeBefore(string last) { normalized < normalizeSemVer(last) }
26+
predicate maybeBefore(string last) { normalized < padSemVer(last) }
2727

2828
/**
2929
* Holds if this version may be after `first`.
3030
*/
3131
bindingset[first]
32-
predicate maybeAfter(string first) { normalizeSemVer(first) < normalized }
32+
predicate maybeAfter(string first) { padSemVer(first) < normalized }
3333

3434
/**
3535
* Holds if this version may be between `first` (inclusive) and `last` (exclusive).
3636
*/
3737
bindingset[first, last]
3838
predicate maybeBetween(string first, string last) {
39-
normalizeSemVer(first) <= normalized and
40-
normalized < normalizeSemVer(last)
39+
padSemVer(first) <= normalized and
40+
normalized < padSemVer(last)
4141
}
4242

4343
/**
4444
* Holds if this version is equivalent to `other`.
4545
*/
4646
bindingset[other]
47-
predicate is(string other) { normalized = normalizeSemVer(other) }
47+
predicate is(string other) { normalized = padSemVer(other) }
4848

4949
/**
5050
* Gets the dependency that uses this string.

ruby/ql/lib/codeql/ruby/frameworks/Gemfile.qll

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
private import codeql.ruby.AST
6+
private import codeql.util.SemVer
67

78
/**
89
* Provides classes and predicates for Gemfiles, including version constraint logic.
@@ -138,7 +139,7 @@ module Gemfile {
138139
exists(int thisMajor, int thisMinor, int otherMajor, int otherMinor |
139140
thisMajor = this.getVersion().getMajor() and
140141
thisMinor = this.getVersion().getMinor() and
141-
exists(string maj, string mi | normalizeSemver(other, _, maj, mi, _) |
142+
exists(string maj, string mi | exists(padSemVer(other, maj, mi, _)) |
142143
otherMajor = maj.toInt() and otherMinor = mi.toInt()
143144
)
144145
|
@@ -171,26 +172,26 @@ module Gemfile {
171172

172173
Version() {
173174
this = any(Gem c).getAVersionConstraint().getVersionString() and
174-
normalized = normalizeSemver(this)
175+
normalized = padSemVer(this)
175176
}
176177

177178
/**
178179
* Holds if this version is strictly before the version defined by `other`.
179180
*/
180181
bindingset[other]
181-
predicate before(string other) { normalized < normalizeSemver(other) }
182+
predicate before(string other) { normalized < padSemVer(other) }
182183

183184
/**
184185
* Holds if this versino is equal to the version defined by `other`.
185186
*/
186187
bindingset[other]
187-
predicate equal(string other) { normalized = normalizeSemver(other) }
188+
predicate equal(string other) { normalized = padSemVer(other) }
188189

189190
/**
190191
* Holds if this version is strictly after the version defined by `other`.
191192
*/
192193
bindingset[other]
193-
predicate after(string other) { normalized > normalizeSemver(other) }
194+
predicate after(string other) { normalized > padSemVer(other) }
194195

195196
/**
196197
* Holds if this version defines a patch number.
@@ -212,43 +213,4 @@ module Gemfile {
212213
*/
213214
int getPatch() { result = getPatch(normalized).toInt() }
214215
}
215-
216-
/**
217-
* Normalizes a SemVer string such that the lexicographical ordering
218-
* of two normalized strings is consistent with the SemVer ordering.
219-
*
220-
* Pre-release information and build metadata is not supported.
221-
*/
222-
bindingset[orig]
223-
private predicate normalizeSemver(
224-
string orig, string normalized, string major, string minor, string patch
225-
) {
226-
major = getMajor(orig) and
227-
(
228-
minor = getMinor(orig)
229-
or
230-
not exists(getMinor(orig)) and minor = "0"
231-
) and
232-
(
233-
patch = getPatch(orig)
234-
or
235-
not exists(getPatch(orig)) and patch = "0"
236-
) and
237-
normalized = leftPad(major) + "." + leftPad(minor) + "." + leftPad(patch)
238-
}
239-
240-
bindingset[orig]
241-
private string normalizeSemver(string orig) { normalizeSemver(orig, result, _, _, _) }
242-
243-
bindingset[s]
244-
private string getMajor(string s) { result = s.regexpCapture("(\\d+).*", 1) }
245-
246-
bindingset[s]
247-
private string getMinor(string s) { result = s.regexpCapture("(\\d+)\\.(\\d+).*", 2) }
248-
249-
bindingset[s]
250-
private string getPatch(string s) { result = s.regexpCapture("(\\d+)\\.(\\d+)\\.(\\d+).*", 3) }
251-
252-
bindingset[str]
253-
private string leftPad(string str) { result = ("000" + str).suffix(str.length()) }
254216
}

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ class CrateItemNode extends NamedItemNode instanceof Crate {
573573
predicate isLatestVersion(string name) {
574574
this =
575575
max(CrateItemNode c, string ver |
576-
name = c.getName() and ver = normalizeSemVer(c.(Crate).getVersion())
576+
name = c.getName() and ver = padSemVer(c.(Crate).getVersion())
577577
|
578578
c order by ver
579579
)

shared/util/codeql/util/SemVer.qll

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,51 @@ module;
77
bindingset[str]
88
private string leftPad(string str) { result = ("0000" + str).suffix(str.length()) }
99

10+
/**
11+
* Gets the major number of a SemVer string.
12+
*/
13+
bindingset[s]
14+
string getMajor(string s) { result = s.regexpCapture("(\\d+).*", 1) }
15+
16+
/**
17+
* Gets the minor number of a SemVer string.
18+
*/
19+
bindingset[s]
20+
string getMinor(string s) { result = s.regexpCapture("(\\d+)\\.(\\d+).*", 2) }
21+
22+
/**
23+
* Gets the patch number of a SemVer string.
24+
*/
25+
bindingset[s]
26+
string getPatch(string s) { result = s.regexpCapture("(\\d+)\\.(\\d+)\\.(\\d+).*", 3) }
27+
1028
/**
1129
* Normalizes a SemVer string such that the lexicographical ordering
1230
* of two normalized strings is consistent with the SemVer ordering.
1331
*
1432
* Pre-release information and build metadata is not yet supported.
1533
*/
1634
bindingset[orig]
17-
string normalizeSemVer(string orig) {
18-
exists(string pattern, string major, string minor, string patch |
19-
pattern = "v?(\\d+)\\.(\\d+)\\.(\\d+)(\\D.*)?" and
20-
major = orig.regexpCapture(pattern, 1) and
21-
minor = orig.regexpCapture(pattern, 2) and
22-
patch = orig.regexpCapture(pattern, 3)
23-
|
24-
result = leftPad(major) + "." + leftPad(minor) + "." + leftPad(patch)
25-
)
35+
string padSemVer(string orig, string major, string minor, string patch) {
36+
major = getMajor(orig) and
37+
(
38+
minor = getMinor(orig)
39+
or
40+
not exists(getMinor(orig)) and minor = "0"
41+
) and
42+
(
43+
patch = getPatch(orig)
44+
or
45+
not exists(getPatch(orig)) and patch = "0"
46+
) and
47+
result = leftPad(major) + "." + leftPad(minor) + "." + leftPad(patch)
2648
}
49+
50+
/**
51+
* Normalizes a SemVer string such that the lexicographical ordering
52+
* of two normalized strings is consistent with the SemVer ordering.
53+
*
54+
* Pre-release information and build metadata is not yet supported.
55+
*/
56+
bindingset[orig]
57+
string padSemVer(string orig) { result = padSemVer(orig, _, _, _) }

0 commit comments

Comments
 (0)