Compare commits

..

2 Commits

Author SHA1 Message Date
Owen Mansel-Chan
cb4a1d0929 Merge pull request #22103 from owen-mc/java/fix-mad-file-names
Java: Fix misnamed MaD models files
2026-07-01 14:04:44 +01:00
Owen Mansel-Chan
7263c00b00 Fix misnamed MaD models files 2026-07-01 13:13:01 +01:00
15 changed files with 9 additions and 399 deletions

View File

@@ -56,19 +56,9 @@ codeql_pkg_files(
prefix = "tools/{CODEQL_PLATFORM}",
)
codeql_pkg_files(
name = "canonicalize-dll",
srcs = select({
"@platforms//os:windows": ["//shared/canonicalize:pkg"],
"//conditions:default": [],
}),
prefix = "tools/{CODEQL_PLATFORM}",
)
codeql_pack(
name = "go",
srcs = [
":canonicalize-dll",
":extractor-pack-arch",
":resources",
"//go/codeql-tools",

View File

@@ -16,7 +16,6 @@ go_library(
importpath = "github.com/github/codeql-go/extractor",
visibility = ["//visibility:public"],
deps = [
"//go/extractor/canonicalize",
"//go/extractor/dbscheme",
"//go/extractor/diagnostics",
"//go/extractor/srcarchive",

View File

@@ -1,11 +0,0 @@
load("@rules_go//go:def.bzl", "go_library")
go_library(
name = "canonicalize",
srcs = [
"canonicalize_other.go",
"canonicalize_windows.go",
],
importpath = "github.com/github/codeql-go/extractor/canonicalize",
visibility = ["//visibility:public"],
)

View File

@@ -1,5 +0,0 @@
//go:build !windows
package canonicalize
func CanonicalizePath(path string) string { return path }

View File

@@ -1,65 +0,0 @@
//go:build windows
package canonicalize
import (
"os"
"path/filepath"
"syscall"
"unsafe"
)
var (
dll *syscall.DLL
procCanonicalize *syscall.Proc
procFree *syscall.Proc
available bool
)
func init() {
root := os.Getenv("CODEQL_EXTRACTOR_GO_ROOT")
if root == "" {
return
}
dllPath := filepath.Join(root, "tools", "win64", "codeql_canonical_path.dll")
d, err := syscall.LoadDLL(dllPath)
if err != nil {
return
}
p, err := d.FindProc("canonicalize_path_u8")
if err != nil {
return
}
f, _ := d.FindProc("canonicalize_free_u8")
dll = d
procCanonicalize = p
procFree = f
available = true
}
func CanonicalizePath(path string) string {
if !available {
return path
}
pathBytes := append([]byte(path), 0)
ret, _, _ := procCanonicalize.Call(uintptr(unsafe.Pointer(&pathBytes[0])))
if ret == 0 {
return path
}
result := bytePtrToString((*byte)(unsafe.Pointer(ret)))
if procFree != nil {
procFree.Call(ret)
}
return result
}
func bytePtrToString(p *byte) string {
if p == nil {
return ""
}
var n int
for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {
ptr = unsafe.Add(ptr, 1)
}
return string(unsafe.Slice(p, n))
}

View File

@@ -22,7 +22,6 @@ import (
"sync"
"time"
"github.com/github/codeql-go/extractor/canonicalize"
"github.com/github/codeql-go/extractor/dbscheme"
"github.com/github/codeql-go/extractor/diagnostics"
"github.com/github/codeql-go/extractor/srcarchive"
@@ -767,7 +766,7 @@ func normalizedPath(ast *ast.File, fset *token.FileSet) string {
if err != nil {
return file
}
return canonicalize.CanonicalizePath(path)
return path
}
// extractFile extracts AST information for the given file

View File

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

View File

@@ -1,41 +0,0 @@
package com.semmle.util.files;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
public class NativeCanonicalizer {
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("codeql_canonical_path.dll").toAbsolutePath();
System.load(library.toString());
loaded = true;
} catch (RuntimeException | UnsatisfiedLinkError ignored) {
}
}
}
available = loaded;
}
private NativeCanonicalizer() {}
// UTF-16 JNI interface - no encoding conversion
private static native String nativeCanonicalizePath(String path);
public static File resolve(File path) {
if (!available) return path;
String result = nativeCanonicalizePath(path.getAbsolutePath());
return result != null ? new File(result) : path;
}
public static boolean isAvailable() {
return available;
}
}

View File

@@ -1,4 +1,10 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.apache.hc.client5.http.protocol", "RedirectLocations", True, "add", "(URI)", "", "Argument[0]", "Argument[this].Element", "value", "hq-manual"]
- addsTo:
pack: codeql/java-all
extensible: neutralModel

View File

@@ -1,6 +0,0 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.apache.hc.client5.http.protocol", "RedirectLocations", True, "add", "(URI)", "", "Argument[0]", "Argument[this].Element", "value", "hq-manual"]

View File

@@ -1,35 +0,0 @@
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_files")
cc_binary(
name = "codeql_canonical_path.dll",
srcs = [
"canonicalize.cpp",
"canonicalize.h",
"canonicalize_jni.cpp",
],
defines = ["CODEQL_CANONICALIZE_EXPORTS"],
linkopts = ["-lkernel32"],
linkshared = True,
target_compatible_with = ["@platforms//os:windows"],
visibility = ["//visibility:public"],
deps = ["@rules_java//toolchains:jni"],
)
cc_library(
name = "canonicalize",
srcs = ["canonicalize.cpp"],
hdrs = ["canonicalize.h"],
defines = ["CODEQL_CANONICALIZE_EXPORTS"],
linkopts = ["-lkernel32"],
target_compatible_with = ["@platforms//os:windows"],
visibility = ["//visibility:public"],
)
pkg_files(
name = "pkg",
srcs = [":codeql_canonical_path.dll"],
attributes = pkg_attributes(mode = "0755"),
target_compatible_with = ["@platforms//os:windows"],
visibility = ["//visibility:public"],
)

View File

@@ -1,165 +0,0 @@
#ifdef _WIN32
#include "canonicalize.h"
#include <windows.h>
#include <string>
#include <unordered_map>
#include <shared_mutex>
#include <random>
namespace {
class PathCache {
public:
static PathCache& instance() {
static PathCache cache;
return cache;
}
const wchar_t* canonicalize(const wchar_t* path) {
std::wstring key(path);
// Fast path: shared (read) lock for cache hit
{
std::shared_lock lock(mutex_);
auto it = cache_.find(key);
if (it != cache_.end()) {
return _wcsdup(it->second.c_str());
}
}
// Slow path: resolve and insert under exclusive lock
std::wstring resolved = resolve(path);
if (resolved.empty()) return nullptr;
std::unique_lock lock(mutex_);
// Check again under exclusive lock (another thread may have inserted)
auto it = cache_.find(key);
if (it != cache_.end()) {
return _wcsdup(it->second.c_str());
}
// Evict a random entry if at capacity (matches C# strategy)
if (cache_.size() >= max_capacity_) {
std::uniform_int_distribution<size_t> dist(0, cache_.size() - 1);
auto evict = cache_.begin();
std::advance(evict, dist(rng_));
cache_.erase(evict);
}
auto inserted = cache_.emplace(std::move(key), std::move(resolved)).first;
return _wcsdup(inserted->second.c_str());
}
private:
PathCache() = default;
static constexpr size_t max_capacity_ = 4096;
std::unordered_map<std::wstring, std::wstring> cache_;
std::shared_mutex mutex_;
std::mt19937 rng_{std::random_device{}()};
static std::wstring resolve(const wchar_t* path) {
HANDLE h = CreateFileW(
path,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
nullptr);
if (h == INVALID_HANDLE_VALUE) {
return resolve_nonexistent(path);
}
std::wstring result = get_final_path(h);
CloseHandle(h);
if (result.empty()) return {};
return strip_prefix(result);
}
static std::wstring get_final_path(HANDLE h) {
wchar_t buf[MAX_PATH];
DWORD len = GetFinalPathNameByHandleW(h, buf, MAX_PATH, FILE_NAME_NORMALIZED);
if (len > 0 && len < MAX_PATH) {
return std::wstring(buf, len);
}
if (len >= MAX_PATH) {
std::wstring big(len + 1, L'\0');
len = GetFinalPathNameByHandleW(h, big.data(), len + 1, FILE_NAME_NORMALIZED);
if (len > 0) return std::wstring(big.data(), len);
}
return {};
}
static std::wstring strip_prefix(const std::wstring& path) {
constexpr std::wstring_view unc_prefix = L"\\\\?\\UNC\\";
constexpr std::wstring_view lp_prefix = L"\\\\?\\";
if (path.starts_with(unc_prefix)) {
return L"\\" + path.substr(unc_prefix.size() - 1);
}
if (path.starts_with(lp_prefix)) {
return std::wstring(path.substr(lp_prefix.size()));
}
return path;
}
// For non-existent files: canonicalize parent, append filename
// (matches C#'s ConstructCanonicalPath)
static std::wstring resolve_nonexistent(const wchar_t* path) {
std::wstring spath(path);
auto sep = spath.find_last_of(L"\\/");
if (sep == std::wstring::npos) return {};
std::wstring parent = spath.substr(0, sep);
std::wstring name = spath.substr(sep + 1);
std::wstring canonical_parent = resolve(parent.c_str());
if (canonical_parent.empty()) return {};
return canonical_parent + L"\\" + name;
}
};
} // namespace
extern "C" {
CODEQL_API const wchar_t* canonicalize_path_w(const wchar_t* path) {
if (!path || !*path) return nullptr;
return PathCache::instance().canonicalize(path);
}
CODEQL_API void canonicalize_free_w(const wchar_t* path) {
free(const_cast<wchar_t*>(path));
}
CODEQL_API const char* canonicalize_path_u8(const char* path) {
if (!path || !*path) return nullptr;
int wlen = MultiByteToWideChar(CP_UTF8, 0, path, -1, nullptr, 0);
if (wlen <= 0) return nullptr;
std::wstring wpath(wlen - 1, L'\0');
MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath.data(), wlen);
const wchar_t* wresult = PathCache::instance().canonicalize(wpath.c_str());
if (!wresult) return nullptr;
int ulen = WideCharToMultiByte(CP_UTF8, 0, wresult, -1, nullptr, 0, nullptr, nullptr);
if (ulen <= 0) { free(const_cast<wchar_t*>(wresult)); return nullptr; }
char* result = static_cast<char*>(malloc(ulen));
WideCharToMultiByte(CP_UTF8, 0, wresult, -1, result, ulen, nullptr, nullptr);
free(const_cast<wchar_t*>(wresult));
return result;
}
CODEQL_API void canonicalize_free_u8(const char* path) {
free(const_cast<char*>(path));
}
} // extern "C"
#endif

