fix: std path safety

This commit is contained in:
FalsePattern 2024-09-20 10:37:54 +02:00
parent 6848ed36b9
commit 30c87577fe
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
4 changed files with 59 additions and 19 deletions

View file

@ -17,6 +17,11 @@ Changelog structure reference:
## [Unreleased] ## [Unreleased]
### Fixed
- Project
- Safer standard library path resolution
## [17.1.0] ## [17.1.0]
### Fixed ### Fixed

View file

@ -147,7 +147,7 @@ public class ZigProjectSettingsPanel implements MyDisposable {
toolchainVersion.setForeground(JBColor.foreground()); toolchainVersion.setForeground(JBColor.foreground());
if (!stdFieldOverride.isSelected()) if (!stdFieldOverride.isSelected())
pathToStdField.setText(StringUtil.orEmpty(stdPath)); pathToStdField.setText(StringUtil.orEmpty(stdPath.toString()));
}); });
} }
} }

View file

@ -33,6 +33,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.swing.Icon; import javax.swing.Icon;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -49,11 +51,30 @@ public class ZigSyntheticLibrary extends SyntheticLibrary implements ItemPresent
val service = ZigProjectSettingsService.getInstance(project); val service = ZigProjectSettingsService.getInstance(project);
val state = service.getState(); val state = service.getState();
this.roots = ApplicationManager.getApplication().executeOnPooledThread(() -> { this.roots = ApplicationManager.getApplication().executeOnPooledThread(() -> {
var roots = pathToVFS(state.getExplicitPathToStd());
if (roots != null) {
return roots;
}
val toolchain = state.getToolchain(); val toolchain = state.getToolchain();
blk: try {
val ePathStr = state.getExplicitPathToStd();
if (ePathStr == null) {
break blk;
}
val ePath = Path.of(ePathStr);
if (ePath.isAbsolute()) {
var roots = pathToVFS(ePath);
if (roots != null) {
return roots;
}
} else if (toolchain != null) {
val stdPath = toolchain.getLocation().resolve(ePath);
if (stdPath.isAbsolute()) {
var roots = pathToVFS(stdPath);
if (roots != null) {
return roots;
}
}
}
} catch (InvalidPathException ignored) {
}
if (toolchain != null) { if (toolchain != null) {
val stdPath = val stdPath =
toolchain.zig().getStdPath().orElse(null); toolchain.zig().getStdPath().orElse(null);
@ -69,16 +90,13 @@ public class ZigSyntheticLibrary extends SyntheticLibrary implements ItemPresent
.orElse("Zig")); .orElse("Zig"));
} }
private static @Nullable Collection<VirtualFile> pathToVFS(String path) { private static @Nullable Collection<VirtualFile> pathToVFS(Path path) {
if (path != null && !path.isEmpty()) { if (path != null) {
val thePath = PathUtil.pathFromString(path); val file = VfsUtil.findFile(path, true);
if (thePath != null) { if (file != null) {
val file = VfsUtil.findFile(thePath, true); val children = file.getChildren();
if (file != null) { if (children != null && children.length > 0)
val children = file.getChildren(); return Arrays.asList(children);
if (children != null && children.length > 0)
return Arrays.asList(children);
}
} }
} }
return null; return null;
@ -86,7 +104,8 @@ public class ZigSyntheticLibrary extends SyntheticLibrary implements ItemPresent
@Override @Override
public @NotNull Collection<VirtualFile> getSourceRoots() { public @NotNull Collection<VirtualFile> getSourceRoots() {
try { try {
return roots.get(); val rootsRaw = roots.get();
return rootsRaw == null ? Collections.emptySet() : rootsRaw;
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
return Collections.emptySet(); return Collections.emptySet();

View file

@ -25,6 +25,7 @@ import com.intellij.openapi.application.ApplicationManager;
import lombok.val; import lombok.val;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -32,7 +33,7 @@ import java.util.concurrent.ExecutionException;
public class ZigCompilerTool extends AbstractZigTool{ public class ZigCompilerTool extends AbstractZigTool{
public static final String TOOL_NAME = "zig"; public static final String TOOL_NAME = "zig";
private final Lazy<Optional<String>> version; private final Lazy<Optional<String>> version;
private final Lazy<Optional<String>> stdPath; private final Lazy<Optional<Path>> stdPath;
public ZigCompilerTool(AbstractZigToolchain toolchain) { public ZigCompilerTool(AbstractZigToolchain toolchain) {
super(toolchain, TOOL_NAME); super(toolchain, TOOL_NAME);
@ -47,7 +48,22 @@ public class ZigCompilerTool extends AbstractZigTool{
}); });
stdPath = new Lazy<>(() -> { stdPath = new Lazy<>(() -> {
try { try {
return baseFuture.get().map(ZigToolchainEnvironmentSerializable::stdDirectory); return baseFuture.get().map(ZigToolchainEnvironmentSerializable::stdDirectory)
.map(pathStr -> {
try {
val path = Path.of(pathStr);
if (path.isAbsolute()) {
return path;
}
val resolvedPath = toolchain.getLocation().resolve(path);
if (resolvedPath.isAbsolute()) {
return resolvedPath;
}
return null;
} catch (InvalidPathException e) {
return null;
}
});
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
return Optional.empty(); return Optional.empty();
} }
@ -61,7 +77,7 @@ public class ZigCompilerTool extends AbstractZigTool{
} }
public Optional<String> getStdPath() { public Optional<Path> getStdPath() {
return stdPath.get(); return stdPath.get();
} }