From 88cfc5794ed5ffd8abf3929303a4444725caa0af Mon Sep 17 00:00:00 2001 From: Jinwoo Hwang Date: Fri, 9 Jan 2026 15:36:00 -0500 Subject: [PATCH] GEODE-10546: Address CVE-2025-48924 in Apache Commons Lang3 - Upgrade commons-lang3 from 3.12.0 to 3.18.0 - Replace StringUtils.startsWith with String.startsWith (with null check) - Replace StringUtils.containsIgnoreCase with toLowerCase().contains() - Replace StringUtils.removeStart with ternary operator pattern - Replace StringUtils.equals with Objects.equals - Replace LineIterator.nextLine() with LineIterator.next() - Fix Mockito compatibility with MutableInt in commons-lang3 3.18.0 - All quality checks pass (japicmp, javadoc, spotlessCheck, rat, checkPom, pmdMain) - ConnectCommandTest: 24 tests now pass (fixed NullPointerException) --- .../geode/gradle/plugins/DependencyConstraints.groovy | 2 +- .../cli/commands/StartServerCommandAcceptanceTest.java | 4 ++-- .../internal/cache/tier/sockets/ServerConnectionTest.java | 2 +- .../management/internal/cli/commands/ConnectCommand.java | 2 +- .../internal/cli/commands/CreateIndexCommand.java | 4 ++-- .../management/internal/cli/commands/QueryCommand.java | 4 ++-- .../internal/cli/domain/FixedPartitionAttributesInfo.java | 5 ++--- .../internal/cli/domain/PartitionAttributesInfo.java | 7 +++---- .../internal/cli/domain/RegionAttributesInfo.java | 3 ++- .../org/apache/geode/management/configuration/Index.java | 3 ++- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy b/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy index 61c7141d6926..ede698942bbe 100644 --- a/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy +++ b/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy @@ -34,7 +34,7 @@ class DependencyConstraints { // Some of these are referenced below as well deps.put("antlr.version", "2.7.7") deps.put("commons-io.version", "2.15.1") - deps.put("commons-lang3.version", "3.12.0") + deps.put("commons-lang3.version", "3.18.0") deps.put("commons-validator.version", "1.7") deps.put("fastutil.version", "8.5.8") deps.put("javax.transaction-api.version", "1.3") diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java index fb9a665bcf88..828655420a32 100644 --- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java +++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java @@ -103,7 +103,7 @@ public void parametersOverrideCacheXml() throws IOException { Boolean configurationLineFound = Boolean.FALSE; LineIterator lineIterator = FileUtils.lineIterator(logFile.toFile()); while (lineIterator.hasNext()) { - String line = lineIterator.nextLine(); + String line = lineIterator.next(); if (line.contains("CacheServer Configuration:")) { configurationLineFound = Boolean.TRUE; assertThat(line).contains("max-threads=100"); @@ -152,7 +152,7 @@ public void usesClusterConfigurationIfEnabled() throws IOException { boolean configurationLineFound = false; LineIterator lineIterator = FileUtils.lineIterator(logFile.toFile()); while (lineIterator.hasNext()) { - String line = lineIterator.nextLine(); + String line = lineIterator.next(); if (line.contains("CacheServer Configuration:")) { configurationLineFound = true; assertThat(line).contains("max-threads=50"); diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java index e32a031a3cdf..8dadc5d4815a 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java @@ -307,7 +307,7 @@ public void handleTerminationWithUnregisterClientShouldNullClientAuths() { ClientUserAuths clientUserAuths = mock(ClientUserAuths.class); ServerConnection spy = spy(serverConnection); Map cleanupTable = mock(Map.class); - when(cleanupTable.get(any())).thenReturn(mock(MutableInt.class)); + when(cleanupTable.get(any())).thenReturn(new MutableInt(0)); doReturn(cleanupTable).when(clientHealthMonitor).getCleanupTable(); doReturn(new HashMap<>()).when(clientHealthMonitor).getCleanupProxyIdTable(); spy.setClientUserAuths(clientUserAuths); diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java index 27ed6e465aa3..8a13f9f6657a 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java @@ -123,7 +123,7 @@ public ResultModel connect( .createInfo("Already connected to: " + getGfsh().getOperationInvoker().toString()); } - if (StringUtils.startsWith(url, "https")) { + if (url != null && url.startsWith("https")) { useSsl = true; } diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java index d1f4f1892afa..4a0b1c499eef 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; @@ -169,7 +168,8 @@ public ResultModel createIndex(@CliOption(key = CliStrings.CREATE_INDEX__NAME, m // returned here should not have "." String getValidRegionName(String regionPath) { String regionName = regionPath.trim().split(" ")[0]; - regionName = StringUtils.removeStart(regionName, SEPARATOR); + regionName = + regionName.startsWith(SEPARATOR) ? regionName.substring(SEPARATOR.length()) : regionName; if (regionName.contains(".")) { regionName = regionName.substring(0, regionName.indexOf('.')); } diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/QueryCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/QueryCommand.java index ccd7d3c833e6..da610a5d8768 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/QueryCommand.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/QueryCommand.java @@ -84,8 +84,8 @@ DataCommandResult select(String query, DistributedMember targetMember) { boolean limitAdded = false; - if (!StringUtils.containsIgnoreCase(query, " limit") - && !StringUtils.containsIgnoreCase(query, " count(")) { + if (!query.toLowerCase().contains(" limit") + && !query.toLowerCase().contains(" count(")) { query = query + " limit " + CommandExecutionContext.getShellFetchSize(); limitAdded = true; } diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/FixedPartitionAttributesInfo.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/FixedPartitionAttributesInfo.java index 06061bacfc2e..6bf349349e8d 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/FixedPartitionAttributesInfo.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/FixedPartitionAttributesInfo.java @@ -15,8 +15,7 @@ package org.apache.geode.management.internal.cli.domain; import java.io.Serializable; - -import org.apache.commons.lang3.StringUtils; +import java.util.Objects; import org.apache.geode.cache.FixedPartitionAttributes; @@ -37,7 +36,7 @@ public boolean equals(Object obj) { if (obj instanceof FixedPartitionAttributesInfo) { FixedPartitionAttributesInfo fpaInfo = (FixedPartitionAttributesInfo) obj; return numBuckets == fpaInfo.getNumBuckets() - && StringUtils.equals(partitionName, fpaInfo.getPartitionName()) + && Objects.equals(partitionName, fpaInfo.getPartitionName()) && isPrimary == fpaInfo.isPrimary(); } else { diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionAttributesInfo.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionAttributesInfo.java index c2bcfe7f6981..c17f50f519ed 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionAttributesInfo.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/PartitionAttributesInfo.java @@ -20,8 +20,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; - -import org.apache.commons.lang3.StringUtils; +import java.util.Objects; import org.apache.geode.cache.FixedPartitionAttributes; import org.apache.geode.cache.PartitionAttributes; @@ -152,9 +151,9 @@ public List getFixedPartitionAttributesInfo() { public boolean equals(Object obj) { if (obj instanceof PartitionAttributesInfo) { PartitionAttributesInfo paInfo = (PartitionAttributesInfo) obj; - return StringUtils.equals(getColocatedWith(), paInfo.getColocatedWith()) + return Objects.equals(getColocatedWith(), paInfo.getColocatedWith()) && getLocalMaxMemory() == paInfo.getLocalMaxMemory() - && StringUtils.equals(getPartitionResolverName(), paInfo.getPartitionResolverName()) + && Objects.equals(getPartitionResolverName(), paInfo.getPartitionResolverName()) && getRecoveryDelay() == paInfo.getRecoveryDelay() && getRedundantCopies() == paInfo.getRedundantCopies() && getStartupRecoveryDelay() == paInfo.getStartupRecoveryDelay() diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributesInfo.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributesInfo.java index 6adf2ecaeaf6..05d77c238c6d 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributesInfo.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/RegionAttributesInfo.java @@ -21,6 +21,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import org.apache.commons.lang3.StringUtils; @@ -364,7 +365,7 @@ public Map getNonDefaultAttributes() { Boolean.toString(cloningEnabled)); } - if (!StringUtils.equals(RegionAttributesDefault.COMPRESSOR_CLASS_NAME, compressorClassName)) { + if (!Objects.equals(RegionAttributesDefault.COMPRESSOR_CLASS_NAME, compressorClassName)) { nonDefaultAttributes.put(RegionAttributesNames.COMPRESSOR, compressorClassName); } diff --git a/geode-management/src/main/java/org/apache/geode/management/configuration/Index.java b/geode-management/src/main/java/org/apache/geode/management/configuration/Index.java index 2e1c684916fd..03372f916863 100644 --- a/geode-management/src/main/java/org/apache/geode/management/configuration/Index.java +++ b/geode-management/src/main/java/org/apache/geode/management/configuration/Index.java @@ -88,7 +88,8 @@ public String getRegionName() { } String regionName = regionPath.trim().split(" ")[0]; - regionName = StringUtils.removeStart(regionName, SEPARATOR); + regionName = + regionName.startsWith(SEPARATOR) ? regionName.substring(SEPARATOR.length()) : regionName; if (regionName.contains(".")) { regionName = regionName.substring(0, regionName.indexOf('.')); }