Skip to content

Commit a53b31a

Browse files
authored
props: support pre-escaped unicode (#341)
1 parent 09ccc63 commit a53b31a

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

src/main/java/me/itzg/helpers/properties/SetPropertiesCommand.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
import java.util.Objects;
1717
import java.util.Properties;
1818
import java.util.concurrent.Callable;
19+
import java.util.regex.Matcher;
1920
import java.util.regex.Pattern;
2021
import lombok.Setter;
2122
import lombok.extern.slf4j.Slf4j;
2223
import me.itzg.helpers.env.EnvironmentVariablesProvider;
2324
import me.itzg.helpers.env.StandardEnvironmentVariablesProvider;
2425
import me.itzg.helpers.errors.InvalidParameterException;
2526
import me.itzg.helpers.json.ObjectMappers;
27+
import org.jetbrains.annotations.NotNull;
2628
import picocli.CommandLine.Command;
2729
import picocli.CommandLine.ExitCode;
2830
import picocli.CommandLine.Option;
@@ -54,6 +56,8 @@ public class SetPropertiesCommand implements Callable<Integer> {
5456
@Setter
5557
private EnvironmentVariablesProvider environmentVariablesProvider = new StandardEnvironmentVariablesProvider();
5658

59+
private static final Pattern UNICODE_ESCAPE = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
60+
5761
@Override
5862
public Integer call() throws Exception {
5963
if (propertyDefinitionsFile == null && customProperties == null) {
@@ -204,6 +208,25 @@ private String mapAndValidateValue(PropertyDefinition definition, String value)
204208
);
205209
}
206210
}
207-
return value;
211+
212+
return unescapeUnicode(value);
213+
}
214+
215+
@NotNull
216+
private static String unescapeUnicode(String value) {
217+
final Matcher m = UNICODE_ESCAPE.matcher(value);
218+
if (m.find()) {
219+
StringBuffer sb = new StringBuffer();
220+
do {
221+
final int charValue = Integer.parseUnsignedInt(m.group(1), 16);
222+
m.appendReplacement(sb, ""+(char)charValue);
223+
} while (m.find());
224+
m.appendTail(sb);
225+
226+
return sb.toString();
227+
}
228+
else {
229+
return value;
230+
}
208231
}
209232
}

src/test/java/me/itzg/helpers/properties/SetPropertiesCommandTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,29 @@ void encodesWithGivenEncoding() {
219219

220220
}
221221

222+
@Test
223+
void encodesPreEscaped() {
224+
final Path outputProperties = tempDir.resolve("out.properties");
225+
226+
final int exitCode = new CommandLine(new SetPropertiesCommand()
227+
.setEnvironmentVariablesProvider(MappedEnvVarProvider.of(
228+
"LEVEL_NAME", "sv\\u011Bt"
229+
))
230+
)
231+
.execute(
232+
"--definitions", definitionsFile.toString(),
233+
outputProperties.toString()
234+
);
235+
236+
assertThat(exitCode).isEqualTo(ExitCode.OK);
237+
238+
//noinspection UnnecessaryUnicodeEscape
239+
assertThat(outputProperties)
240+
.content(StandardCharsets.UTF_8)
241+
.containsIgnoringNewLines("level-name=svět");
242+
243+
}
244+
222245
private void assertPropertiesEqualExcept(Properties properties, String... propertiesToIgnore) {
223246
final HashSet<Object> actualKeys = new HashSet<>(properties.keySet());
224247
Arrays.asList(propertiesToIgnore).forEach(actualKeys::remove);

0 commit comments

Comments
 (0)