From 9d509ffc95454e2a12e389340c6f0823d1db1e7c Mon Sep 17 00:00:00 2001 From: Liven Maxim Date: Tue, 25 Feb 2025 18:55:12 +0300 Subject: [PATCH 1/2] tests: add test with secret that was generated with something that accidentally similar to placeholder --- .../properties/SetPropertiesCommandTest.java | 22 +++++++++++++++++++ .../properties/property-definitions.json | 3 +++ 2 files changed, 25 insertions(+) diff --git a/src/test/java/me/itzg/helpers/properties/SetPropertiesCommandTest.java b/src/test/java/me/itzg/helpers/properties/SetPropertiesCommandTest.java index a649c03f..641b5f33 100644 --- a/src/test/java/me/itzg/helpers/properties/SetPropertiesCommandTest.java +++ b/src/test/java/me/itzg/helpers/properties/SetPropertiesCommandTest.java @@ -289,6 +289,28 @@ void processesPlaceholders(String motd, String expected) { } + @Test + void complexSecretsProcessedCorrectly() throws Exception { + final String secret = ":xDmW!T5Y%Jjam;$L9adz-tf%4BuhN,z#64pGx+;3R6^W$#PgGv!Nm-*)A}3^*/js*&)#"; + + final int exitCode = new CommandLine(new SetPropertiesCommand() + .setEnvironmentVariablesProvider(MappedEnvVarProvider.of( + "RCON_PASSWORD", secret + )) + ) + .execute( + "--definitions", definitionsFile.toString(), + propertiesFile.toString() + ); + + assertThat(exitCode).isEqualTo(ExitCode.OK); + + final Properties properties = loadProperties(); + + assertThat(properties).containsEntry("rcon.password", secret); + assertPropertiesEqualExcept(properties, "rcon.password"); + } + private void assertPropertiesEqualExcept(Properties properties, String... propertiesToIgnore) { final HashSet actualKeys = new HashSet<>(properties.keySet()); Arrays.asList(propertiesToIgnore).forEach(actualKeys::remove); diff --git a/src/test/resources/properties/property-definitions.json b/src/test/resources/properties/property-definitions.json index a01b1eb2..0e819415 100644 --- a/src/test/resources/properties/property-definitions.json +++ b/src/test/resources/properties/property-definitions.json @@ -72,6 +72,9 @@ "compression-threshold": { "env": "COMPRESSION_THRESHOLD" }, + "rcon.password": { + "env": "RCON_PASSWORD" + }, "level-name": { "env": "LEVEL_NAME" }, From 5f8c0eda3803da76d7bd4470e8fb841bc23f903d Mon Sep 17 00:00:00 2001 From: Liven Maxim Date: Tue, 25 Feb 2025 19:14:34 +0300 Subject: [PATCH 2/2] fix: placeholder's replacement to fallback value throws an IllegalArgumentException (Illegal group reference) --- .../itzg/helpers/env/SimplePlaceholders.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/itzg/helpers/env/SimplePlaceholders.java b/src/main/java/me/itzg/helpers/env/SimplePlaceholders.java index 3cfd73b7..d325b378 100644 --- a/src/main/java/me/itzg/helpers/env/SimplePlaceholders.java +++ b/src/main/java/me/itzg/helpers/env/SimplePlaceholders.java @@ -39,7 +39,11 @@ public String processPlaceholders(String value) { do { final String type = Optional.ofNullable(m.group("type")) .orElse("env"); - final String replacement = buildPlaceholderReplacement(type, m.group("var"), m.group()); + final String replacement = buildPlaceholderReplacement(type, m.group("var")); + + if (replacement == null) { + continue; + } m.appendReplacement(sb, replacement); } while (m.find()); @@ -50,18 +54,15 @@ public String processPlaceholders(String value) { return value; } - private String buildPlaceholderReplacement(String type, String var, String fallback) { + private String buildPlaceholderReplacement(String type, String var) { log.debug("Building placeholder replacement from type={} with var='{}'", type, var); switch (type) { case "env": final String result = environmentVariablesProvider.get(var); - if (result != null) { - return result; - } - else { + if (result == null) { log.warn("Unable to resolve environment variable {}", var); - return fallback; } + return result; case "date": case "time": @@ -70,11 +71,11 @@ private String buildPlaceholderReplacement(String type, String var, String fallb return ZonedDateTime.now(clock).format(f); } catch (IllegalArgumentException e) { log.error("Invalid date/time format in {}", var, e); - return fallback; + return null; } } - return fallback; + return null; } }