View File

@@ -1,31 +0,0 @@
#ifndef CODEQL_CANONICALIZE_H
#define CODEQL_CANONICALIZE_H
#ifdef _WIN32
#ifdef CODEQL_CANONICALIZE_EXPORTS
#define CODEQL_API __declspec(dllexport)
#else
#define CODEQL_API __declspec(dllimport)
#endif
#include <wchar.h>
#ifdef __cplusplus
extern "C" {
#endif
// UTF-16 interface (for JNI / Java / Kotlin)
CODEQL_API const wchar_t* canonicalize_path_w(const wchar_t* path);
CODEQL_API void canonicalize_free_w(const wchar_t* path);
// UTF-8 interface (for Go)
CODEQL_API const char* canonicalize_path_u8(const char* path);
CODEQL_API void canonicalize_free_u8(const char* path);
#ifdef __cplusplus
}
#endif
#endif // _WIN32
#endif // CODEQL_CANONICALIZE_H

View File

@@ -1,25 +0,0 @@
#ifdef _WIN32
#include <jni.h>
#include "canonicalize.h"
extern "C" {
JNIEXPORT jstring JNICALL
Java_com_semmle_util_files_NativeCanonicalizer_nativeCanonicalizePath(
JNIEnv *env, jclass cls, jstring jpath) {
const jchar* path = env->GetStringChars(jpath, nullptr);
const wchar_t* result = canonicalize_path_w(reinterpret_cast<const wchar_t*>(path));
env->ReleaseStringChars(jpath, path);
if (result == nullptr) return nullptr;
jstring jresult = env->NewString(
reinterpret_cast<const jchar*>(result),
static_cast<jsize>(wcslen(result)));
canonicalize_free_w(result);
return jresult;
}
} // extern "C"
#endif