Skip to content

Commit 11368be

Browse files
tjgqcopybara-github
authored andcommitted
Correctly report errors thrown by CommandLinePathFactory#create.
This method is called while initializing the remote module [1]. Any exceptions not derived from java.io.IOException cause a silent server crash. [1] https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/remote/RemoteModule.java;l=436;drc=f3211f00ae08746b5794ab01d404c32b43146aba Closes bazelbuild#16022. PiperOrigin-RevId: 464997904 Change-Id: I87fd5eaeb562d849bb830d68f1bfbbf06f6e0ea9
1 parent f4b5239 commit 11368be

File tree

2 files changed

+26
-24
lines changed

2 files changed

+26
-24
lines changed

src/main/java/com/google/devtools/build/lib/runtime/CommandLinePathFactory.java

+12-8
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@
3939
* (e.g., {@code %workspace%/foo} becomes {@code </path/to/workspace>/foo}).
4040
*/
4141
public final class CommandLinePathFactory {
42-
private static final Pattern REPLACEMENT_PATTERN = Pattern.compile("^(%([a-z_]+)%/)?([^%].*)$");
42+
/** An exception thrown while attempting to resolve a path. */
43+
public static class CommandLinePathFactoryException extends IOException {
44+
public CommandLinePathFactoryException(String message) {
45+
super(message);
46+
}
47+
}
48+
49+
private static final Pattern REPLACEMENT_PATTERN = Pattern.compile("^(%([a-z_]+)%/+)?([^%].*)$");
4350

4451
private static final Splitter PATH_SPLITTER = Splitter.on(File.pathSeparator);
4552

@@ -78,20 +85,17 @@ public Path create(Map<String, String> env, String value) throws IOException {
7885
String rootName = matcher.group(2);
7986
PathFragment path = PathFragment.create(matcher.group(3));
8087
if (path.containsUplevelReferences()) {
81-
throw new IllegalArgumentException(
88+
throw new CommandLinePathFactoryException(
8289
String.format(
8390
Locale.US, "Path must not contain any uplevel references ('..'), got '%s'", value));
8491
}
8592

8693
// Case 1: `path` is relative to a well-known root.
8794
if (!Strings.isNullOrEmpty(rootName)) {
88-
// The regex above cannot check that `value` is not of form `%foo%//abc` (group 2 will be
89-
// `foo` and group 3 will be `/abc`).
90-
Preconditions.checkArgument(!path.isAbsolute());
91-
9295
Path root = roots.get(rootName);
9396
if (root == null) {
94-
throw new IllegalArgumentException(String.format(Locale.US, "Unknown root %s", rootName));
97+
throw new CommandLinePathFactoryException(
98+
String.format(Locale.US, "Unknown root %s", rootName));
9599
}
96100
return root.getRelative(path);
97101
}
@@ -108,7 +112,7 @@ public Path create(Map<String, String> env, String value) throws IOException {
108112
// flag is from?), we only allow relative paths with a single segment (i.e., no `/`) and treat
109113
// it as relative to the user's `PATH`.
110114
if (path.segmentCount() > 1) {
111-
throw new IllegalArgumentException(
115+
throw new CommandLinePathFactoryException(
112116
"Path must either be absolute or not contain any path separators");
113117
}
114118

src/test/java/com/google/devtools/build/lib/runtime/CommandLinePathFactoryTest.java

+14-16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.common.base.Joiner;
2020
import com.google.common.base.Preconditions;
2121
import com.google.common.collect.ImmutableMap;
22+
import com.google.devtools.build.lib.runtime.CommandLinePathFactory.CommandLinePathFactoryException;
2223
import com.google.devtools.build.lib.vfs.DigestHashFunction;
2324
import com.google.devtools.build.lib.vfs.FileSystem;
2425
import com.google.devtools.build.lib.vfs.Path;
@@ -99,6 +100,9 @@ public void createWithNamedRoot() throws Exception {
99100
.isEqualTo(filesystem.getPath("/path/to/output/base/foo"));
100101
assertThat(factory.create(ImmutableMap.of(), "%output_base%/foo/bar"))
101102
.isEqualTo(filesystem.getPath("/path/to/output/base/foo/bar"));
103+
104+
assertThat(factory.create(ImmutableMap.of(), "%workspace%//foo//bar"))
105+
.isEqualTo(filesystem.getPath("/path/to/workspace/foo/bar"));
102106
}
103107

104108
@Test
@@ -108,9 +112,11 @@ public void pathLeakingOutsideOfRoot() {
108112
filesystem, ImmutableMap.of("a", filesystem.getPath("/path/to/a")));
109113

110114
assertThrows(
111-
IllegalArgumentException.class, () -> factory.create(ImmutableMap.of(), "%a%/../foo"));
115+
CommandLinePathFactoryException.class,
116+
() -> factory.create(ImmutableMap.of(), "%a%/../foo"));
112117
assertThrows(
113-
IllegalArgumentException.class, () -> factory.create(ImmutableMap.of(), "%a%/b/../.."));
118+
CommandLinePathFactoryException.class,
119+
() -> factory.create(ImmutableMap.of(), "%a%/b/../.."));
114120
}
115121

116122
@Test
@@ -120,29 +126,21 @@ public void unknownRoot() {
120126
filesystem, ImmutableMap.of("a", filesystem.getPath("/path/to/a")));
121127

122128
assertThrows(
123-
IllegalArgumentException.class, () -> factory.create(ImmutableMap.of(), "%workspace%/foo"));
129+
CommandLinePathFactoryException.class,
130+
() -> factory.create(ImmutableMap.of(), "%workspace%/foo"));
124131
assertThrows(
125-
IllegalArgumentException.class,
132+
CommandLinePathFactoryException.class,
126133
() -> factory.create(ImmutableMap.of(), "%output_base%/foo"));
127134
}
128135

129-
@Test
130-
public void rootWithDoubleSlash() {
131-
CommandLinePathFactory factory =
132-
new CommandLinePathFactory(
133-
filesystem, ImmutableMap.of("a", filesystem.getPath("/path/to/a")));
134-
135-
assertThrows(
136-
IllegalArgumentException.class, () -> factory.create(ImmutableMap.of(), "%a%//foo"));
137-
}
138-
139136
@Test
140137
public void relativePathWithMultipleSegments() {
141138
CommandLinePathFactory factory = new CommandLinePathFactory(filesystem, ImmutableMap.of());
142139

143-
assertThrows(IllegalArgumentException.class, () -> factory.create(ImmutableMap.of(), "a/b"));
144140
assertThrows(
145-
IllegalArgumentException.class, () -> factory.create(ImmutableMap.of(), "a/b/c/d"));
141+
CommandLinePathFactoryException.class, () -> factory.create(ImmutableMap.of(), "a/b"));
142+
assertThrows(
143+
CommandLinePathFactoryException.class, () -> factory.create(ImmutableMap.of(), "a/b/c/d"));
146144
}
147145

148146
@Test

0 commit comments

Comments
 (0)