diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 69ace0d4d..9e3418034 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,7 @@ + Make logic for comparing OS versions in SystemUtils smarter Shutdown thread pools in test cases FastDateParser and FastDatePrinter support 'X' format Avoid memory allocation when using date formating to StringBuffer diff --git a/src/main/java/org/apache/commons/lang3/SystemUtils.java b/src/main/java/org/apache/commons/lang3/SystemUtils.java index 6508ddcbf..ba99a4ae0 100644 --- a/src/main/java/org/apache/commons/lang3/SystemUtils.java +++ b/src/main/java/org/apache/commons/lang3/SystemUtils.java @@ -1448,7 +1448,7 @@ static boolean isOSMatch(final String osName, final String osVersion, final Stri if (osName == null || osVersion == null) { return false; } - return isOSNameMatch(osName, osNamePrefix) && osVersion.startsWith(osVersionPrefix); + return isOSNameMatch(osName, osNamePrefix) && isOSVersionMatch(osVersion, osVersionPrefix); } /** @@ -1467,6 +1467,32 @@ static boolean isOSNameMatch(final String osName, final String osNamePrefix) { } return osName.startsWith(osNamePrefix); } + + /** + * Decides if the operating system version matches. + *

+ * This method is package private instead of private to support unit test invocation. + *

+ * + * @param osVersion the actual OS version + * @param osVersionPrefix the prefix for the expected OS version + * @return true if matches, or false if not or can't determine + */ + static boolean isOSVersionMatch(final String osVersion, final String osVersionPrefix) { + if (StringUtils.isEmpty(osVersion)) { + return false; + } + // Compare parts of the version string instead of using String.startsWith(String) because otherwise + // osVersionPrefix 10.1 would also match osVersion 10.10 + String[] versionPrefixParts = osVersionPrefix.split("\\."); + String[] versionParts = osVersion.split("\\."); + for (int i = 0; i < Math.min(versionPrefixParts.length, versionParts.length); i++) { + if (!versionPrefixParts[i].equals(versionParts[i])) { + return false; + } + } + return true; + } // ----------------------------------------------------------------------- /** diff --git a/src/test/java/org/apache/commons/lang3/SystemUtilsTest.java b/src/test/java/org/apache/commons/lang3/SystemUtilsTest.java index 1d6d262f0..fa474d1cb 100644 --- a/src/test/java/org/apache/commons/lang3/SystemUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/SystemUtilsTest.java @@ -377,6 +377,45 @@ public void testOSMatchesNameAndVersion() { assertFalse(SystemUtils.isOSMatch(osName, osVersion, "Windows 9", "4.1")); } + @Test + public void testOsVersionMatches() throws Exception { + String osVersion = null; + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + + osVersion = ""; + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + + osVersion = "10"; + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.1.1")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.10")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.10.1")); + + osVersion = "10.1"; + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.1.1")); + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.10")); + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.10.1")); + + osVersion = "10.1.1"; + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.1.1")); + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.10")); + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.10.1")); + + osVersion = "10.10"; + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.1.1")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.10")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.10.1")); + + osVersion = "10.10.1"; + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.1")); + assertFalse(SystemUtils.isOSVersionMatch(osVersion, "10.1.1")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.10")); + assertTrue(SystemUtils.isOSVersionMatch(osVersion, "10.10.1")); + } + @Test public void testJavaAwtHeadless() { final boolean atLeastJava14 = SystemUtils.isJavaVersionAtLeast(JAVA_1_4);