Skip to content

Commit d83b2dd

Browse files
authored
Merge pull request #851 from jglick/ArgumentsActionImpl-JENKINS-71926
[JENKINS-71926] Robustness against NULs in `ArgumentsActionImpl`
2 parents 7f65cc8 + 72f8929 commit d83b2dd

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/actions/ArgumentsActionImpl.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import hudson.model.Result;
3232
import java.util.Collection;
3333
import jenkins.model.Jenkins;
34-
import org.apache.commons.io.output.NullOutputStream;
3534
import org.jenkinsci.plugins.structs.describable.DescribableModel;
3635
import org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable;
3736
import org.jenkinsci.plugins.workflow.actions.ArgumentsAction;
@@ -41,6 +40,7 @@
4140

4241
import edu.umd.cs.findbugs.annotations.CheckForNull;
4342
import edu.umd.cs.findbugs.annotations.NonNull;
43+
import java.io.OutputStream;
4444
import java.lang.reflect.Type;
4545
import java.net.URL;
4646
import java.util.ArrayList;
@@ -240,6 +240,9 @@ Object sanitizeObjectAndRecordMutation(@CheckForNull Object o, @CheckForNull Env
240240
this.isUnmodifiedBySanitization = true;
241241
return NotStoredReason.UNSERIALIZABLE;
242242
}
243+
} else if (modded instanceof String && ((String) modded).contains("\0")) {
244+
this.isUnmodifiedBySanitization = false;
245+
return "<contains ASCII NUL>";
243246
} else if (modded instanceof String && vars != null && !vars.isEmpty()) {
244247
String replaced = replaceSensitiveVariables((String)modded, vars, sensitiveVariables);
245248
if (!replaced.equals(modded)) {
@@ -282,7 +285,7 @@ Map<String, Object> serializationCheck(@NonNull Map<String, Object> arguments) {
282285
try {
283286
if (val != null && !(val instanceof String) && !(val instanceof Boolean) && !(val instanceof Number) && !(val instanceof NotStoredReason) && !(val instanceof TimeUnit)) {
284287
// We only need to check serialization for nontrivial types
285-
Jenkins.XSTREAM2.toXMLUTF8(entry.getValue(), NullOutputStream.NULL_OUTPUT_STREAM); // Hacky but can't find a better way
288+
Jenkins.XSTREAM2.toXMLUTF8(entry.getValue(), OutputStream.nullOutputStream()); // Hacky but can't find a better way
286289
}
287290
out.put(entry.getKey(), entry.getValue());
288291
} catch (Exception ex) {

plugin/src/test/java/org/jenkinsci/plugins/workflow/cps/actions/ArgumentsActionImplTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import java.io.Serializable;
7171
import java.lang.reflect.Field;
7272
import java.lang.reflect.Method;
73+
import java.nio.file.Files;
7374
import java.time.temporal.ChronoUnit;
7475
import java.util.ArrayList;
7576
import java.util.Arrays;
@@ -566,6 +567,14 @@ public void simpleSemaphoreStep() throws Exception {
566567
testDeserialize(run.getExecution());
567568
}
568569

570+
@Test
571+
public void nul() throws Exception {
572+
var job = r.createProject(WorkflowJob.class);
573+
job.setDefinition(new CpsFlowDefinition("echo 'one\\0two'; echo 'this part is fine'", true));
574+
var store = r.buildAndAssertSuccess(job).getRootDir().toPath().resolve("workflow-completed/flowNodeStore.xml");
575+
assertThat(store + " was written", Files.readString(store), containsString("this part is fine"));
576+
}
577+
569578
@Test
570579
public void testArgumentDescriptions() throws Exception {
571580
WorkflowJob job = r.createProject(WorkflowJob.class);

0 commit comments

Comments
 (0)