From fb69372ed56a6f5f8950a632e44fe979779ec1ad Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Tue, 18 Nov 2025 13:27:14 +0200 Subject: [PATCH] Remove commons-text dependency (#2817) And thus fix vulnerability that it brings. Also decrease dependencies. Signed-off-by: Avgustin Marinov --- .../artifact/fs/FileArtifactStorageTest.java | 2 +- hawkbit-repository/hawkbit-repository-api/pom.xml | 4 ---- .../repository/rsql/VirtualPropertyResolver.java | 13 +++++-------- .../ql/rsql/VirtualPropertyResolverTest.java | 5 ++--- .../jpa/scheduler/AutoAssignExecutorIntTest.java | 3 +-- .../test/util/AbstractIntegrationTest.java | 3 +-- .../repository/test/util/TestdataFactory.java | 13 ++++++++++--- pom.xml | 6 ------ 8 files changed, 20 insertions(+), 29 deletions(-) diff --git a/hawkbit-artifact/hawkbit-artifact-fs/src/test/java/org/eclipse/hawkbit/artifact/fs/FileArtifactStorageTest.java b/hawkbit-artifact/hawkbit-artifact-fs/src/test/java/org/eclipse/hawkbit/artifact/fs/FileArtifactStorageTest.java index 9bb940f14..ec06dbc31 100644 --- a/hawkbit-artifact/hawkbit-artifact-fs/src/test/java/org/eclipse/hawkbit/artifact/fs/FileArtifactStorageTest.java +++ b/hawkbit-artifact/hawkbit-artifact-fs/src/test/java/org/eclipse/hawkbit/artifact/fs/FileArtifactStorageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; class FileArtifactStorageTest { private static final String TENANT = "test_tenant"; - @SuppressWarnings("java:S1068") // used for tests only, no need of secure random + @SuppressWarnings("java:S2245") // used for tests only, no need of secure random private static final Random RND = new Random(); private static FileArtifactProperties artifactResourceProperties; diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index 17d66280b..0e3b67592 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -51,10 +51,6 @@ com.cronutils cron-utils - - org.apache.commons - commons-text - org.jsoup jsoup diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java index 233b16ced..9207b2f02 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java @@ -14,12 +14,11 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope import java.time.Duration; -import org.apache.commons.text.StringSubstitutor; -import org.apache.commons.text.lookup.StringLookupFactory; import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.PollingTime; +import org.springframework.util.PropertyPlaceholderHelper; /** * Adds macro capabilities to RSQL expressions that are used to filter for targets. @@ -41,12 +40,10 @@ import org.eclipse.hawkbit.tenancy.configuration.PollingTime; */ public class VirtualPropertyResolver { - private static final StringSubstitutor STRING_SUBSTITUTOR = new StringSubstitutor( - StringLookupFactory.builder().get().functionStringLookup(VirtualPropertyResolver::lookup), - StringSubstitutor.DEFAULT_PREFIX, StringSubstitutor.DEFAULT_SUFFIX, StringSubstitutor.DEFAULT_ESCAPE); + private static final PropertyPlaceholderHelper HELPER = new PropertyPlaceholderHelper("${", "}", null, '$', true); public String replace(final String input) { - return STRING_SUBSTITUTOR.replace(input); + return HELPER.replacePlaceholders(input, VirtualPropertyResolver::lookup); } private static String lookup(final String rhs) { @@ -78,8 +75,8 @@ public class VirtualPropertyResolver { private static long calculateOverdueTimestamp(final PollingTime.PollingInterval pollingInterval, final Duration pollingOverdueTime) { return System.currentTimeMillis() - (pollingInterval.getDeviationPercent() == 0 - ? pollingInterval.getInterval().toMillis() - : pollingInterval.getInterval().toMillis() * (100 + pollingInterval.getDeviationPercent()) / 100) + ? pollingInterval.getInterval().toMillis() + : pollingInterval.getInterval().toMillis() * (100 + pollingInterval.getDeviationPercent()) / 100) - pollingOverdueTime.toMillis(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java index 77ac63ed0..15b89166b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java @@ -14,7 +14,6 @@ import static org.mockito.Mockito.when; import java.util.concurrent.Callable; -import org.apache.commons.text.StringSubstitutor; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.helper.TenantConfigurationManagementHolder; @@ -33,11 +32,11 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) /** * Feature: Unit Tests - Repository
* Story: Placeholder resolution for virtual properties */ +@ExtendWith(SpringExtension.class) class VirtualPropertyResolverTest { private static final TenantConfigurationValue TEST_POLLING_TIME_INTERVAL = @@ -78,7 +77,7 @@ class VirtualPropertyResolverTest { @Test void handleEscapedPlaceholder() { final String placeholder = "${OVERDUE_TS}"; - final String escapedPlaceholder = StringSubstitutor.DEFAULT_ESCAPE + placeholder; + final String escapedPlaceholder = "$" + placeholder; final String testString = "lhs=lt=" + escapedPlaceholder; final String resolvedPlaceholders = substitutor.replace(testString); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignExecutorIntTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignExecutorIntTest.java index 97e0acc20..5f9abd12e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignExecutorIntTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignExecutorIntTest.java @@ -144,8 +144,7 @@ class AutoAssignExecutorIntTest extends AbstractJpaIntegrationTest { verifyThatTargetsHaveDistributionSetAssignment(setB, targets.subList(10, 20), targetsCount); // Count the number of targets that will be assigned with setA - assertThat(targetManagement.countByRsqlAndNonDsAndCompatibleAndUpdatable(setA.getId(), targetFilterQuery.getQuery())) - .isEqualTo(15); + assertThat(targetManagement.countByRsqlAndNonDsAndCompatibleAndUpdatable(setA.getId(), targetFilterQuery.getQuery())).isEqualTo(15); // Run the check autoAssignChecker.checkAllTargets(); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 796ceb31c..8914c94cb 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -125,8 +125,7 @@ public abstract class AbstractIntegrationTest { protected static final URI LOCALHOST = URI.create("http://127.0.0.1"); protected static final int DEFAULT_TEST_WEIGHT = 500; - @SuppressWarnings("java:S1068") // used for tests only, no need of secure random - protected static final Random RND = new Random(); + protected static final Random RND = TestdataFactory.RND; /** * Number of {@link DistributionSetType}s that exist in every test case. One diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java index ba6de6396..8c45907c2 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java @@ -20,13 +20,13 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.IntStream; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomStringUtils; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.Constants; import org.eclipse.hawkbit.repository.ControllerManagement; @@ -90,12 +90,14 @@ import org.springframework.util.ObjectUtils; @SuppressWarnings("java:S107") public class TestdataFactory { + @SuppressWarnings("java:S2245") // used for tests only, no need of secure random + public static final Random RND = new Random(); + public static final String VISIBLE_SM_MD_KEY = "visibleMetdataKey"; public static final String VISIBLE_SM_MD_VALUE = "visibleMetdataValue"; public static final String INVISIBLE_SM_MD_KEY = "invisibleMetdataKey"; public static final String INVISIBLE_SM_MD_VALUE = "invisibleMetdataValue"; - public static final RandomStringUtils RANDOM_STRING_UTILS = RandomStringUtils.secure(); public static final AtomicLong COUNTER = new AtomicLong(); /** @@ -197,8 +199,13 @@ public class TestdataFactory { this.systemSecurityContext = systemSecurityContext; } + private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; public static String randomString(final int len) { - return RANDOM_STRING_UTILS.next(len, true, false); + final StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; i++) { + sb.append(ALPHABET.charAt(RND.nextInt(ALPHABET.length()))); + } + return sb.toString(); } public static byte[] randomBytes(final int len) { diff --git a/pom.xml b/pom.xml index 3f1e4805f..6b7ebb6fa 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,6 @@ 2.1.0 2.21.0 4.5.0 - 1.14.0 1.8.0 5.4.0 @@ -303,11 +302,6 @@ commons-collections4 ${commons-collections4.version}
- - org.apache.commons - commons-text - ${commons-text.version} -