From 7c7c8b954277b6e18c57ff5ea1791b59569c0511 Mon Sep 17 00:00:00 2001 From: Bartosz Spyrko-Smietanko Date: Tue, 30 May 2023 11:01:50 +0100 Subject: [PATCH] [2029] Fallback to default charset if the charset provided by sun.st*.encoding is invalid --- src/main/java/picocli/CommandLine.java | 12 +++++- src/test/java/picocli/Issue2029.java | 55 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/test/java/picocli/Issue2029.java diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index f0ad3490a..8c98f74e5 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -15045,7 +15045,15 @@ static Charset getStderrEncoding() { static Charset charsetForName(String encoding) { if (encoding != null) { if ("cp65001".equalsIgnoreCase(encoding)) { encoding = "UTF-8"; } // #1474 MS Windows uses code page 65001 for UTF8 - return Charset.forName(encoding); + try { + return Charset.forName(encoding); + } catch (Exception e) { + // fallback to default charset if the requested encoding is not available + final Charset defaultCharset = Charset.defaultCharset(); + CommandLine.tracer().info("The %s encoding in not available, falling back to %s", encoding, + defaultCharset.name()); + return defaultCharset; + } } return Charset.defaultCharset(); } @@ -18705,7 +18713,7 @@ private List prefixCommandName(List suggestions) if(commandName == null || commandName.trim().isEmpty()) { return suggestions; } List prefixedSuggestions = new ArrayList(); for (String s : suggestions) { - prefixedSuggestions.add(commandName + " " + s); + prefixedSuggestions.add(commandName + " " + s); } return prefixedSuggestions; } diff --git a/src/test/java/picocli/Issue2029.java b/src/test/java/picocli/Issue2029.java new file mode 100644 index 000000000..f0f27f5ac --- /dev/null +++ b/src/test/java/picocli/Issue2029.java @@ -0,0 +1,55 @@ +package picocli; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.contrib.java.lang.system.SystemErrRule; +import org.junit.contrib.java.lang.system.SystemOutRule; +import org.junit.rules.TestRule; + +import static org.junit.Assert.assertEquals; + +public class Issue2029 { + @Rule + public final TestRule restoreSystemProperties = new RestoreSystemProperties(); + + @Rule + public final SystemOutRule systemOutRule = new SystemOutRule().enableLog(); + + @Rule + public final SystemErrRule systemErrRule = new SystemErrRule().enableLog(); + + @CommandLine.Command(name = "test") + static class TestCommand implements Runnable { + + @CommandLine.Parameters + String text; + + @CommandLine.Spec + CommandLine.Model.CommandSpec spec; + + //@Override + public void run() { + spec.commandLine().getOut().print(text); + spec.commandLine().getOut().flush(); + spec.commandLine().getErr().print(text); + spec.commandLine().getErr().flush(); + } + } + + @Test + public void invalidEncodingFallsbackToDefaultEncoding() { + resetLogs(); + System.setProperty("sun.stdout.encoding", "cp0"); + System.setProperty("sun.stdout.encoding", "cp0"); + + assertEquals(CommandLine.ExitCode.OK, new CommandLine(new Issue1320.TestCommand()).execute("test")); + assertEquals("test", systemOutRule.getLog()); + assertEquals("test", systemErrRule.getLog()); + } + + private void resetLogs() { + systemOutRule.clearLog(); + systemErrRule.clearLog(); + } +}