Skip to content

Commit 44fea4f

Browse files
authored
[JENKINS-71788] Fix timing of SecretPatterns.getAggregateSecretPattern (#314)
* [JENKINS-71788] Fix timing of `SecretPatterns.getAggregateSecretPattern` * Protect against possible race condition
1 parent 0a1c04c commit 44fea4f

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/main/java/com/datapipe/jenkins/vault/log/MaskingConsoleLogFilter.java

+15-9
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import java.io.IOException;
66
import java.io.OutputStream;
77
import java.io.Serializable;
8+
import java.util.ArrayList;
89
import java.util.List;
910
import java.util.Objects;
11+
import java.util.regex.Pattern;
1012
import java.util.stream.Collectors;
1113
import org.jenkinsci.plugins.credentialsbinding.masking.SecretPatterns;
1214

@@ -18,33 +20,37 @@ public class MaskingConsoleLogFilter extends ConsoleLogFilter
1820

1921
private final String charsetName;
2022
private final List<String> valuesToMask;
21-
23+
private Pattern pattern;
24+
private List<String> valuesToMaskInUse;
2225

2326
public MaskingConsoleLogFilter(final String charsetName,
2427
List<String> valuesToMask) {
2528
this.charsetName = charsetName;
2629
this.valuesToMask = valuesToMask;
30+
updatePattern();
31+
}
32+
33+
private synchronized Pattern updatePattern() {
34+
if (!valuesToMask.equals(valuesToMaskInUse)) {
35+
List<String> values = valuesToMask.stream().filter(Objects::nonNull).collect(Collectors.toList());
36+
pattern = values.isEmpty() ? null : SecretPatterns.getAggregateSecretPattern(values);
37+
valuesToMaskInUse = new ArrayList<>(valuesToMask);
38+
}
39+
return pattern;
2740
}
2841

2942
@Override
3043
public OutputStream decorateLogger(Run run,
3144
final OutputStream logger) throws IOException, InterruptedException {
3245
return new SecretPatterns.MaskingOutputStream(logger,
33-
() -> {
3446
// Only return a non-null pattern once there are secrets to mask. When a non-null
3547
// pattern is returned it is cached and not supplied again. In cases like
3648
// VaultBuildWrapper the secrets are added to the "valuesToMasker" list AFTER
3749
// construction AND AFTER the decorateLogger method is initially called, therefore
3850
// the Pattern should only be returned once the secrets have been made available.
3951
// Not to mention it is also a slight optimization when there is are no secrets
4052
// to mask.
41-
List<String> values = valuesToMask.stream().filter(Objects::nonNull).collect(Collectors.toList());
42-
if (!values.isEmpty()) {
43-
return SecretPatterns.getAggregateSecretPattern(values);
44-
} else {
45-
return null;
46-
}
47-
},
53+
this::updatePattern,
4854
charsetName);
4955
}
5056

0 commit comments

Comments
 (0)