Add subst resolution for Kotlin and Go extractors

This commit is contained in:
copilot-swe-agent[bot]
2026-07-02 08:22:53 +00:00
committed by GitHub
parent 5079680558
commit e34375c0cc
9 changed files with 290 additions and 4 deletions

View File

@@ -1242,12 +1242,13 @@ public class FileUtil
public static File tryMakeCanonical (File f)
{
try {
return f.getCanonicalFile();
f = f.getCanonicalFile();
}
catch (IOException ignored) {
Exceptions.ignore(ignored, "Can't log error: Could be too verbose.");
return new File(simplifyPath(f));
f = new File(simplifyPath(f));
}
return SubstResolver.resolve(f);
}

View File

@@ -0,0 +1,76 @@
package com.semmle.util.files;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Resolves Windows {@code subst}ed drive letters to their underlying paths. On non-Windows
* platforms, or when the native library failed to load, {@link #resolve(File)} is a no-op that
* returns its argument unchanged.
*/
public class SubstResolver {
private static final boolean available;
static {
boolean loaded = false;
if (File.separatorChar == '\\') {
String dist = System.getenv("CODEQL_DIST");
if (dist != null && !dist.isEmpty()) {
try {
Path library = Paths.get(dist).resolve("tools").resolve("win64")
.resolve("canonicalize.dll").toAbsolutePath();
System.load(library.toString());
loaded = true;
} catch (RuntimeException | UnsatisfiedLinkError ignored) {
}
}
}
available = loaded;
}
private SubstResolver() {}
/**
* Given a drive root like {@code "X:\\"}, returns the path that drive is
* {@code subst}ed to, or {@code null} if the letter isn't a subst mapping.
*/
private static native String nativeResolveSubst(String driveRoot);
/**
* If {@code f} is an absolute path starting with a {@code subst}ed drive letter, return an
* equivalent path with the drive letter replaced by its target. Otherwise return {@code f}
* unchanged.
*/
public static File resolve(File f) {
if (!available) {
return f;
}
String path = f.getPath();
if (path.length() < 3 || path.charAt(1) != ':') {
return f;
}
char sep = path.charAt(2);
if (sep != '\\' && sep != '/') {
return f;
}
if (!isDriveLetter(path.charAt(0))) {
return f;
}
String resolved = nativeResolveSubst(path.substring(0, 3));
if (resolved == null) {
return f;
}
return new File(resolved + path.substring(2));
}
private static boolean isDriveLetter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
public static boolean isAvailable() {
return available;
}
}