From 6a3c64e320785e2e0e652678687b84e9a8bca478 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jan 2022 07:48:51 -0800 Subject: [PATCH 01/14] Bump `jenkins-test-harness` (#6160) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index 5d949a610cd6..9f473e2d1ed9 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -83,7 +83,7 @@ THE SOFTWARE. ${project.groupId} jenkins-test-harness - 1674.v3b8b1441e939 + 1682.v4a_71b_f124ca_3 test From 02a975d5caac1e422ee082f18476e7ace91e0afd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jan 2022 07:49:07 -0800 Subject: [PATCH 02/14] Bump `mailer` from 1.34 to 391.ve4a_38c1b_cf4b_ (#6159) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index 9f473e2d1ed9..336a6e6322ed 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -118,7 +118,7 @@ THE SOFTWARE. org.jenkins-ci.plugins mailer - 1.34 + 391.ve4a_38c1b_cf4b_ test From c31d9302d946463884406f920c8d14b2cf7cdf24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jan 2022 07:49:21 -0800 Subject: [PATCH 03/14] Bump `jenkins` from 1.69 to 1.70 (#6158) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7aa11d309fb3..492981b43579 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.69 + 1.70 From 627912239e6c0e4324002d1bfd45e241b34127b3 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Fri, 7 Jan 2022 11:41:58 +0000 Subject: [PATCH 04/14] [JENKINS-67515] Fix vertical icon alignment for build status in M and S icon sizes (#6162) * JENKINS-67515 * Fix headlines --- war/src/main/less/base/layout-commons.less | 2 ++ war/src/main/less/base/style.less | 2 +- war/src/main/less/modules/icons.less | 5 +++-- war/src/main/less/modules/table.less | 1 - 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/war/src/main/less/base/layout-commons.less b/war/src/main/less/base/layout-commons.less index 1df72a639c58..fd85351bf583 100644 --- a/war/src/main/less/base/layout-commons.less +++ b/war/src/main/less/base/layout-commons.less @@ -125,6 +125,8 @@ body.full-screen #main-panel { /* -------------------------------------- */ h1.build-caption.page-headline { + display: flex; + align-items: center; max-width: 1200px; overflow: hidden; white-space: nowrap; diff --git a/war/src/main/less/base/style.less b/war/src/main/less/base/style.less index 5fe70bcb534a..4c6e3124b597 100644 --- a/war/src/main/less/base/style.less +++ b/war/src/main/less/base/style.less @@ -1522,7 +1522,7 @@ svg.icon-xlg { } .jenkins-icon-adjacent { - margin-left: 0.2rem; + margin-left: 0.5rem; } /* -------------- Unclassified ---------- */ diff --git a/war/src/main/less/modules/icons.less b/war/src/main/less/modules/icons.less index cc558ad14d85..b7e060ae3b27 100644 --- a/war/src/main/less/modules/icons.less +++ b/war/src/main/less/modules/icons.less @@ -89,11 +89,12 @@ } .build-status-icon__wrapper { - display: inline-block; + display: inline-flex; position: relative; } + .build-status-icon__outer { - display: block; + display: flex; position: absolute; top: 50%; left: 50%; diff --git a/war/src/main/less/modules/table.less b/war/src/main/less/modules/table.less index 10320baea922..b0bee21e995e 100644 --- a/war/src/main/less/modules/table.less +++ b/war/src/main/less/modules/table.less @@ -63,7 +63,6 @@ &:first-of-type { border-radius: var(--table-body-radius) 0 0 var(--table-body-radius); padding-left: calc(var(--table-padding) * 2); - padding-right: var(--table-padding); } &:last-of-type { From 5d9b1556ffe3fd54f45a9fa1571589d4714becaa Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 7 Jan 2022 09:26:12 -0500 Subject: [PATCH 05/14] [JENKINS-67470] Extend shading of Tyrus WebSocket client (#6164) --- cli/pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cli/pom.xml b/cli/pom.xml index 34a47850a8b2..8772f2658fc2 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -149,6 +149,14 @@ net io.jenkins.cli.shaded.net + + com + io.jenkins.cli.shaded.com + + + jakarta + io.jenkins.cli.shaded.jakarta + From 1c738297b02914a67f5ae42504cb3a24dcf4a753 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jan 2022 06:26:38 -0800 Subject: [PATCH 06/14] Bump `jnr-posix` from 3.1.14 to 3.1.15 (#6168) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 3fc576fae329..9f6a499a1dbb 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -221,7 +221,7 @@ THE SOFTWARE. com.github.jnr jnr-posix - 3.1.14 + 3.1.15 org.kohsuke From 46d6af94e6b767a6261b1db4760314372e193750 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jan 2022 06:26:57 -0800 Subject: [PATCH 07/14] Bump `spotless-maven-plugin` from 2.18.0 to 2.19.0 (#6167) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 492981b43579..385c1363c51f 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,7 @@ THE SOFTWARE. 1.23 5.8.2 4.2.0 - 2.18.0 + 2.19.0 From 72d38d2192ce46dfa29b1879bae2bc24b2b4c8ce Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 7 Jan 2022 09:27:12 -0500 Subject: [PATCH 08/14] Do not use `javax.mail` for `doCheckAdminAddress` (#6166) --- .../jenkins/model/JenkinsLocationConfiguration.java | 10 ++++------ .../main/resources/jenkins/model/Messages.properties | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java index 12aa35b0e5f6..5aa73c17528a 100644 --- a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java +++ b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java @@ -18,8 +18,6 @@ import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; import javax.servlet.ServletContext; import jenkins.util.SystemProperties; import jenkins.util.UrlHelper; @@ -210,11 +208,11 @@ public FormValidation doCheckUrl(@QueryParameter String value) { } public FormValidation doCheckAdminAddress(@QueryParameter String value) { - try { - new InternetAddress(value); + // TODO if equal to Messages.Mailer_Address_Not_Configured(), suggest configuring it with FormValidation.warning? + if (Util.fixNull(value).contains("@")) { return FormValidation.ok(); - } catch (AddressException e) { - return FormValidation.error(e.getMessage()); + } else { + return FormValidation.error(Messages.JenkinsLocationConfiguration_does_not_look_like_an_email_address()); } } diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties index d5afb130acf6..ef2028aa5fd5 100644 --- a/core/src/main/resources/jenkins/model/Messages.properties +++ b/core/src/main/resources/jenkins/model/Messages.properties @@ -57,6 +57,7 @@ IdStrategy.CaseSensitive.DisplayName=Case sensitive IdStrategy.CaseSensitiveEmailAddress.DisplayName=Case sensitive (email address) Mailer.Address.Not.Configured=address not configured yet +JenkinsLocationConfiguration.does_not_look_like_an_email_address=Does not look like an email address Mailer.Localhost.Error=Please set a valid host name, instead of localhost Mailer.NotHttp.Error=The URL is invalid, please ensure you are using http:// or https:// with a valid domain. From dd0db180bf3fd727b5aa594a94105c3430004a84 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 7 Jan 2022 06:29:06 -0800 Subject: [PATCH 09/14] Begin migration to Jakarta Annotations (#6161) --- bom/pom.xml | 2 +- core/src/main/java/hudson/ExtensionFinder.java | 4 ++-- core/src/main/java/hudson/model/PersistentDescriptor.java | 2 +- core/src/main/java/hudson/triggers/SCMTrigger.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 9f6a499a1dbb..44220df8b8af 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -40,7 +40,7 @@ THE SOFTWARE. 9.2 1.7.32 - 1635.vb_0ddedb_739f2 + 1638.v229a_24fa_b_17c 2.4.21 diff --git a/core/src/main/java/hudson/ExtensionFinder.java b/core/src/main/java/hudson/ExtensionFinder.java index 19c60bc9b975..5bddd008f5f0 100644 --- a/core/src/main/java/hudson/ExtensionFinder.java +++ b/core/src/main/java/hudson/ExtensionFinder.java @@ -39,6 +39,7 @@ import hudson.init.InitMilestone; import hudson.model.Descriptor; import hudson.model.Hudson; +import jakarta.annotation.PostConstruct; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; @@ -56,7 +57,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import javax.annotation.PostConstruct; import jenkins.ExtensionComponentSet; import jenkins.ExtensionFilter; import jenkins.ExtensionRefreshException; @@ -580,7 +580,7 @@ public void onProvision(ProvisionInvocation provision) { Arrays.stream(c.getDeclaredMethods()) .map(m -> getMethodAndInterfaceDeclarations(m, interfaces)) .flatMap(Collection::stream) - .filter(m -> m.getAnnotation(PostConstruct.class) != null) + .filter(m -> m.getAnnotation(PostConstruct.class) != null || m.getAnnotation(javax.annotation.PostConstruct.class) != null) .findFirst() .ifPresent(method -> methods.add(0, method)); c = c.getSuperclass(); diff --git a/core/src/main/java/hudson/model/PersistentDescriptor.java b/core/src/main/java/hudson/model/PersistentDescriptor.java index 80a2f829e491..908752151279 100644 --- a/core/src/main/java/hudson/model/PersistentDescriptor.java +++ b/core/src/main/java/hudson/model/PersistentDescriptor.java @@ -1,6 +1,6 @@ package hudson.model; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; /** * Marker interface for Descriptors which use xml persistent data, and as such need to load from disk when instantiated. diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index 6f7eff0bcbf7..061bd15c2383 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -50,6 +50,7 @@ import hudson.util.NamingThreadFactory; import hudson.util.SequentialExecutionQueue; import hudson.util.StreamTaskListener; +import jakarta.annotation.PostConstruct; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -71,7 +72,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.PostConstruct; import jenkins.model.Jenkins; import jenkins.model.RunAction2; import jenkins.scm.SCMDecisionHandler; From 520e114ea1804c4eee594d30621f362413bfd60d Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 7 Jan 2022 06:29:39 -0800 Subject: [PATCH 10/14] Use explicit character set in tests (#6150) --- .../java/hudson/cli/PlainCLIProtocolTest.java | 9 ++-- core/src/test/java/hudson/FilePathTest.java | 7 ++-- core/src/test/java/hudson/LauncherTest.java | 8 ++-- .../test/java/hudson/PluginManagerTest.java | 6 +-- core/src/test/java/hudson/UtilTest.java | 7 ++-- .../java/hudson/cli/ListJobsCommandTest.java | 18 +++++--- .../hudson/slaves/ComputerLauncherTest.java | 5 ++- .../java/hudson/util/SecretRewriterTest.java | 2 +- .../src/test/java/hudson/util/SecretTest.java | 2 +- ...ewindableRotatingFileOutputStreamTest.java | 4 +- .../routines/DomainValidatorTest.java | 9 ++-- .../security/CryptoConfidentialKeyTest.java | 7 ++-- .../DefaultConfidentialStoreTest.java | 8 ++-- .../java/jenkins/util/io/PathRemoverTest.java | 5 ++- test/src/test/java/hudson/LauncherTest.java | 11 ++--- .../test/java/hudson/PluginManagerTest.java | 5 ++- test/src/test/java/hudson/ProcTest.java | 14 +++---- test/src/test/java/hudson/XMLFileTest.java | 5 ++- .../java/hudson/cli/BuildCommandTest.java | 3 +- .../test/java/hudson/cli/CLIActionTest.java | 14 ++++--- .../test/java/hudson/cli/CLIEnvVarTest.java | 9 ++-- test/src/test/java/hudson/cli/CLITest.java | 9 ++-- .../java/hudson/cli/GetJobCommandTest.java | 42 +++++++++---------- .../java/hudson/cli/GroovyshCommandTest.java | 3 +- .../cli/ReloadConfigurationCommandTest.java | 22 ++++++---- .../console/AnnotatedLargeTextTest.java | 12 +++--- .../hudson/console/ConsoleLogFilterTest.java | 3 +- .../hudson/model/AbstractProjectTest.java | 4 +- .../src/test/java/hudson/model/CauseTest.java | 13 +++--- .../model/FingerprintCleanupThreadTest.java | 22 +++++++--- .../hudson/model/FreeStyleProjectTest.java | 9 ++-- .../java/hudson/model/ItemGroupMixInTest.java | 11 ++--- test/src/test/java/hudson/model/JobTest.java | 5 ++- .../java/hudson/model/UpdateSiteTest.java | 3 +- .../model/listeners/ItemListenerTest.java | 3 +- .../TokenBasedRememberMeServices2Test.java | 3 +- .../hudson/triggers/TriggerStartTest.java | 5 ++- .../java/hudson/triggers/TriggerTest.java | 3 +- .../hudson/util/ArgumentListBuilder2Test.java | 5 ++- .../util/RobustReflectionConverterTest.java | 5 ++- .../jenkins/agents/WebSocketAgentsTest.java | 3 +- .../java/jenkins/install/SetupWizardTest.java | 7 ++-- .../model/JenkinsReloadConfigurationTest.java | 22 ++++++---- .../java/jenkins/model/NodeListenerTest.java | 5 ++- .../security/RekeySecretAdminMonitorTest.java | 4 +- .../jenkins/tasks/SimpleBuildWrapperTest.java | 3 +- 46 files changed, 225 insertions(+), 159 deletions(-) diff --git a/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java b/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java index 71b0368111c4..98a4fefd8001 100644 --- a/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java +++ b/cli/src/test/java/hudson/cli/PlainCLIProtocolTest.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.nio.charset.Charset; import org.junit.jupiter.api.Test; public class PlainCLIProtocolTest { @@ -67,7 +68,7 @@ protected void handleClose() {} void send() throws IOException { sendArg("command"); sendStart(); - streamStdin().write("hello".getBytes()); + streamStdin().write("hello".getBytes(Charset.defaultCharset())); } void newop() throws IOException { @@ -123,7 +124,7 @@ protected void onEndStdin() throws IOException {} protected void handleClose() {} void send() throws IOException { - streamStdout().write("goodbye".getBytes()); + streamStdout().write("goodbye".getBytes(Charset.defaultCharset())); sendExit(2); } @@ -156,9 +157,9 @@ void newop() throws IOException { while (server.stdin.size() == 0) { Thread.sleep(100); } - assertEquals("hello", server.stdin.toString()); + assertEquals("hello", server.stdin.toString(Charset.defaultCharset().name())); assertEquals("command", server.arg); - assertEquals("goodbye", client.stdout.toString()); + assertEquals("goodbye", client.stdout.toString(Charset.defaultCharset().name())); assertEquals(2, client.code); } diff --git a/core/src/test/java/hudson/FilePathTest.java b/core/src/test/java/hudson/FilePathTest.java index be721312fd88..031537fc46ee 100644 --- a/core/src/test/java/hudson/FilePathTest.java +++ b/core/src/test/java/hudson/FilePathTest.java @@ -58,6 +58,7 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -657,9 +658,9 @@ private static void assertValidateAntFileMask(String expected, FilePath d, Strin when(con.getInputStream()).thenThrow(new ConnectException()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); String message = "going ahead"; - assertFalse(d.installIfNecessaryFrom(url, new StreamTaskListener(baos), message)); + assertFalse(d.installIfNecessaryFrom(url, new StreamTaskListener(baos, Charset.defaultCharset()), message)); verify(con).setIfModifiedSince(123000); - String log = baos.toString(); + String log = baos.toString(Charset.defaultCharset().name()); assertFalse(log, log.contains(message)); assertTrue(log, log.contains("504 Gateway Timeout")); } @@ -701,7 +702,7 @@ private InputStream someZippedContent() throws IOException { final ZipOutputStream zip = new ZipOutputStream(buf); zip.putNextEntry(new ZipEntry("abc")); - zip.write("abc".getBytes()); + zip.write("abc".getBytes(StandardCharsets.US_ASCII)); zip.close(); return new ByteArrayInputStream(buf.toByteArray()); diff --git a/core/src/test/java/hudson/LauncherTest.java b/core/src/test/java/hudson/LauncherTest.java index acbf93f1e345..b1ef4befdbde 100644 --- a/core/src/test/java/hudson/LauncherTest.java +++ b/core/src/test/java/hudson/LauncherTest.java @@ -90,12 +90,12 @@ public Object call() throws RuntimeException { @Issue("JENKINS-15733") @Test public void decorateByEnv() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - TaskListener l = new StreamBuildListener(baos); + TaskListener l = new StreamBuildListener(baos, Charset.defaultCharset()); Launcher base = new Launcher.LocalLauncher(l); EnvVars env = new EnvVars("key1", "val1"); Launcher decorated = base.decorateByEnv(env); int res = decorated.launch().envs("key2=val2").cmds(Functions.isWindows() ? new String[] {"cmd", "/q", "/c", "echo %key1% %key2%"} : new String[] {"sh", "-c", "echo $key1 $key2"}).stdout(l).join(); - String log = baos.toString(); + String log = baos.toString(Charset.defaultCharset().name()); assertEquals(log, 0, res); assertTrue(log, log.contains("val1 val2")); } @@ -103,7 +103,7 @@ public Object call() throws RuntimeException { @Issue("JENKINS-18368") @Test public void decoratedByEnvMaintainsIsUnix() { ByteArrayOutputStream output = new ByteArrayOutputStream(); - TaskListener listener = new StreamBuildListener(output); + TaskListener listener = new StreamBuildListener(output, Charset.defaultCharset()); Launcher remoteLauncher = new Launcher.RemoteLauncher(listener, FilePath.localChannel, false); Launcher decorated = remoteLauncher.decorateByEnv(new EnvVars()); assertFalse(decorated.isUnix()); @@ -115,7 +115,7 @@ public Object call() throws RuntimeException { @Issue("JENKINS-18368") @Test public void decoratedByPrefixMaintainsIsUnix() { ByteArrayOutputStream output = new ByteArrayOutputStream(); - TaskListener listener = new StreamBuildListener(output); + TaskListener listener = new StreamBuildListener(output, Charset.defaultCharset()); Launcher remoteLauncher = new Launcher.RemoteLauncher(listener, FilePath.localChannel, false); Launcher decorated = remoteLauncher.decorateByPrefix("test"); assertFalse(decorated.isUnix()); diff --git a/core/src/test/java/hudson/PluginManagerTest.java b/core/src/test/java/hudson/PluginManagerTest.java index 81cc5f5df695..4ccde769c37a 100644 --- a/core/src/test/java/hudson/PluginManagerTest.java +++ b/core/src/test/java/hudson/PluginManagerTest.java @@ -63,7 +63,7 @@ public void parseRequestedPlugins() throws Exception { tmp.resolve("output.txt") ); assertEquals("{other=2.0, stuff=1.2}", new LocalPluginManager(output.getParent().toFile()) - .parseRequestedPlugins(new ByteArrayInputStream("".getBytes())).toString()); + .parseRequestedPlugins(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))).toString()); } @Issue("SECURITY-167") @@ -82,7 +82,7 @@ public void parseInvalidRequestedPlugins() throws Exception { PluginManager pluginManager = new LocalPluginManager(Util.createTempDir()); final IOException ex = assertThrows(IOException.class, - () -> pluginManager.parseRequestedPlugins(new ByteArrayInputStream(evilXML.getBytes())), + () -> pluginManager.parseRequestedPlugins(new ByteArrayInputStream(evilXML.getBytes(StandardCharsets.UTF_8))), "XML contains an external entity, but no exception was thrown."); assertThat(ex.getCause(), instanceOf(SAXException.class)); assertThat(ex.getCause().getMessage(), containsString("DOCTYPE is disallowed")); @@ -156,7 +156,7 @@ private File createHpiWithManifest() throws IOException { try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(f.toPath()))) { ZipEntry e = new ZipEntry(manifestPath); out.putNextEntry(e); - byte[] data = SAMPLE_MANIFEST_FILE.getBytes(); + byte[] data = SAMPLE_MANIFEST_FILE.getBytes(StandardCharsets.UTF_8); out.write(data, 0, data.length); out.closeEntry(); } diff --git a/core/src/test/java/hudson/UtilTest.java b/core/src/test/java/hudson/UtilTest.java index 2dad8304be76..5ea83d1f8489 100644 --- a/core/src/test/java/hudson/UtilTest.java +++ b/core/src/test/java/hudson/UtilTest.java @@ -44,6 +44,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.AccessDeniedException; import java.nio.file.Files; @@ -231,7 +232,7 @@ public void testSymlink() throws Exception { assumeFalse(Functions.isWindows()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - StreamTaskListener l = new StreamTaskListener(baos); + StreamTaskListener l = new StreamTaskListener(baos, Charset.defaultCharset()); File d = tmp.getRoot(); try { new FilePath(new File(d, "a")).touch(0); @@ -245,7 +246,7 @@ public void testSymlink() throws Exception { buf.append((char) ('0' + (i % 10))); Util.createSymlink(d, buf.toString(), "x", l); - String log = baos.toString(); + String log = baos.toString(Charset.defaultCharset().name()); if (log.length() > 0) System.err.println("log output: " + log); @@ -279,7 +280,7 @@ public void testIsSymlink() throws IOException, InterruptedException { assumeFalse(Functions.isWindows()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - StreamTaskListener l = new StreamTaskListener(baos); + StreamTaskListener l = new StreamTaskListener(baos, Charset.defaultCharset()); File d = tmp.getRoot(); try { new FilePath(new File(d, "original")).touch(0); diff --git a/core/src/test/java/hudson/cli/ListJobsCommandTest.java b/core/src/test/java/hudson/cli/ListJobsCommandTest.java index 832fedfb70a1..99750cea9b08 100644 --- a/core/src/test/java/hudson/cli/ListJobsCommandTest.java +++ b/core/src/test/java/hudson/cli/ListJobsCommandTest.java @@ -14,11 +14,13 @@ import hudson.model.ViewTest.CompositeView; import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Set; import jenkins.model.Jenkins; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; @@ -154,8 +156,11 @@ private TypeSafeMatcher empty() { @Override protected boolean matchesSafely(ByteArrayOutputStream item) { - - return item.toString().isEmpty(); + try { + return item.toString(command.getClientCharset().name()).isEmpty(); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } } @Override @@ -173,9 +178,12 @@ private TypeSafeMatcher listsJobs(final String... expecte @Override protected boolean matchesSafely(ByteArrayOutputStream item) { - final HashSet jobs = new HashSet<>( - Arrays.asList(item.toString().split(System.getProperty("line.separator"))) - ); + Set jobs; + try { + jobs = new HashSet<>(Arrays.asList(item.toString(command.getClientCharset().name()).split(System.getProperty("line.separator")))); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } return new HashSet<>(Arrays.asList(expected)).equals(jobs); } diff --git a/core/src/test/java/hudson/slaves/ComputerLauncherTest.java b/core/src/test/java/hudson/slaves/ComputerLauncherTest.java index c019492d3484..80ba6a61a74b 100644 --- a/core/src/test/java/hudson/slaves/ComputerLauncherTest.java +++ b/core/src/test/java/hudson/slaves/ComputerLauncherTest.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.PrintStream; import java.io.StringReader; +import java.nio.charset.Charset; import org.apache.commons.io.output.NullOutputStream; import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; @@ -142,8 +143,8 @@ public class ComputerLauncherTest { private static void assertChecked(String text, String spec) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); - ComputerLauncher.checkJavaVersion(new PrintStream(os), "bin/java", new BufferedReader(new StringReader(text))); - String logged = os.toString(); + ComputerLauncher.checkJavaVersion(new PrintStream(os, false, Charset.defaultCharset().name()), "bin/java", new BufferedReader(new StringReader(text))); + String logged = os.toString(Charset.defaultCharset().name()); assertTrue(logged.contains(Messages.ComputerLauncher_JavaVersionResult("bin/java", spec)), logged); } } diff --git a/core/src/test/java/hudson/util/SecretRewriterTest.java b/core/src/test/java/hudson/util/SecretRewriterTest.java index ea3af9085227..6cd12245da29 100644 --- a/core/src/test/java/hudson/util/SecretRewriterTest.java +++ b/core/src/test/java/hudson/util/SecretRewriterTest.java @@ -61,7 +61,7 @@ private String roundtrip(String before) throws Exception { private String encryptOld(String str) throws Exception { Cipher cipher = Secret.getCipher("AES"); cipher.init(Cipher.ENCRYPT_MODE, HistoricalSecrets.getLegacyKey()); - return new String(Base64.getEncoder().encode(cipher.doFinal((str + HistoricalSecrets.MAGIC).getBytes(StandardCharsets.UTF_8)))); + return Base64.getEncoder().encodeToString(cipher.doFinal((str + HistoricalSecrets.MAGIC).getBytes(StandardCharsets.UTF_8))); } private String encryptNew(String str) { diff --git a/core/src/test/java/hudson/util/SecretTest.java b/core/src/test/java/hudson/util/SecretTest.java index 316db2a7c5be..ea7ec5cc403a 100644 --- a/core/src/test/java/hudson/util/SecretTest.java +++ b/core/src/test/java/hudson/util/SecretTest.java @@ -130,7 +130,7 @@ public void migrationFromLegacyKeyToConfidentialStore() throws Exception { for (String str : new String[] {"Hello world", "", "\u0000unprintable"}) { Cipher cipher = Secret.getCipher("AES"); cipher.init(Cipher.ENCRYPT_MODE, legacy); - String old = new String(Base64.getEncoder().encode(cipher.doFinal((str + HistoricalSecrets.MAGIC).getBytes(StandardCharsets.UTF_8)))); + String old = Base64.getEncoder().encodeToString(cipher.doFinal((str + HistoricalSecrets.MAGIC).getBytes(StandardCharsets.UTF_8))); Secret s = Secret.fromString(old); assertEquals("secret by the old key should decrypt", str, s.getPlainText()); assertNotEquals("but when encrypting, ConfidentialKey should be in use", old, s.getEncryptedValue()); diff --git a/core/src/test/java/hudson/util/io/RewindableRotatingFileOutputStreamTest.java b/core/src/test/java/hudson/util/io/RewindableRotatingFileOutputStreamTest.java index 432ccd21455f..b6368779469a 100644 --- a/core/src/test/java/hudson/util/io/RewindableRotatingFileOutputStreamTest.java +++ b/core/src/test/java/hudson/util/io/RewindableRotatingFileOutputStreamTest.java @@ -8,7 +8,9 @@ import hudson.Functions; import java.io.File; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; @@ -24,7 +26,7 @@ public class RewindableRotatingFileOutputStreamTest { public void rotation() throws IOException, InterruptedException { File base = tmp.newFile("test.log"); RewindableRotatingFileOutputStream os = new RewindableRotatingFileOutputStream(base, 3); - PrintWriter w = new PrintWriter(os, true); + PrintWriter w = new PrintWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8), true); for (int i = 0; i <= 4; i++) { w.println("Content" + i); os.rewind(); diff --git a/core/src/test/java/jenkins/org/apache/commons/validator/routines/DomainValidatorTest.java b/core/src/test/java/jenkins/org/apache/commons/validator/routines/DomainValidatorTest.java index e75a80d6928e..07fc75d98275 100644 --- a/core/src/test/java/jenkins/org/apache/commons/validator/routines/DomainValidatorTest.java +++ b/core/src/test/java/jenkins/org/apache/commons/validator/routines/DomainValidatorTest.java @@ -21,7 +21,6 @@ import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; -import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; @@ -29,6 +28,8 @@ import java.net.HttpURLConnection; import java.net.IDN; import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; @@ -336,7 +337,7 @@ public static void main(String[] a) throws Exception { // if the txt file contains entries not found in the html file, try again in a day or two download(htmlFile, "https://www.iana.org/domains/root/db", timestamp); - BufferedReader br = new BufferedReader(new FileReader(txtFile)); + BufferedReader br = Files.newBufferedReader(txtFile.toPath(), StandardCharsets.UTF_8); String line; final String header; line = br.readLine(); // header @@ -437,7 +438,7 @@ private static Map getHtmlInfo(final File f) throws IOExceptio // Ã…lands landskapsregering final Pattern comment = Pattern.compile("\\s+([^<]+)"); - final BufferedReader br = new BufferedReader(new FileReader(f)); + final BufferedReader br = Files.newBufferedReader(f.toPath(), StandardCharsets.UTF_8); String line; while ((line = br.readLine()) != null) { Matcher m = domain.matcher(line); @@ -541,7 +542,7 @@ private static boolean isNotInRootZone(String domain) { BufferedReader in = null; try { download(rootCheck, tldurl, 0L); - in = new BufferedReader(new FileReader(rootCheck)); + in = Files.newBufferedReader(rootCheck.toPath(), StandardCharsets.UTF_8); String inputLine; while ((inputLine = in.readLine()) != null) { if (inputLine.contains("This domain is not present in the root zone at this time.")) { diff --git a/core/src/test/java/jenkins/security/CryptoConfidentialKeyTest.java b/core/src/test/java/jenkins/security/CryptoConfidentialKeyTest.java index 198bc347f3ea..bf56ff0be395 100644 --- a/core/src/test/java/jenkins/security/CryptoConfidentialKeyTest.java +++ b/core/src/test/java/jenkins/security/CryptoConfidentialKeyTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertArrayEquals; +import java.nio.charset.StandardCharsets; import org.junit.Rule; import org.junit.Test; @@ -15,13 +16,13 @@ public class CryptoConfidentialKeyTest { @Test public void decryptGetsPlainTextBack() throws Exception { for (String str : new String[] {"Hello world", "", "\u0000"}) { - assertArrayEquals(str.getBytes(), key.decrypt().doFinal(key.encrypt().doFinal(str.getBytes()))); + assertArrayEquals(str.getBytes(StandardCharsets.UTF_8), key.decrypt().doFinal(key.encrypt().doFinal(str.getBytes(StandardCharsets.UTF_8)))); } } @Test public void multipleEncryptsAreIdempotent() throws Exception { - byte[] str = "Hello world".getBytes(); + byte[] str = "Hello world".getBytes(StandardCharsets.UTF_8); assertArrayEquals(key.encrypt().doFinal(str), key.encrypt().doFinal(str)); } @@ -29,7 +30,7 @@ public void multipleEncryptsAreIdempotent() throws Exception { public void loadingExistingKey() throws Exception { CryptoConfidentialKey key2 = new CryptoConfidentialKey("test"); // this will cause the key to be loaded from the disk for (String str : new String[] {"Hello world", "", "\u0000"}) { - assertArrayEquals(str.getBytes(), key2.decrypt().doFinal(key.encrypt().doFinal(str.getBytes()))); + assertArrayEquals(str.getBytes(StandardCharsets.UTF_8), key2.decrypt().doFinal(key.encrypt().doFinal(str.getBytes(StandardCharsets.UTF_8)))); } } diff --git a/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java b/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java index be91dd1a38cd..2475d7714b22 100644 --- a/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java +++ b/core/src/test/java/jenkins/security/DefaultConfidentialStoreTest.java @@ -10,7 +10,7 @@ import hudson.FilePath; import hudson.Functions; import java.io.File; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; @@ -30,14 +30,14 @@ public void roundtrip() throws Exception { // basic roundtrip String str = "Hello world!"; - store.store(key, str.getBytes()); - assertEquals(str, new String(store.load(key))); + store.store(key, str.getBytes(StandardCharsets.UTF_8)); + assertEquals(str, new String(store.load(key), StandardCharsets.UTF_8)); // data storage should have some stuff assertTrue(new File(tmp, "test").exists()); assertTrue(new File(tmp, "master.key").exists()); - assertThat(FileUtils.readFileToString(new File(tmp, "test"), Charset.defaultCharset()), not(containsString("Hello"))); // the data shouldn't be a plain text, obviously + assertThat(FileUtils.readFileToString(new File(tmp, "test"), StandardCharsets.UTF_8), not(containsString("Hello"))); // the data shouldn't be a plain text, obviously if (!Functions.isWindows()) { assertEquals(0700, new FilePath(tmp).mode() & 0777); // should be read only diff --git a/core/src/test/java/jenkins/util/io/PathRemoverTest.java b/core/src/test/java/jenkins/util/io/PathRemoverTest.java index 6fcc6b128df7..0702221d3981 100644 --- a/core/src/test/java/jenkins/util/io/PathRemoverTest.java +++ b/core/src/test/java/jenkins/util/io/PathRemoverTest.java @@ -42,8 +42,9 @@ import hudson.Functions; import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; +import java.nio.charset.Charset; import java.nio.file.FileSystem; import java.nio.file.FileSystemException; import java.nio.file.Files; @@ -454,7 +455,7 @@ private static void mkdirs(File... dirs) { private static void touchWithFileName(File... files) throws IOException { for (File file : files) { - try (FileWriter writer = new FileWriter(file)) { + try (Writer writer = Files.newBufferedWriter(file.toPath(), Charset.defaultCharset())) { writer.append(file.getName()).append(System.lineSeparator()); } assertTrue(file.isFile()); diff --git a/test/src/test/java/hudson/LauncherTest.java b/test/src/test/java/hudson/LauncherTest.java index d83914c69783..e0e0454566b5 100644 --- a/test/src/test/java/hudson/LauncherTest.java +++ b/test/src/test/java/hudson/LauncherTest.java @@ -56,6 +56,7 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -286,15 +287,15 @@ private void assertMultipleStdioCalls(String message, Node node, boolean emitStd } ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); - TaskListener listener = new StreamTaskListener(baos2); + TaskListener listener = new StreamTaskListener(baos2, Charset.defaultCharset()); psCustomizer.run(ps, baos1, baos2, listener); assertEquals(message, 0, ps.join()); if (outputIn2) { - assertThat(message, baos2.toString(), containsString("hello")); - assertThat(message, baos1.toString(), is(emptyString())); + assertThat(message, baos2.toString(Charset.defaultCharset().name()), containsString("hello")); + assertThat(message, baos1.toString(Charset.defaultCharset().name()), is(emptyString())); } else { - assertThat(message, baos1.toString(), containsString("hello")); - assertThat(message, baos2.toString(), is(emptyString())); + assertThat(message, baos1.toString(Charset.defaultCharset().name()), containsString("hello")); + assertThat(message, baos2.toString(Charset.defaultCharset().name()), is(emptyString())); } } diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index 8331772f7a94..4182d6d738f1 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -51,6 +51,7 @@ import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -244,9 +245,9 @@ public void startPlugin(PluginWrapper plugin) throws Exception { sites.add(site); assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); assertNotNull(site.getData()); - assertEquals(Collections.emptyList(), r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes()))); + assertEquals(Collections.emptyList(), r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))); assertNull(r.jenkins.getPluginManager().getPlugin("htmlpublisher")); - List> jobs = r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes())); + List> jobs = r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); assertEquals(1, jobs.size()); UpdateCenterJob job = jobs.get(0).get(); // blocks for completion assertEquals("InstallationJob", job.getType()); diff --git a/test/src/test/java/hudson/ProcTest.java b/test/src/test/java/hudson/ProcTest.java index c19bb10453be..d3e7608b8ef6 100644 --- a/test/src/test/java/hudson/ProcTest.java +++ b/test/src/test/java/hudson/ProcTest.java @@ -64,7 +64,7 @@ public void run() { for (int i = 0; i < 1000; i++) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); launcher.launch().cmds("echo", str).stdout(baos).join(); - assertEquals(str, baos.toString().trim()); + assertEquals(str, baos.toString(Charset.defaultCharset().name()).trim()); } ch.close(); @@ -115,21 +115,21 @@ private void doIoPumpingTest(Launcher l) throws IOException, InterruptedExceptio String[] ECHO_BACK_CMD = {"cat"}; // TODO: what is the echo back command for Windows? "cmd /C copy CON CON"? ByteArrayOutputStream out = new ByteArrayOutputStream(); - l.launch().cmds(ECHO_BACK_CMD).stdin(new ByteArrayInputStream("Hello".getBytes())).stdout(out).join(); - assertEquals("Hello", out.toString()); + l.launch().cmds(ECHO_BACK_CMD).stdin(new ByteArrayInputStream("Hello".getBytes(Charset.defaultCharset()))).stdout(out).join(); + assertEquals("Hello", out.toString(Charset.defaultCharset().name())); - Proc p = l.launch().cmds(ECHO_BACK_CMD).stdin(new ByteArrayInputStream("Hello".getBytes())).readStdout().start(); + Proc p = l.launch().cmds(ECHO_BACK_CMD).stdin(new ByteArrayInputStream("Hello".getBytes(Charset.defaultCharset()))).readStdout().start(); p.join(); - assertEquals("Hello", org.apache.commons.io.IOUtils.toString(p.getStdout())); + assertEquals("Hello", org.apache.commons.io.IOUtils.toString(p.getStdout(), Charset.defaultCharset())); assertNull(p.getStderr()); assertNull(p.getStdin()); p = l.launch().cmds(ECHO_BACK_CMD).writeStdin().readStdout().start(); - p.getStdin().write("Hello".getBytes()); + p.getStdin().write("Hello".getBytes(Charset.defaultCharset())); p.getStdin().close(); p.join(); - assertEquals("Hello", org.apache.commons.io.IOUtils.toString(p.getStdout())); + assertEquals("Hello", org.apache.commons.io.IOUtils.toString(p.getStdout(), Charset.defaultCharset())); assertNull(p.getStderr()); } } diff --git a/test/src/test/java/hudson/XMLFileTest.java b/test/src/test/java/hudson/XMLFileTest.java index dc2e62c0b6e2..ef0ff15af79f 100644 --- a/test/src/test/java/hudson/XMLFileTest.java +++ b/test/src/test/java/hudson/XMLFileTest.java @@ -5,7 +5,8 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -39,7 +40,7 @@ public void silentlyMigrateConfigsTest() throws Exception { File configFile = new File(j.jenkins.getRootDir(), "config.xml"); assertThat(configFile.exists(), is(true)); - try (BufferedReader config = new BufferedReader(new FileReader(configFile))) { + try (BufferedReader config = Files.newBufferedReader(configFile.toPath(), StandardCharsets.UTF_8)) { assertThat(config.readLine(), is("")); } } diff --git a/test/src/test/java/hudson/cli/BuildCommandTest.java b/test/src/test/java/hudson/cli/BuildCommandTest.java index dd7723292ba9..9a3c5700a4cf 100644 --- a/test/src/test/java/hudson/cli/BuildCommandTest.java +++ b/test/src/test/java/hudson/cli/BuildCommandTest.java @@ -60,6 +60,7 @@ import hudson.util.OneShotEvent; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.Charset; import java.util.List; import net.sf.json.JSONObject; import org.junit.ClassRule; @@ -298,7 +299,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen } }); assertThat(new CLICommandInvoker(j, "build"). - withStdin(new ByteArrayInputStream("uploaded content here".getBytes())). + withStdin(new ByteArrayInputStream("uploaded content here".getBytes(Charset.defaultCharset()))). invokeWithArgs("-f", "-p", "file=", "myjob"), CLICommandInvoker.Matcher.succeeded()); FreeStyleBuild b = p.getBuildByNumber(1); diff --git a/test/src/test/java/hudson/cli/CLIActionTest.java b/test/src/test/java/hudson/cli/CLIActionTest.java index 800fa18f574f..8d2d4856368e 100644 --- a/test/src/test/java/hudson/cli/CLIActionTest.java +++ b/test/src/test/java/hudson/cli/CLIActionTest.java @@ -17,11 +17,13 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintWriter; import java.lang.reflect.Field; import java.net.HttpURLConnection; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -143,7 +145,7 @@ public void encodingAndLocale() throws Exception { "-webSocket", // TODO as above "-s", j.getURL().toString()./* just checking */replaceFirst("/$", ""), "test-diagnostic"). stdout(baos).stderr(System.err).join()); - assertEquals("encoding=ISO-8859-2 locale=cs_CZ", baos.toString().trim()); + assertEquals("encoding=ISO-8859-2 locale=cs_CZ", baos.toString(Charset.forName("ISO-8859-2").name()).trim()); // TODO test that stdout/stderr are in expected encoding (not true of -remoting mode!) // -ssh mode does not pass client locale or encoding } @@ -157,21 +159,21 @@ public void interleavedStdio() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutputStream(pis); - PrintWriter pw = new PrintWriter(new TeeOutputStream(pos, System.err), true); + PrintWriter pw = new PrintWriter(new OutputStreamWriter(new TeeOutputStream(pos, System.err), Charset.defaultCharset()), true); Proc proc = new Launcher.LocalLauncher(StreamTaskListener.fromStderr()).launch().cmds( "java", "-jar", jar.getAbsolutePath(), "-s", j.getURL().toString(), "-webSocket", // TODO as above "groovysh"). stdout(new TeeOutputStream(baos, System.out)).stderr(System.err).stdin(pis).start(); - while (!baos.toString().contains("000")) { // cannot just search for, say, "groovy:000> " since there are ANSI escapes there (cf. StringEscapeUtils.escapeJava) + while (!baos.toString(Charset.defaultCharset().name()).contains("000")) { // cannot just search for, say, "groovy:000> " since there are ANSI escapes there (cf. StringEscapeUtils.escapeJava) Thread.sleep(100); } pw.println("11 * 11"); - while (!baos.toString().contains("121")) { // ditto not "===> 121" + while (!baos.toString(Charset.defaultCharset().name()).contains("121")) { // ditto not "===> 121" Thread.sleep(100); } pw.println("11 * 11 * 11"); - while (!baos.toString().contains("1331")) { + while (!baos.toString(Charset.defaultCharset().name()).contains("1331")) { Thread.sleep(100); } pw.println(":q"); @@ -245,7 +247,7 @@ public void largeTransferWebSocket() throws Exception { "large-upload"). stdin(new NullInputStream(size)). stdout(baos).stderr(System.err).join()); - assertEquals("received " + size + " bytes", baos.toString().trim()); + assertEquals("received " + size + " bytes", baos.toString(Charset.defaultCharset().name()).trim()); } @TestExtension("largeTransferWebSocket") diff --git a/test/src/test/java/hudson/cli/CLIEnvVarTest.java b/test/src/test/java/hudson/cli/CLIEnvVarTest.java index 33c2a8f57261..eff0c985227c 100644 --- a/test/src/test/java/hudson/cli/CLIEnvVarTest.java +++ b/test/src/test/java/hudson/cli/CLIEnvVarTest.java @@ -15,6 +15,7 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.Charset; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -117,7 +118,7 @@ public void testAuthOptionWithoutEnvVars() throws Exception { "-auth", String.format("%s:%s", "admin", token), "who-am-i") ); - assertThat(baos.toString(), containsString("Authenticated as: admin")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("Authenticated as: admin")); } } @@ -134,7 +135,7 @@ public void testWithoutEnvVarsAndWithoutAuthOption() throws Exception { "-s", r.getURL().toString(), "who-am-i") ); - assertThat(baos.toString(), containsString("Authenticated as: anonymous")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("Authenticated as: anonymous")); } } @@ -152,7 +153,7 @@ public void testEnvVarsWithoutAuthOption() throws Exception { "-s", r.getURL().toString(), "who-am-i") ); - assertThat(baos.toString(), containsString("Authenticated as: admin")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("Authenticated as: admin")); } } @@ -203,7 +204,7 @@ public void testAuthOptionOverridesEnvVars() throws Exception { "-auth", String.format("%s:%s", "admin", token), "who-am-i") ); - assertThat(baos.toString(), containsString("Authenticated as: admin")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("Authenticated as: admin")); } } diff --git a/test/src/test/java/hudson/cli/CLITest.java b/test/src/test/java/hudson/cli/CLITest.java index d6537a918fba..30b02bc7ee24 100644 --- a/test/src/test/java/hudson/cli/CLITest.java +++ b/test/src/test/java/hudson/cli/CLITest.java @@ -43,6 +43,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.net.HttpURLConnection; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -107,7 +108,7 @@ private void doInterrupt(FreeStyleProject p, String... modeArgs) throws Exceptio args.addAll(Arrays.asList(modeArgs)); args.addAll(Arrays.asList("build", "-s", "-v", "p")); Proc proc = new Launcher.LocalLauncher(StreamTaskListener.fromStderr()).launch().cmds(args).stdout(new TeeOutputStream(baos, System.out)).stderr(System.err).start(); - while (!baos.toString().contains("Sleeping ")) { + while (!baos.toString(Charset.defaultCharset().name()).contains("Sleeping ")) { if (!proc.isAlive()) { throw new AssertionError("Process failed to start with " + proc.join()); } @@ -128,7 +129,7 @@ public void reportNotJenkins() throws Exception { "java", "-jar", jar.getAbsolutePath(), "-s", url, "-http", "-user", "asdf", "who-am-i" ).stdout(baos).stderr(baos).join(); - assertThat(baos.toString(), containsString("There's no Jenkins running at")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("There's no Jenkins running at")); assertNotEquals(0, ret); // TODO -webSocket currently produces a stack trace } @@ -186,7 +187,7 @@ public void redirectToEndpointShouldBeFollowed() throws Exception { ).stdout(baos).stderr(baos).join(); //assertThat(baos.toString(), containsString("There's no Jenkins running at")); - assertThat(baos.toString(), containsString("Authenticated as: anonymous")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("Authenticated as: anonymous")); assertEquals(0, ret); } } @@ -208,7 +209,7 @@ public void readInputAtOnce() throws Exception { .stderr(baos) .stdin(CLITest.class.getResourceAsStream("huge-stdin.txt")) .join(); - assertThat(baos.toString(), not(containsString("java.io.IOException: Stream is closed"))); + assertThat(baos.toString(Charset.defaultCharset().name()), not(containsString("java.io.IOException: Stream is closed"))); assertEquals(0, ret); } } diff --git a/test/src/test/java/hudson/cli/GetJobCommandTest.java b/test/src/test/java/hudson/cli/GetJobCommandTest.java index 440a1fc8c6df..4d8839fc2bec 100644 --- a/test/src/test/java/hudson/cli/GetJobCommandTest.java +++ b/test/src/test/java/hudson/cli/GetJobCommandTest.java @@ -24,14 +24,13 @@ package hudson.cli; -import static org.junit.Assert.assertEquals; +import static hudson.cli.CLICommandInvoker.Matcher.hasNoErrorOutput; +import static hudson.cli.CLICommandInvoker.Matcher.succeeded; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import hudson.model.FreeStyleProject; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.Collections; -import java.util.Locale; -import org.apache.commons.io.input.NullInputStream; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -40,27 +39,28 @@ public class GetJobCommandTest { + private CLICommandInvoker command; + @Rule public JenkinsRule j = new JenkinsRule(); + @Before + public void setUp() { + command = new CLICommandInvoker(j, new GetJobCommand()); + } + @Issue("JENKINS-20236") @Test public void withFolders() throws Exception { MockFolder d = j.createFolder("d"); FreeStyleProject p = d.createProject(FreeStyleProject.class, "p"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintStream outS = new PrintStream(out); - // TODO switch to CLICommandInvoker - int result = new GetJobCommand().main(Collections.singletonList("d/p"), Locale.ENGLISH, new NullInputStream(0), outS, outS); - outS.flush(); - String output = out.toString(); - assertEquals(output, 0, result); - assertEquals(p.getConfigFile().asString(), output); - out = new ByteArrayOutputStream(); - outS = new PrintStream(out); - result = new GetJobCommand().main(Collections.singletonList("d"), Locale.ENGLISH, new NullInputStream(0), outS, outS); - outS.flush(); - output = out.toString(); - assertEquals(output, 0, result); - assertEquals(d.getConfigFile().asString(), output); + CLICommandInvoker.Result result = command.invokeWithArgs("d/p"); + assertThat(result.stdout(), equalTo(p.getConfigFile().asString())); + assertThat(result, hasNoErrorOutput()); + assertThat(result, succeeded()); + + result = command.invokeWithArgs("d"); + assertThat(result.stdout(), equalTo(d.getConfigFile().asString())); + assertThat(result, hasNoErrorOutput()); + assertThat(result, succeeded()); } } diff --git a/test/src/test/java/hudson/cli/GroovyshCommandTest.java b/test/src/test/java/hudson/cli/GroovyshCommandTest.java index 5c5724ebdc39..d3b9264c808e 100644 --- a/test/src/test/java/hudson/cli/GroovyshCommandTest.java +++ b/test/src/test/java/hudson/cli/GroovyshCommandTest.java @@ -30,6 +30,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.io.ByteArrayInputStream; +import java.nio.charset.Charset; import jenkins.model.Jenkins; import org.junit.Rule; import org.junit.Test; @@ -44,7 +45,7 @@ public class GroovyshCommandTest { @Test public void authentication() { CLICommandInvoker.Result result = new CLICommandInvoker(r, new GroovyshCommand()) .authorizedTo(Jenkins.READ, Jenkins.ADMINISTER) - .withStdin(new ByteArrayInputStream("println(jenkins.model.Jenkins.instance.getClass().name)\n:quit\n".getBytes())) + .withStdin(new ByteArrayInputStream("println(jenkins.model.Jenkins.instance.getClass().name)\n:quit\n".getBytes(Charset.defaultCharset()))) .invoke(); assertThat(result, succeeded()); assertThat(result, hasNoErrorOutput()); diff --git a/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java b/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java index a287162a05d4..da82fb6534ba 100644 --- a/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java +++ b/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java @@ -38,8 +38,11 @@ import hudson.model.User; import hudson.tasks.Mailer; import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.io.UncheckedIOException; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import jenkins.model.Jenkins; import org.junit.Before; import org.junit.Ignore; @@ -184,16 +187,19 @@ private void reloadJenkinsConfigurationViaCliAndWait() { private void replace(String path, String search, String replace) { File configFile = new File(j.jenkins.getRootDir(), path); + String oldConfig; try { - String oldConfig = Util.loadFile(configFile); + oldConfig = Util.loadFile(configFile, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new UncheckedIOException(e); + } - String newConfig = oldConfig.replaceAll(search, replace); + String newConfig = oldConfig.replaceAll(search, replace); - FileWriter fw = new FileWriter(configFile); - fw.write(newConfig); - fw.close(); - } catch (IOException ex) { - throw new AssertionError(ex); + try (Writer writer = Files.newBufferedWriter(configFile.toPath(), StandardCharsets.UTF_8)) { + writer.write(newConfig); + } catch (IOException e) { + throw new UncheckedIOException(e); } } diff --git a/test/src/test/java/hudson/console/AnnotatedLargeTextTest.java b/test/src/test/java/hudson/console/AnnotatedLargeTextTest.java index 5556d95c2bc0..18b6f47b2e5d 100644 --- a/test/src/test/java/hudson/console/AnnotatedLargeTextTest.java +++ b/test/src/test/java/hudson/console/AnnotatedLargeTextTest.java @@ -57,14 +57,14 @@ public class AnnotatedLargeTextTest { @Test public void smokes() throws Exception { ByteBuffer buf = new ByteBuffer(); - PrintStream ps = new PrintStream(buf, true); + PrintStream ps = new PrintStream(buf, true, StandardCharsets.UTF_8.name()); ps.print("Some text.\n"); ps.print("Go back to " + TestNote.encodeTo("/root", "your home") + ".\n"); ps.print("More text.\n"); AnnotatedLargeText text = new AnnotatedLargeText<>(buf, StandardCharsets.UTF_8, true, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); text.writeLogTo(0, baos); - assertEquals("Some text.\nGo back to your home.\nMore text.\n", baos.toString()); + assertEquals("Some text.\nGo back to your home.\nMore text.\n", baos.toString(StandardCharsets.UTF_8.name())); StringWriter w = new StringWriter(); text.writeHtmlTo(0, w); assertEquals("Some text.\nGo back to your home.\nMore text.\n", w.toString()); @@ -83,11 +83,11 @@ public void oldDeserialization() throws Exception { + "v3+utadQyH8B+aJxVM4AAAA=" + ConsoleNote.POSTAMBLE_STR + "there\n") - .getBytes()); + .getBytes(StandardCharsets.UTF_8)); AnnotatedLargeText text = new AnnotatedLargeText<>(buf, StandardCharsets.UTF_8, true, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); text.writeLogTo(0, baos); - assertEquals("hellothere\n", baos.toString()); + assertEquals("hellothere\n", baos.toString(StandardCharsets.UTF_8.name())); StringWriter w = new StringWriter(); text.writeHtmlTo(0, w); assertEquals("hellothere\n", w.toString()); @@ -121,11 +121,11 @@ public void badMac() throws Exception { + "ABmN28qcAAAA" + ConsoleNote.POSTAMBLE_STR + "your home.\n") - .getBytes()); + .getBytes(StandardCharsets.UTF_8)); AnnotatedLargeText text = new AnnotatedLargeText<>(buf, StandardCharsets.UTF_8, true, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); text.writeLogTo(0, baos); - assertEquals("Go back to your home.\n", baos.toString()); + assertEquals("Go back to your home.\n", baos.toString(StandardCharsets.UTF_8.name())); StringWriter w = new StringWriter(); text.writeHtmlTo(0, w); assertEquals("Go back to your home.\n", w.toString()); diff --git a/test/src/test/java/hudson/console/ConsoleLogFilterTest.java b/test/src/test/java/hudson/console/ConsoleLogFilterTest.java index 8a21a80c6666..9e98e2771679 100644 --- a/test/src/test/java/hudson/console/ConsoleLogFilterTest.java +++ b/test/src/test/java/hudson/console/ConsoleLogFilterTest.java @@ -7,6 +7,7 @@ import hudson.slaves.SlaveComputer; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.Charset; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -42,7 +43,7 @@ public OutputStream decorateLogger(final Computer c, OutputStream out) { return new LineTransformationOutputStream.Delegating(out) { @Override protected void eol(byte[] b, int len) throws IOException { - out.write(("[[" + c.getName() + "]] ").getBytes()); + out.write(("[[" + c.getName() + "]] ").getBytes(Charset.defaultCharset())); out.write(b, 0, len); } }; diff --git a/test/src/test/java/hudson/model/AbstractProjectTest.java b/test/src/test/java/hudson/model/AbstractProjectTest.java index a5d9cc559146..0229069c0701 100644 --- a/test/src/test/java/hudson/model/AbstractProjectTest.java +++ b/test/src/test/java/hudson/model/AbstractProjectTest.java @@ -455,10 +455,10 @@ public void configDotXmlSubmissionToDifferentType() throws Exception { private HttpURLConnection postConfigDotXml(FreeStyleProject p, String xml) throws Exception { HttpURLConnection con = (HttpURLConnection) new URL(j.getURL(), "job/" + p.getName() + "/config.xml").openConnection(); con.setRequestMethod("POST"); - con.setRequestProperty("Content-Type", "application/xml"); + con.setRequestProperty("Content-Type", "application/xml; charset=utf-8"); con.setDoOutput(true); try (OutputStream s = con.getOutputStream()) { - s.write(xml.getBytes()); + s.write(xml.getBytes(StandardCharsets.UTF_8)); } return con; } diff --git a/test/src/test/java/hudson/model/CauseTest.java b/test/src/test/java/hudson/model/CauseTest.java index d5f779fed0af..90737294dca6 100644 --- a/test/src/test/java/hudson/model/CauseTest.java +++ b/test/src/test/java/hudson/model/CauseTest.java @@ -36,6 +36,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; @@ -96,29 +97,29 @@ public class CauseTest { @Issue("JENKINS-48467") - @Test public void userIdCausePrintTest() { + @Test public void userIdCausePrintTest() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - TaskListener listener = new StreamTaskListener(baos); + TaskListener listener = new StreamTaskListener(baos, Charset.defaultCharset()); //null userId - print unknown or anonymous Cause causeA = new Cause.UserIdCause(null); causeA.print(listener); - assertEquals("Started by user unknown or anonymous", baos.toString().trim()); + assertEquals("Started by user unknown or anonymous", baos.toString(Charset.defaultCharset().name()).trim()); baos.reset(); //SYSTEM userid - getDisplayName() should be SYSTEM Cause causeB = new Cause.UserIdCause(); causeB.print(listener); - assertThat(baos.toString(), containsString("SYSTEM")); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString("SYSTEM")); baos.reset(); //unknown userid - print unknown or anonymous Cause causeC = new Cause.UserIdCause("abc123"); causeC.print(listener); - assertEquals("Started by user unknown or anonymous", baos.toString().trim()); + assertEquals("Started by user unknown or anonymous", baos.toString(Charset.defaultCharset().name()).trim()); baos.reset(); //More or less standard operation @@ -127,7 +128,7 @@ public class CauseTest { Cause causeD = new Cause.UserIdCause(user.getId()); causeD.print(listener); - assertThat(baos.toString(), containsString(user.getDisplayName())); + assertThat(baos.toString(Charset.defaultCharset().name()), containsString(user.getDisplayName())); baos.reset(); } diff --git a/test/src/test/java/hudson/model/FingerprintCleanupThreadTest.java b/test/src/test/java/hudson/model/FingerprintCleanupThreadTest.java index 5ea2dc99f2c4..9a30b0f5c3d8 100644 --- a/test/src/test/java/hudson/model/FingerprintCleanupThreadTest.java +++ b/test/src/test/java/hudson/model/FingerprintCleanupThreadTest.java @@ -41,6 +41,8 @@ import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -71,7 +73,7 @@ public void testDoesNotLogUnimportantExcessiveLogMessage() throws IOException { configureLocalTestStorage(new TestFingerprint(true)); FingerprintCleanupThread cleanupThread = new FingerprintCleanupThread(); cleanupThread.execute(testTaskListener); - String logOutput = testTaskListener.outputStream.toString(); + String logOutput = testTaskListener.outputStream.toString(Charset.defaultCharset().name()); assertFalse("Should not have logged unimportant, excessive message.", logOutput.contains("possibly trimming")); } @@ -82,7 +84,7 @@ public void testFingerprintFileIsEmpty() throws IOException { configureLocalTestStorage(new TestFingerprint(false)); FingerprintCleanupThread cleanupThread = new FingerprintCleanupThread(); cleanupThread.execute(testTaskListener); - String logOutput = testTaskListener.outputStream.toString(); + String logOutput = testTaskListener.outputStream.toString(Charset.defaultCharset().name()); assertFalse("Should have deleted obsolete file.", fpFile.toFile().exists()); } @@ -99,7 +101,7 @@ public void testNoFingerprintsDir() throws IOException { configureLocalTestStorage(new TestFingerprint()); FingerprintCleanupThread cleanupThread = new FingerprintCleanupThread(); cleanupThread.execute(testTaskListener); - String logOutput = testTaskListener.outputStream.toString(); + String logOutput = testTaskListener.outputStream.toString(Charset.defaultCharset().name()); assertTrue("Should have done nothing.", logOutput.startsWith("Cleaned up 0 records")); } @@ -114,7 +116,7 @@ public void testBlockingFacetBlocksDeletion() throws IOException { configureLocalTestStorage(fp); FingerprintCleanupThread cleanupThread = new FingerprintCleanupThread(); cleanupThread.execute(testTaskListener); - String logOutput = testTaskListener.outputStream.toString(); + String logOutput = testTaskListener.outputStream.toString(Charset.defaultCharset().name()); assertThat(logOutput, containsString("blocked deletion of")); } @@ -219,8 +221,16 @@ private void createTestDir() throws IOException { private static class TestTaskListener implements TaskListener { - private ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - private PrintStream logStream = new PrintStream(outputStream); + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + private final PrintStream logStream; + + { + try { + logStream = new PrintStream(outputStream, false, Charset.defaultCharset().name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } + } @NonNull @Override diff --git a/test/src/test/java/hudson/model/FreeStyleProjectTest.java b/test/src/test/java/hudson/model/FreeStyleProjectTest.java index 705042905190..655facdc0aea 100644 --- a/test/src/test/java/hudson/model/FreeStyleProjectTest.java +++ b/test/src/test/java/hudson/model/FreeStyleProjectTest.java @@ -48,6 +48,7 @@ import hudson.tasks.Shell; import java.io.ByteArrayInputStream; import java.io.File; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import jenkins.model.Jenkins; @@ -129,7 +130,7 @@ public void customWorkspaceVariableExpansion() throws Exception { @Issue("JENKINS-15817") public void minimalConfigXml() throws Exception { // Make sure it can be created without exceptions: - FreeStyleProject project = (FreeStyleProject) j.jenkins.createProjectFromXML("stuff", new ByteArrayInputStream("".getBytes())); + FreeStyleProject project = (FreeStyleProject) j.jenkins.createProjectFromXML("stuff", new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); System.out.println(project.getConfigFile().asString()); // and round-tripped: Shell shell = new Shell("echo hello"); @@ -253,7 +254,7 @@ public void submitPossibleWithJellyTrace() throws Exception { public void cannotCreateJobWithTrailingDot_withoutOtherJob() throws Exception { assertThat(j.jenkins.getItems(), hasSize(0)); try { - j.jenkins.createProjectFromXML("jobA.", new ByteArrayInputStream("".getBytes())); + j.jenkins.createProjectFromXML("jobA.", new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); fail("Adding the job should have thrown an exception during checkGoodName"); } catch (Failure e) { @@ -269,7 +270,7 @@ public void cannotCreateJobWithTrailingDot_withExistingJob() throws Exception { j.createFreeStyleProject("jobA"); assertThat(j.jenkins.getItems(), hasSize(1)); try { - j.jenkins.createProjectFromXML("jobA.", new ByteArrayInputStream("".getBytes())); + j.jenkins.createProjectFromXML("jobA.", new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); fail("Adding the job should have thrown an exception during checkGoodName"); } catch (Failure e) { @@ -285,7 +286,7 @@ public void cannotCreateJobWithTrailingDot_withExistingJob() throws Exception { System.setProperty(propName, "false"); try { assertThat(j.jenkins.getItems(), hasSize(0)); - j.jenkins.createProjectFromXML("jobA.", new ByteArrayInputStream("".getBytes())); + j.jenkins.createProjectFromXML("jobA.", new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); } finally { if (initialValue == null) { diff --git a/test/src/test/java/hudson/model/ItemGroupMixInTest.java b/test/src/test/java/hudson/model/ItemGroupMixInTest.java index ee058c03093b..db80be293e7f 100644 --- a/test/src/test/java/hudson/model/ItemGroupMixInTest.java +++ b/test/src/test/java/hudson/model/ItemGroupMixInTest.java @@ -49,6 +49,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; import java.util.Map; @@ -95,13 +96,13 @@ public void xmlFileFailsToLoad() throws Exception { File configFile = project.getConfigFile().getFile(); - List lines = FileUtils.readLines(configFile).subList(0, 5); + List lines = FileUtils.readLines(configFile, StandardCharsets.UTF_8).subList(0, 5); configFile.delete(); // Remove half of the config.xml file to make "invalid" or fail to load - FileUtils.writeByteArrayToFile(configFile, lines.toString().getBytes()); + FileUtils.writeByteArrayToFile(configFile, lines.toString().getBytes(StandardCharsets.UTF_8)); for (int i = lines.size() / 2; i < lines.size(); i++) { - FileUtils.writeStringToFile(configFile, lines.get(i), true); + FileUtils.writeStringToFile(configFile, lines.get(i), StandardCharsets.UTF_8, true); } // Reload Jenkins. @@ -212,7 +213,7 @@ public boolean isApplicable(Class jobType) { " \n" + ""; - Item foo = r.jenkins.createProjectFromXML("foo", new ByteArrayInputStream(xml.getBytes())); + Item foo = r.jenkins.createProjectFromXML("foo", new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); // if no exception then JAXP is swallowing these - so there should be no entity in the description. assertThat(Items.getConfigFile(foo).asString(), containsString("")); } @@ -261,7 +262,7 @@ public void createProjectFromXML_checkGoodName() { ""; Failure exception = assertThrows(Failure.class, () -> { - r.jenkins.createProjectFromXML(badName, new ByteArrayInputStream(xml.getBytes())); + r.jenkins.createProjectFromXML(badName, new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); }); assertEquals(exception.getMessage(), Messages.Hudson_UnsafeChar("@")); } diff --git a/test/src/test/java/hudson/model/JobTest.java b/test/src/test/java/hudson/model/JobTest.java index f4aa9a3ae030..4d03ab278e24 100644 --- a/test/src/test/java/hudson/model/JobTest.java +++ b/test/src/test/java/hudson/model/JobTest.java @@ -53,6 +53,7 @@ import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; +import java.nio.charset.Charset; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; @@ -375,7 +376,7 @@ private static void tryConfigDotXml(JenkinsRule.WebClient wc, int status, String FreeStyleBuild b2 = p2.getBuilds().getLastBuild(); ByteArrayOutputStream out = new ByteArrayOutputStream(); b2.getLogText().writeRawLogTo(0, out); - final String oldB2Log = out.toString(); + final String oldB2Log = out.toString(Charset.defaultCharset().name()); assertTrue(b2.getArtifactManager().root().child("hello.txt").exists()); f.renameTo("something-else"); @@ -392,7 +393,7 @@ private static void tryConfigDotXml(JenkinsRule.WebClient wc, int status, String assertNotNull(b2); out = new ByteArrayOutputStream(); b2.getLogText().writeRawLogTo(0, out); - final String newB2Log = out.toString(); + final String newB2Log = out.toString(Charset.defaultCharset().name()); assertEquals(oldB2Log, newB2Log); assertTrue(b2.getArtifactManager().root().child("hello.txt").exists()); diff --git a/test/src/test/java/hudson/model/UpdateSiteTest.java b/test/src/test/java/hudson/model/UpdateSiteTest.java index 872719de443c..d95b97dce6cb 100644 --- a/test/src/test/java/hudson/model/UpdateSiteTest.java +++ b/test/src/test/java/hudson/model/UpdateSiteTest.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -99,7 +100,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques baseRequest.setHandled(true); response.setContentType("text/plain; charset=utf-8"); response.setStatus(HttpServletResponse.SC_OK); - response.getOutputStream().write(responseBody.getBytes()); + response.getOutputStream().write(responseBody.getBytes(StandardCharsets.UTF_8)); } } }); diff --git a/test/src/test/java/hudson/model/listeners/ItemListenerTest.java b/test/src/test/java/hudson/model/listeners/ItemListenerTest.java index 4aaf67460c3b..6209790f1a97 100644 --- a/test/src/test/java/hudson/model/listeners/ItemListenerTest.java +++ b/test/src/test/java/hudson/model/listeners/ItemListenerTest.java @@ -31,6 +31,7 @@ import hudson.cli.CLICommandInvoker; import hudson.model.Item; import java.io.ByteArrayInputStream; +import java.nio.charset.Charset; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -64,7 +65,7 @@ public void setUp() { @Test public void onCreatedViaCLI() { CLICommandInvoker.Result result = new CLICommandInvoker(j, "create-job"). - withStdin(new ByteArrayInputStream("".getBytes())). + withStdin(new ByteArrayInputStream("".getBytes(Charset.defaultCharset()))). invokeWithArgs("testJob"); assertThat(result, CLICommandInvoker.Matcher.succeeded()); assertNotNull("job should be created: " + result, j.jenkins.getItem("testJob")); diff --git a/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java b/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java index 81066c9a3664..7481fecbf71d 100644 --- a/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java +++ b/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java @@ -14,6 +14,7 @@ import com.gargoylesoftware.htmlunit.util.Cookie; import com.gargoylesoftware.htmlunit.xml.XmlPage; import hudson.model.User; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Base64; import java.util.Collections; @@ -336,7 +337,7 @@ private Cookie createRememberMeCookie(TokenBasedRememberMeServices2 tokenService HudsonPrivateSecurityRealm.Details details = user.getProperty(HudsonPrivateSecurityRealm.Details.class); String signatureValue = tokenService.makeTokenSignature(expiryTime, details.getUsername(), details.getPassword()); String tokenValue = user.getId() + ":" + expiryTime + ":" + signatureValue; - String tokenValueBase64 = Base64.getEncoder().encodeToString(tokenValue.getBytes()); + String tokenValueBase64 = Base64.getEncoder().encodeToString(tokenValue.getBytes(StandardCharsets.UTF_8)); return new Cookie(j.getURL().getHost(), tokenService.getCookieName(), tokenValueBase64); } diff --git a/test/src/test/java/hudson/triggers/TriggerStartTest.java b/test/src/test/java/hudson/triggers/TriggerStartTest.java index 7434b458d82d..e3aa8fdc474d 100644 --- a/test/src/test/java/hudson/triggers/TriggerStartTest.java +++ b/test/src/test/java/hudson/triggers/TriggerStartTest.java @@ -34,6 +34,7 @@ import java.io.ByteArrayInputStream; import java.io.ObjectStreamException; import java.io.StringReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import javax.xml.transform.Source; @@ -84,7 +85,9 @@ public class TriggerStartTest { } @Test public void createProjectFromXmlCallsStartTrue() throws Exception { - FreeStyleProject p = (FreeStyleProject) j.jenkins.createProjectFromXML("whatever", new ByteArrayInputStream(("\n \n \n \n" + triggersSection() + "").getBytes())); + FreeStyleProject p = (FreeStyleProject) j.jenkins.createProjectFromXML( + "whatever", + new ByteArrayInputStream(("\n \n \n \n" + triggersSection() + "").getBytes(StandardCharsets.UTF_8))); MockTrigger t = p.getTrigger(MockTrigger.class); assertNotNull(t); assertEquals("[true]", t.calls.toString()); diff --git a/test/src/test/java/hudson/triggers/TriggerTest.java b/test/src/test/java/hudson/triggers/TriggerTest.java index d39d56285bd3..6638a96d23ab 100644 --- a/test/src/test/java/hudson/triggers/TriggerTest.java +++ b/test/src/test/java/hudson/triggers/TriggerTest.java @@ -28,6 +28,7 @@ import hudson.Extension; import hudson.model.Item; import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; import java.util.Calendar; import java.util.GregorianCalendar; import org.junit.Rule; @@ -44,7 +45,7 @@ public class TriggerTest { @Issue("JENKINS-36748") @Test public void testNoNPE() throws Exception { - jenkinsRule.getInstance().createProjectFromXML("whatever", new ByteArrayInputStream(("\n \n \n \n" + triggersSection() + "").getBytes())); + jenkinsRule.getInstance().createProjectFromXML("whatever", new ByteArrayInputStream(("\n \n \n \n" + triggersSection() + "").getBytes(StandardCharsets.UTF_8))); final Calendar cal = new GregorianCalendar(); Trigger.checkTriggers(cal); } diff --git a/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java b/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java index d6decd9cc562..897fa0947c88 100644 --- a/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java +++ b/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java @@ -39,6 +39,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.StringWriter; +import java.nio.charset.Charset; import java.util.logging.Level; import jenkins.util.SystemProperties; import org.apache.tools.ant.util.JavaEnvUtils; @@ -135,7 +136,7 @@ public String echoArgs(String... arguments) throws Exception { .toWindowsCommand(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - final StreamTaskListener listener = new StreamTaskListener(out); + final StreamTaskListener listener = new StreamTaskListener(out, Charset.defaultCharset()); Proc p = new LocalLauncher(listener) .launch() .stderr(System.err) @@ -147,6 +148,6 @@ public String echoArgs(String... arguments) throws Exception { listener.close(); assumeThat("Failed to run " + args, code, equalTo(0)); - return out.toString(); + return out.toString(Charset.defaultCharset().name()); } } diff --git a/test/src/test/java/hudson/util/RobustReflectionConverterTest.java b/test/src/test/java/hudson/util/RobustReflectionConverterTest.java index 0d165a6d7482..eeffdf6a0871 100644 --- a/test/src/test/java/hudson/util/RobustReflectionConverterTest.java +++ b/test/src/test/java/hudson/util/RobustReflectionConverterTest.java @@ -47,6 +47,7 @@ import java.io.ByteArrayInputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.Charset; import java.util.Collections; import java.util.Map; import jenkins.model.Jenkins; @@ -271,7 +272,7 @@ public void testCliFailure() throws Exception { CLICommandInvoker.Result ret = new CLICommandInvoker(r, "update-job") .asUser("test") - .withStdin(new ByteArrayInputStream(String.format(CONFIGURATION_TEMPLATE, "badvalue", AcceptOnlySpecificKeyword.ACCEPT_KEYWORD).getBytes())) + .withStdin(new ByteArrayInputStream(String.format(CONFIGURATION_TEMPLATE, "badvalue", AcceptOnlySpecificKeyword.ACCEPT_KEYWORD).getBytes(Charset.defaultCharset()))) .withArgs( p.getFullName() ) @@ -303,7 +304,7 @@ public void testCliFailure() throws Exception { r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); CLICommandInvoker.Result ret = new CLICommandInvoker(r, "update-job") .asUser("test") - .withStdin(new ByteArrayInputStream(String.format(CONFIGURATION_TEMPLATE, AcceptOnlySpecificKeyword.ACCEPT_KEYWORD, "badvalue").getBytes())) + .withStdin(new ByteArrayInputStream(String.format(CONFIGURATION_TEMPLATE, AcceptOnlySpecificKeyword.ACCEPT_KEYWORD, "badvalue").getBytes(Charset.defaultCharset()))) .withArgs( p.getFullName() ) diff --git a/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java b/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java index 3b82cd784e62..d26883f5a28a 100644 --- a/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java +++ b/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java @@ -38,6 +38,7 @@ import hudson.tasks.BatchFile; import hudson.tasks.Shell; import java.io.File; +import java.nio.charset.StandardCharsets; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; @@ -136,7 +137,7 @@ private FatTask() { @Override public String call() { - return new String(payload); + return new String(payload, StandardCharsets.UTF_8); } } diff --git a/test/src/test/java/jenkins/install/SetupWizardTest.java b/test/src/test/java/jenkins/install/SetupWizardTest.java index 02c33f0e7b74..23664e0961c0 100644 --- a/test/src/test/java/jenkins/install/SetupWizardTest.java +++ b/test/src/test/java/jenkins/install/SetupWizardTest.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -89,7 +90,7 @@ public void initSetupWizard() throws IOException, InterruptedException { final FilePath adminPassFile = wizard.getInitialAdminPasswordFile(); ByteArrayOutputStream ostream = new ByteArrayOutputStream(); adminPassFile.copyTo(ostream); - final String password = ostream.toString(); + final String password = ostream.toString(StandardCharsets.UTF_8.name()); } @Test @@ -351,7 +352,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques baseRequest.setHandled(true); response.setContentType("text/plain; charset=utf-8"); response.setStatus(HttpServletResponse.SC_OK); - response.getOutputStream().write(responseBody.getBytes()); + response.getOutputStream().write(responseBody.getBytes(StandardCharsets.UTF_8)); } else { response.sendError(404); } @@ -456,7 +457,7 @@ private static class CustomJSONSignatureValidator extends JSONSignatureValidator protected Set loadTrustAnchors(CertificateFactory cf) throws IOException { Set trustAnchors = new HashSet<>(); try { - Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(cert.getBytes())); + Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(cert.getBytes(StandardCharsets.UTF_8))); trustAnchors.add(new TrustAnchor((X509Certificate) certificate, null)); } catch (CertificateException ex) { throw new IOException(ex); diff --git a/test/src/test/java/jenkins/model/JenkinsReloadConfigurationTest.java b/test/src/test/java/jenkins/model/JenkinsReloadConfigurationTest.java index d6a224fa44a7..a783ff67f052 100644 --- a/test/src/test/java/jenkins/model/JenkinsReloadConfigurationTest.java +++ b/test/src/test/java/jenkins/model/JenkinsReloadConfigurationTest.java @@ -9,8 +9,11 @@ import hudson.model.User; import hudson.tasks.Mailer; import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.io.UncheckedIOException; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -126,16 +129,19 @@ private Mailer.DescriptorImpl mailerDescriptor() { private void replace(String path, String search, String replace) { File configFile = new File(j.jenkins.getRootDir(), path); + String oldConfig; try { - String oldConfig = Util.loadFile(configFile); + oldConfig = Util.loadFile(configFile, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new UncheckedIOException(e); + } - String newConfig = oldConfig.replaceAll(search, replace); + String newConfig = oldConfig.replaceAll(search, replace); - FileWriter fw = new FileWriter(configFile); - fw.write(newConfig); - fw.close(); - } catch (IOException ex) { - throw new AssertionError(ex); + try (Writer writer = Files.newBufferedWriter(configFile.toPath(), StandardCharsets.UTF_8)) { + writer.write(newConfig); + } catch (IOException e) { + throw new UncheckedIOException(e); } } } diff --git a/test/src/test/java/jenkins/model/NodeListenerTest.java b/test/src/test/java/jenkins/model/NodeListenerTest.java index b387acd751a0..d6241ff13d61 100644 --- a/test/src/test/java/jenkins/model/NodeListenerTest.java +++ b/test/src/test/java/jenkins/model/NodeListenerTest.java @@ -15,6 +15,7 @@ import hudson.cli.UpdateNodeCommand; import hudson.model.Node; import java.io.ByteArrayInputStream; +import java.nio.charset.Charset; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -36,10 +37,10 @@ public void setUp() { public void crud() throws Exception { Node agent = j.createSlave(); String xml = cli(new GetNodeCommand()).invokeWithArgs(agent.getNodeName()).stdout(); - cli(new UpdateNodeCommand()).withStdin(new ByteArrayInputStream(xml.getBytes())).invokeWithArgs(agent.getNodeName()); + cli(new UpdateNodeCommand()).withStdin(new ByteArrayInputStream(xml.getBytes(Charset.defaultCharset()))).invokeWithArgs(agent.getNodeName()); cli(new DeleteNodeCommand()).invokeWithArgs(agent.getNodeName()); - cli(new CreateNodeCommand()).withStdin(new ByteArrayInputStream(xml.getBytes())).invokeWithArgs("replica"); + cli(new CreateNodeCommand()).withStdin(new ByteArrayInputStream(xml.getBytes(Charset.defaultCharset()))).invokeWithArgs("replica"); j.jenkins.getComputer("replica").doDoDelete(); verify(mock, times(2)).onCreated(any(Node.class)); diff --git a/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java b/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java index 1bb7d62974c7..0ff44e3a26dc 100644 --- a/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java +++ b/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java @@ -89,7 +89,7 @@ public void decorateHome(JenkinsRule jenkinsRule, File home) throws Exception { private static void putSomeOldData(File dir) throws Exception { File xml = new File(dir, "foo.xml"); - FileUtils.writeStringToFile(xml, "" + encryptOld(TEST_KEY) + ""); + FileUtils.writeStringToFile(xml, "" + encryptOld(TEST_KEY) + "", StandardCharsets.UTF_8); } private void verifyRewrite(File dir) throws Exception { @@ -177,7 +177,7 @@ public void testScanOnBoot() throws Exception { private static String encryptOld(String str) throws Exception { Cipher cipher = Secret.getCipher("AES"); cipher.init(Cipher.ENCRYPT_MODE, Util.toAes128Key(TEST_KEY)); - return new String(Base64.getEncoder().encode(cipher.doFinal((str + "::::MAGIC::::").getBytes(StandardCharsets.UTF_8)))); + return Base64.getEncoder().encodeToString(cipher.doFinal((str + "::::MAGIC::::").getBytes(StandardCharsets.UTF_8))); } private String encryptNew(String str) { diff --git a/test/src/test/java/jenkins/tasks/SimpleBuildWrapperTest.java b/test/src/test/java/jenkins/tasks/SimpleBuildWrapperTest.java index f930d05700a9..92718a081445 100644 --- a/test/src/test/java/jenkins/tasks/SimpleBuildWrapperTest.java +++ b/test/src/test/java/jenkins/tasks/SimpleBuildWrapperTest.java @@ -58,6 +58,7 @@ import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; +import java.nio.charset.Charset; import java.util.Collections; import java.util.Locale; import org.junit.Assume; @@ -291,7 +292,7 @@ private static class UpcaseFilter extends ConsoleLogFilter implements Serializab @Override public OutputStream decorateLogger(AbstractBuild _ignore, OutputStream logger) throws IOException, InterruptedException { return new LineTransformationOutputStream.Delegating(logger) { @Override protected void eol(byte[] b, int len) throws IOException { - out.write(new String(b, 0, len).toUpperCase(Locale.ROOT).getBytes()); + out.write(new String(b, 0, len, Charset.defaultCharset()).toUpperCase(Locale.ROOT).getBytes(Charset.defaultCharset())); } }; } From 3b29e9d460381f83eba9e939f6053b8336d946f4 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 7 Jan 2022 06:29:55 -0800 Subject: [PATCH 11/14] Fix more `DM_DEFAULT_ENCODING` SpotBugs violations (#6098) --- core/src/main/java/hudson/FilePath.java | 3 +-- core/src/main/java/hudson/cli/CLICommand.java | 7 ++++++- .../main/java/hudson/cli/GroovyCommand.java | 3 ++- .../main/java/hudson/cli/GroovyshCommand.java | 3 ++- .../java/hudson/cli/ListChangesCommand.java | 3 ++- .../lifecycle/WindowsServiceLifecycle.java | 7 +++++-- .../java/hudson/model/StreamBuildListener.java | 6 ++++++ core/src/main/java/hudson/os/SU.java | 5 +++-- .../java/hudson/util/StreamTaskListener.java | 18 ++++++++++++++++-- .../java/jenkins/diagnosis/HsErrPidList.java | 7 ++++--- .../slaves/DefaultJnlpSlaveReceiver.java | 6 ++++-- src/spotbugs/spotbugs-excludes.xml | 12 +----------- 12 files changed, 52 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index ca205d353b4e..8d0faa933453 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -70,7 +70,6 @@ import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; @@ -1656,7 +1655,7 @@ public String invoke(File dir, VirtualChannel channel) throws IOException { throw new IOException("Failed to create a temporary directory in " + dir, e); } - try (Writer w = new FileWriter(f)) { + try (Writer w = Files.newBufferedWriter(Util.fileToPath(f), Charset.defaultCharset())) { w.write(contents); } diff --git a/core/src/main/java/hudson/cli/CLICommand.java b/core/src/main/java/hudson/cli/CLICommand.java index 389f0bcbf71c..913003a8aefc 100644 --- a/core/src/main/java/hudson/cli/CLICommand.java +++ b/core/src/main/java/hudson/cli/CLICommand.java @@ -433,7 +433,12 @@ public final String getUsage() { @Restricted(NoExternalUse.class) public final String getLongDescription() { ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(out); + PrintStream ps; + try { + ps = new PrintStream(out, false, getClientCharset().name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } printUsageSummary(ps); ps.close(); diff --git a/core/src/main/java/hudson/cli/GroovyCommand.java b/core/src/main/java/hudson/cli/GroovyCommand.java index 066fd909fa86..0d7e45e6ca18 100644 --- a/core/src/main/java/hudson/cli/GroovyCommand.java +++ b/core/src/main/java/hudson/cli/GroovyCommand.java @@ -28,6 +28,7 @@ import groovy.lang.GroovyShell; import hudson.Extension; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -63,7 +64,7 @@ protected int run() throws Exception { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Binding binding = new Binding(); - binding.setProperty("out", new PrintWriter(stdout, true)); + binding.setProperty("out", new PrintWriter(new OutputStreamWriter(stdout, getClientCharset()), true)); binding.setProperty("stdin", stdin); binding.setProperty("stdout", stdout); binding.setProperty("stderr", stderr); diff --git a/core/src/main/java/hudson/cli/GroovyshCommand.java b/core/src/main/java/hudson/cli/GroovyshCommand.java index 75c0a9c18e37..f25a2544aa02 100644 --- a/core/src/main/java/hudson/cli/GroovyshCommand.java +++ b/core/src/main/java/hudson/cli/GroovyshCommand.java @@ -30,6 +30,7 @@ import hudson.Extension; import java.io.BufferedInputStream; import java.io.InputStream; +import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.PrintWriter; import java.util.ArrayList; @@ -84,7 +85,7 @@ protected Groovysh createShell(InputStream stdin, PrintStream stdout, Binding binding = new Binding(); // redirect "println" to the CLI - binding.setProperty("out", new PrintWriter(stdout, true)); + binding.setProperty("out", new PrintWriter(new OutputStreamWriter(stdout, getClientCharset()), true)); binding.setProperty("hudson", Jenkins.get()); // backward compatibility binding.setProperty("jenkins", Jenkins.get()); diff --git a/core/src/main/java/hudson/cli/ListChangesCommand.java b/core/src/main/java/hudson/cli/ListChangesCommand.java index 36b81e5630af..59c5b8c78904 100644 --- a/core/src/main/java/hudson/cli/ListChangesCommand.java +++ b/core/src/main/java/hudson/cli/ListChangesCommand.java @@ -5,6 +5,7 @@ import hudson.scm.ChangeLogSet; import hudson.util.QuotedStringTokenizer; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.List; import jenkins.scm.RunWithSCM; @@ -46,7 +47,7 @@ protected int act(List> builds) throws IOException { // No other permission check needed. switch (format) { case XML: - PrintWriter w = new PrintWriter(stdout); + PrintWriter w = new PrintWriter(new OutputStreamWriter(stdout, getClientCharset())); w.println(""); for (Run build : builds) { if (build instanceof RunWithSCM) { diff --git a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java index 08193532a274..961cf1358b52 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java @@ -33,9 +33,12 @@ import hudson.util.StreamTaskListener; import hudson.util.jna.Kernel32; import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; import java.net.URL; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; @@ -110,7 +113,7 @@ public void rewriteHudsonWar(File by) throws IOException { File baseDir = getBaseDir(); File copyFiles = new File(baseDir, baseName + ".copies"); - try (FileWriter w = new FileWriter(copyFiles, true)) { + try (Writer w = Files.newBufferedWriter(Util.fileToPath(copyFiles), Charset.defaultCharset(), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { w.write(by.getAbsolutePath() + '>' + getHudsonWar().getAbsolutePath() + '\n'); } } diff --git a/core/src/main/java/hudson/model/StreamBuildListener.java b/core/src/main/java/hudson/model/StreamBuildListener.java index 2b41ca48b0b8..efa1204fe11f 100644 --- a/core/src/main/java/hudson/model/StreamBuildListener.java +++ b/core/src/main/java/hudson/model/StreamBuildListener.java @@ -47,6 +47,12 @@ public StreamBuildListener(File out, Charset charset) throws IOException { super(out, charset); } + /** + * @deprecated as of TODO + * The caller should use {@link #StreamBuildListener(OutputStream, Charset)} to pass in + * the charset and output stream separately, so that this class can handle encoding correctly. + */ + @Deprecated public StreamBuildListener(OutputStream w) { super(w); } diff --git a/core/src/main/java/hudson/os/SU.java b/core/src/main/java/hudson/os/SU.java index 6ba5b055fd33..185110d83781 100644 --- a/core/src/main/java/hudson/os/SU.java +++ b/core/src/main/java/hudson/os/SU.java @@ -43,6 +43,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.nio.charset.Charset; import java.util.Collections; /** @@ -83,7 +84,7 @@ protected String sudoExe() { return "sudo"; } - @SuppressFBWarnings(value = {"COMMAND_INJECTION", "DM_DEFAULT_ENCODING"}, justification = "TODO needs triage") + @SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage") @Override protected Process sudoWithPass(ArgumentListBuilder args) throws IOException { args.prepend(sudoExe(), "-S"); @@ -92,7 +93,7 @@ protected Process sudoWithPass(ArgumentListBuilder args) throws IOException { Process p = pb.start(); // TODO: use -p to detect prompt // TODO: detect if the password didn't work - try (PrintStream ps = new PrintStream(p.getOutputStream())) { + try (PrintStream ps = new PrintStream(p.getOutputStream(), false, Charset.defaultCharset().name())) { ps.println(rootPassword); ps.println(rootPassword); ps.println(rootPassword); diff --git a/core/src/main/java/hudson/util/StreamTaskListener.java b/core/src/main/java/hudson/util/StreamTaskListener.java index 8f6698a4a85a..8aad40f5b599 100644 --- a/core/src/main/java/hudson/util/StreamTaskListener.java +++ b/core/src/main/java/hudson/util/StreamTaskListener.java @@ -76,6 +76,13 @@ public StreamTaskListener(@NonNull PrintStream out) { this(out, null); } + /** + * @deprecated as of TODO + * The caller should use {@link #StreamTaskListener(OutputStream, Charset)} to pass in + * the charset and output stream separately, so that this class can handle encoding correctly, + * or use {@link #fromStdout()} or {@link #fromStderr()}. + */ + @Deprecated public StreamTaskListener(@NonNull OutputStream out) { this(out, null); } @@ -83,7 +90,7 @@ public StreamTaskListener(@NonNull OutputStream out) { public StreamTaskListener(@NonNull OutputStream out, @CheckForNull Charset charset) { try { if (charset == null) - this.out = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out, false); + this.out = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out, false, Charset.defaultCharset().name()); else this.out = new PrintStream(out, false, charset.name()); this.charset = charset; @@ -93,6 +100,12 @@ public StreamTaskListener(@NonNull OutputStream out, @CheckForNull Charset chars } } + /** + * @deprecated as of TODO + * The caller should use {@link #StreamTaskListener(File, Charset)} to pass in + * the charset and file separately, so that this class can handle encoding correctly. + */ + @Deprecated public StreamTaskListener(@NonNull File out) throws IOException { this(out, null); } @@ -187,8 +200,9 @@ private void writeObject(ObjectOutputStream out) throws IOException { private static /* not final */ boolean AUTO_FLUSH = SystemProperties.getBoolean(KEY_AUTO_FLUSH); private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - out = new PrintStream((OutputStream) in.readObject(), AUTO_FLUSH); + OutputStream os = (OutputStream) in.readObject(); String name = (String) in.readObject(); + out = new PrintStream(os, AUTO_FLUSH, name != null ? name : Charset.defaultCharset().name()); charset = name == null ? null : Charset.forName(name); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, null, new Throwable("deserializing here with AUTO_FLUSH=" + AUTO_FLUSH)); diff --git a/core/src/main/java/jenkins/diagnosis/HsErrPidList.java b/core/src/main/java/jenkins/diagnosis/HsErrPidList.java index 49b2519c655a..a8a8566eb0c6 100644 --- a/core/src/main/java/jenkins/diagnosis/HsErrPidList.java +++ b/core/src/main/java/jenkins/diagnosis/HsErrPidList.java @@ -7,12 +7,13 @@ import hudson.util.jna.Kernel32Utils; import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; +import java.nio.charset.Charset; +import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.StandardOpenOption; import java.util.ArrayList; @@ -123,7 +124,7 @@ private void scan(String pattern) { private void scanFile(File log) { LOGGER.fine("Scanning " + log); - try (Reader rawReader = new FileReader(log); + try (Reader rawReader = Files.newBufferedReader(log.toPath(), Charset.defaultCharset()); BufferedReader r = new BufferedReader(rawReader)) { if (!findHeader(r)) @@ -140,7 +141,7 @@ private void scanFile(File log) { return; } } - } catch (IOException e) { + } catch (IOException | InvalidPathException e) { // not a big enough deal. LOGGER.log(Level.FINE, "Failed to parse hs_err_pid file: " + log, e); } diff --git a/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java b/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java index 00d0d7d1a4e2..dbe60372e961 100644 --- a/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java +++ b/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java @@ -16,10 +16,12 @@ import hudson.slaves.SlaveComputer; import java.io.IOException; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.channels.ClosedChannelException; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.concurrent.ExecutionException; @@ -152,7 +154,7 @@ public void beforeChannel(@NonNull JnlpConnectionState event) { final SlaveComputer computer = state.getNode(); final OutputStream log = computer.openLogFile(); state.setLog(log); - try (PrintWriter logw = new PrintWriter(log, true)) { + try (PrintWriter logw = new PrintWriter(new OutputStreamWriter(log, /* TODO switch agent logs to UTF-8 */ Charset.defaultCharset()), true)) { logw.println("Inbound agent connected from " + event.getRemoteEndpointDescription()); } for (ChannelConfigurator cc : ChannelConfigurator.all()) { @@ -172,7 +174,7 @@ public void afterChannel(@NonNull JnlpConnectionState event) { try { computer.setChannel(event.getChannel(), state.getLog(), null); } catch (IOException | InterruptedException e) { - PrintWriter logw = new PrintWriter(state.getLog(), true); + PrintWriter logw = new PrintWriter(new OutputStreamWriter(state.getLog(), /* TODO switch agent logs to UTF-8 */ Charset.defaultCharset()), true); Functions.printStackTrace(e, logw); try { event.getChannel().close(); diff --git a/src/spotbugs/spotbugs-excludes.xml b/src/spotbugs/spotbugs-excludes.xml index fc7fcf481dfb..4b78e8570b21 100644 --- a/src/spotbugs/spotbugs-excludes.xml +++ b/src/spotbugs/spotbugs-excludes.xml @@ -45,22 +45,12 @@ annotation indicating the reason why it is a false positive, then remove the exclusion from this section. - If it is not a false positive, fix the bug, then remove the exclusion from this section. - --> + --> - - - - - - - - - - From 936849e07d64a3783c4b7bfb75637d30588b2002 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Jan 2022 09:02:27 -0800 Subject: [PATCH 12/14] Bump `script-security` from 1118.vba21ca2e3286 to 1131.v8b_b_5eda_c328e (#6170) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index 336a6e6322ed..ad5cb291d233 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -68,7 +68,7 @@ THE SOFTWARE. org.jenkins-ci.plugins script-security - 1118.vba21ca2e3286 + 1131.v8b_b_5eda_c328e From bf81c201fbb71791ec9bbdf7d994d3c1abb51f36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Jan 2022 09:02:50 -0800 Subject: [PATCH 13/14] Bump `spotless-maven-plugin` from 2.19.0 to 2.19.1 (#6169) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 385c1363c51f..a48447ab85cb 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,7 @@ THE SOFTWARE. 1.23 5.8.2 4.2.0 - 2.19.0 + 2.19.1 From 64d0f15ee577f8bf4c69641c4d135cc15fb971d7 Mon Sep 17 00:00:00 2001 From: Tim Jacomb <21194782+timja@users.noreply.github.com> Date: Sat, 8 Jan 2022 17:03:04 +0000 Subject: [PATCH 14/14] Stop spamming logs when retrieving `AdminWhitelistRule` (#6128) --- core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java b/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java index 03622c94bc4e..303f901c9e1e 100644 --- a/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java +++ b/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java @@ -22,7 +22,6 @@ public AdminWhitelistRule() { } public boolean getMasterKillSwitch() { - LOGGER.log(WARNING, "AdminWhitelistRule no longer has any effect but an attempt was made to read its current configuration value. See https://www.jenkins.io/redirect/AdminWhitelistRule to learn more.", new Exception()); return false; }