From d39df59044f9d240f16c12809431278e49d3779f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Musante?= <38815440+adrianmusante@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:38:14 -0300 Subject: [PATCH] JENKINS-52264 The variable "=" is removed when the exec command is executed (#219) --- .../docker/workflow/WithContainerStep.java | 5 +- .../workflow/WithContainerStepTest.java | 68 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java b/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java index 41f4910b3..ebbfd68a3 100644 --- a/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java +++ b/src/main/java/org/jenkinsci/plugins/docker/workflow/WithContainerStep.java @@ -286,10 +286,11 @@ private static class Decorator extends LauncherDecorator implements Serializable Set envReduced = new TreeSet(Arrays.asList(starter.envs())); envReduced.removeAll(Arrays.asList(envHost)); - // Remove PATH during `exec` as well. + // Remove PATH or invalid variable during `exec` as well. Iterator it = envReduced.iterator(); while (it.hasNext()) { - if (it.next().startsWith("PATH=")) { + final String envVar = it.next(); + if (envVar.startsWith("PATH=") || "=".equals(envVar.trim())) { it.remove(); } } diff --git a/src/test/java/org/jenkinsci/plugins/docker/workflow/WithContainerStepTest.java b/src/test/java/org/jenkinsci/plugins/docker/workflow/WithContainerStepTest.java index c5ddf141a..4c9a97447 100644 --- a/src/test/java/org/jenkinsci/plugins/docker/workflow/WithContainerStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/docker/workflow/WithContainerStepTest.java @@ -36,6 +36,7 @@ import hudson.util.ArgumentListBuilder; import hudson.util.Secret; import java.io.File; +import java.util.Collection; import java.util.Collections; import java.util.logging.Level; @@ -387,4 +388,71 @@ private static final class Execution extends SynchronousNonBlockingStepExecution } } + @Issue("JENKINS-52264") + @Test public void removeInvalidEnvVars() throws IOException { + story.then(r -> { + DockerTestUtil.assumeDocker(); + WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); + p.setDefinition(new CpsFlowDefinition( + "node {\n" + + " withDockerContainer('ubuntu') {\n" + + " removeInvalidEnvVarsStep([]) \n" + //without envVars to overwrite + " removeInvalidEnvVarsStep([\"other=only_valid_value\"]) \n" + //only valid envVar + " removeInvalidEnvVarsStep([\"=\", \"other=with_empty_var\"]) \n" + //with empty variable + " removeInvalidEnvVarsStep([\"PATH=ignored_value\", \"other=with_path\"]) \n" + //with PATH variable + " removeInvalidEnvVarsStep([\"=\", \"PATH=ignored_value\", \"other=with_path_and_empty\"]) \n" + //both invalid variables + " }\n" + + "}", true)); + WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0)); + story.j.assertLogContains("working with empty environment.", b); + story.j.assertLogContains("only_valid_value", b); + story.j.assertLogContains("with_empty_var", b); + story.j.assertLogContains("with_path", b); + story.j.assertLogContains("with_path_and_empty", b); + story.j.assertLogNotContains("ignored_value", b); + }); + } + public static final class RemoveInvalidEnvVarsStep extends Step { + public final Collection envVars; + @DataBoundConstructor public RemoveInvalidEnvVarsStep(Collection envVars) { + this.envVars = envVars; + } + @Override public StepExecution start(StepContext context) throws Exception { + return new Execution(context, envVars); + } + private static final class Execution extends SynchronousNonBlockingStepExecution { + private final Collection envVars; + Execution(StepContext context, Collection envVars) { + super(context); + this.envVars = envVars; + } + @Override protected Void run() throws Exception { + Launcher.ProcStarter ps = getContext().get(Launcher.class).launch(); + ps.envs(envVars.toArray(new String[0])); + ArgumentListBuilder args = new ArgumentListBuilder("sh", "-c"); + if(envVars.isEmpty()) { + args.add("echo working with empty environment."); + } else { + args.add("printenv other && printenv PATH"); + } + final int exitCode = ps + .cmds(args) + .stdout(getContext().get(TaskListener.class)) + .join(); + if (exitCode != 0) { + throw new IOException("failed to run exec command with vars: "+envVars); + } + return null; + } + } + @TestExtension("removeInvalidEnvVars") public static final class DescriptorImpl extends StepDescriptor { + @Override public String getFunctionName() { + return "removeInvalidEnvVarsStep"; + } + @Override public Set> getRequiredContext() { + return ImmutableSet.of(Launcher.class, TaskListener.class); + } + } + } + }