Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,10 @@ private String createFilename(String environment, RunnerApi.ArtifactInformation
// all path separators.
List<String> components = Splitter.onPattern("[^A-Za-z-_.]]").splitToList(path);
String base = components.get(components.size() - 1);
String sanitizedEnvironment = environment.replaceAll("[<>:\"/\\\\|?*]", "_");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To avoid compiling the regular expression pattern on every invocation of createFilename, it is highly recommended to precompile the pattern as a private static final Pattern constant at the class level.

For example:

private static final Pattern INVALID_WINDOWS_CHARS = Pattern.compile("[<>:\"/\\\\|?*]");
Suggested change
String sanitizedEnvironment = environment.replaceAll("[<>:\"/\\\\|?*]", "_");
String sanitizedEnvironment = INVALID_WINDOWS_CHARS.matcher(environment).replaceAll("_");

return clip(
String.format("%s-%s-%s", idGenerator.getId(), clip(environment, 25), base), 100);
String.format("%s-%s-%s", idGenerator.getId(), clip(sanitizedEnvironment, 25), base),
100);
}

private String clip(String s, int maxLength) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,27 @@ public void testStageArtifacts() throws InterruptedException, ExecutionException
checkArtifacts(contentsList, staged.get("env2"));
}

@Test
public void testStageArtifactsWithInvalidFilenameCharacters()
throws InterruptedException, ExecutionException {
String environment = "0:ref_Environment_default";
List<String> contentsList = ImmutableList.of("artifact-content");

stagingService.registerJob(
"stagingToken",
ImmutableMap.of(
environment,
Lists.transform(contentsList, FakeArtifactRetrievalService::resolvedArtifact)));

ArtifactStagingService.offer(new FakeArtifactRetrievalService(), stagingStub, "stagingToken");

Map<String, List<RunnerApi.ArtifactInformation>> staged =
stagingService.getStagedArtifacts("stagingToken");

assertEquals(1, staged.size());
checkArtifacts(contentsList, staged.get(environment));
Comment on lines +186 to +187

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since : is a valid filename character on Unix-like operating systems (such as Linux and macOS), this test will pass on those platforms even without the sanitization fix. To ensure the test actually verifies the sanitization behavior across all platforms (including CI environments running on Linux), consider asserting that the physical file created in the staging directory contains the sanitized environment string (0_ref_Environment_default) and does not contain the colon (:).

}

private void checkArtifacts(
List<String> expectedContents, List<RunnerApi.ArtifactInformation> staged) {
assertEquals(
Expand Down
Loading