Skip to content

Commit 4da4b78

Browse files
fix: Semantic version fix and multiple plus signs check added (#394)
* Semantic version fix and multiple plus signs check added * renamed buildMetacount function to isValidBuildMetadata Co-authored-by: FOLIO3PK\muhammadnoman <muhammadnoman@folio3.com>
1 parent d3dd94d commit 4da4b78

File tree

2 files changed

+85
-8
lines changed

2 files changed

+85
-8
lines changed

core-api/src/main/java/com/optimizely/ab/config/audience/match/SemanticVersion.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
public final class SemanticVersion {
2727

28-
private static final String BUILD_SEPERATOR = "+";
28+
private static final String BUILD_SEPERATOR = "\\+";
2929
private static final String PRE_RELEASE_SEPERATOR = "-";
3030

3131
private final String version;
@@ -54,8 +54,10 @@ public int compare(SemanticVersion targetedVersion) throws Exception {
5454
if (userVersionPartInt == null) {
5555
// Compare strings
5656
int result = userVersionParts[index].compareTo(targetedVersionParts[index]);
57-
if (result != 0) {
58-
return result;
57+
if (result < 0) {
58+
return targetedVersion.isPreRelease() && !isPreRelease() ? 1 : -1;
59+
} else if (result > 0) {
60+
return !targetedVersion.isPreRelease() && isPreRelease() ? -1 : 1;
5961
}
6062
} else if (targetVersionPartInt != null) {
6163
if (!userVersionPartInt.equals(targetVersionPartInt)) {
@@ -75,11 +77,25 @@ public int compare(SemanticVersion targetedVersion) throws Exception {
7577
}
7678

7779
public boolean isPreRelease() {
78-
return version.contains(PRE_RELEASE_SEPERATOR);
80+
int buildIndex = version.indexOf("+");
81+
int preReleaseIndex = version.indexOf("-");
82+
if (buildIndex < 0) {
83+
return preReleaseIndex > 0;
84+
} else if(preReleaseIndex < 0) {
85+
return false;
86+
}
87+
return preReleaseIndex < buildIndex;
7988
}
8089

8190
public boolean isBuild() {
82-
return version.contains(BUILD_SEPERATOR);
91+
int buildIndex = version.indexOf("+");
92+
int preReleaseIndex = version.indexOf("-");
93+
if (preReleaseIndex < 0) {
94+
return buildIndex > 0;
95+
} else if(buildIndex < 0) {
96+
return false;
97+
}
98+
return buildIndex < preReleaseIndex;
8399
}
84100

85101
private int dotCount(String prefixVersion) {
@@ -93,6 +109,17 @@ private int dotCount(String prefixVersion) {
93109
return count;
94110
}
95111

112+
private boolean isValidBuildMetadata() {
113+
char[] vCharArray = version.toCharArray();
114+
int count = 0;
115+
for (char c : vCharArray) {
116+
if (c == '+') {
117+
count++;
118+
}
119+
}
120+
return count > 1;
121+
}
122+
96123
public String[] splitSemanticVersion() throws Exception {
97124
List<String> versionParts = new ArrayList<>();
98125
String versionPrefix = "";
@@ -102,13 +129,13 @@ public String[] splitSemanticVersion() throws Exception {
102129
String[] preVersionParts;
103130

104131
// Contains white spaces
105-
if (version.contains(" ")) { // log and throw error
106-
throw new Exception("Semantic version contains white spaces. Invalid Semantic Version.");
132+
if (version.contains(" ") || isValidBuildMetadata()) { // log and throw error
133+
throw new Exception("Invalid Semantic Version.");
107134
}
108135

109136
if (isBuild() || isPreRelease()) {
110137
String[] partialVersionParts = version.split(isPreRelease() ?
111-
PRE_RELEASE_SEPERATOR : BUILD_SEPERATOR);
138+
PRE_RELEASE_SEPERATOR : BUILD_SEPERATOR, 2);
112139

113140
if (partialVersionParts.length <= 1) {
114141
// throw error

core-api/src/test/java/com/optimizely/ab/config/audience/SemanticVersionTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ public void semanticVersionInvalidDoubleDot() throws Exception {
4949
semanticVersion.splitSemanticVersion();
5050
}
5151

52+
@Test
53+
public void semanticVersionInvalidMultipleBuild() throws Exception {
54+
thrown.expect(Exception.class);
55+
SemanticVersion semanticVersion = new SemanticVersion("3.1.2-2+2.3+1");
56+
semanticVersion.splitSemanticVersion();
57+
}
58+
5259
@Test
5360
public void semanticVersionInvalidPlus() throws Exception {
5461
thrown.expect(Exception.class);
@@ -175,13 +182,56 @@ public void semanticVersionCompareToActualPreReleaseMissing() throws Exception {
175182
assertTrue(actualSV.compare(targetSV) > 0);
176183
}
177184

185+
@Test
186+
public void semanticVersionCompareTargetBetaComplex() throws Exception {
187+
SemanticVersion targetSV = new SemanticVersion("2.1.3-beta+1");
188+
SemanticVersion actualSV = new SemanticVersion("2.1.3-beta+1.2.3");
189+
assertTrue(actualSV.compare(targetSV) > 0);
190+
}
191+
192+
@Test
193+
public void semanticVersionCompareTargetBuildIgnores() throws Exception {
194+
SemanticVersion targetSV = new SemanticVersion("2.1.3");
195+
SemanticVersion actualSV = new SemanticVersion("2.1.3+build");
196+
assertTrue(actualSV.compare(targetSV) == 0);
197+
}
198+
199+
@Test
200+
public void semanticVersionCompareTargetBuildComplex() throws Exception {
201+
SemanticVersion targetSV = new SemanticVersion("2.1.3-beta+1.2.3");
202+
SemanticVersion actualSV = new SemanticVersion("2.1.3-beta+1");
203+
assertTrue(actualSV.compare(targetSV) < 0);
204+
}
205+
206+
@Test
207+
public void semanticVersionCompareMultipleDash() throws Exception {
208+
SemanticVersion targetSV = new SemanticVersion("2.1.3-beta-1.2.3");
209+
SemanticVersion actualSV = new SemanticVersion("2.1.3-beta-1");
210+
assertTrue(actualSV.compare(targetSV) < 0);
211+
}
212+
178213
@Test
179214
public void semanticVersionCompareToAlphaBetaAsciiComparision() throws Exception {
180215
SemanticVersion targetSV = new SemanticVersion("3.7.1-alpha");
181216
SemanticVersion actualSV = new SemanticVersion("3.7.1-beta");
182217
assertTrue(actualSV.compare(targetSV) > 0);
183218
}
184219

220+
@Test
221+
public void semanticVersionComparePrereleaseSmallerThanBuild() throws Exception {
222+
SemanticVersion targetSV = new SemanticVersion("3.7.1-prerelease");
223+
SemanticVersion actualSV = new SemanticVersion("3.7.1+build");
224+
assertTrue(actualSV.compare(targetSV) > 0);
225+
}
226+
227+
228+
@Test
229+
public void semanticVersionCompareAgainstPreReleaseToPreRelease() throws Exception {
230+
SemanticVersion targetSV = new SemanticVersion("3.7.1-prerelease+build");
231+
SemanticVersion actualSV = new SemanticVersion("3.7.1-prerelease-prerelease+rc");
232+
assertTrue(actualSV.compare(targetSV) > 0);
233+
}
234+
185235
@Test
186236
public void semanticVersionCompareToIgnoreMetaComparision() throws Exception {
187237
SemanticVersion targetSV = new SemanticVersion("3.7.1-beta.1+2.3");

0 commit comments

Comments
 (0)