Files
HMCL/HMCLBoot/src/main/java/org/jackhuang/hmcl/DesktopUtils.java
T
layue13 551bd4cef2
Mirror Repository / Mirror to CNB (push) Skipped
Mirror Repository / Mirror to Gitee (push) Skipped
Java CI / build (pull_request) Successful in 12m50s
fix: harden MultiMC/authlib/IO trust boundaries (#8–#13)
- #8: do not import MultiMC PreLaunch/Wrapper/JVM overrides from packs
- #9: filter dangerous +jvmArgs from MultiMC patches / lwjgl3ify
- #10: cap HTTP body reads at 16 MiB
- #11: guard FileUtils.copyDirectory against path escape
- #12: allow only http/https/mailto in openLink
- #13: follow authlib api-location only on same-host HTTPS
2026-11-09 21:19:30 +00:00

105 lines
3.2 KiB
Java

// SPDX-FileCopyrightText: Copyright (C) 2025 The HMCL Authors
// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL
package org.jackhuang.hmcl;
import java.io.File;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
/// @author Glavo
public final class DesktopUtils {
private static final String[] linuxBrowsers = {
"xdg-open",
"google-chrome",
"firefox",
"microsoft-edge",
"opera",
"konqueror",
"mozilla"
};
public static Path which(String command) {
String path = System.getenv("PATH");
if (path == null)
return null;
try {
for (String item : path.split(File.pathSeparator)) {
try {
Path program = Paths.get(item, command);
if (Files.isExecutable(program))
return program.toRealPath();
} catch (Throwable ignored) {
}
}
} catch (Throwable ignored) {
}
return null;
}
public static void openLink(String link) {
if (!isAllowedOpenLink(link)) {
System.err.println("Refusing to open link with disallowed scheme: " + link);
return;
}
String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT);
Throwable e1 = null;
try {
if (osName.startsWith("windows")) {
Runtime.getRuntime().exec(new String[]{"rundll32.exe", "url.dll,FileProtocolHandler", link});
return;
} else if (osName.startsWith("mac") || osName.startsWith("darwin")) {
Runtime.getRuntime().exec(new String[]{"open", link});
return;
} else {
for (String browser : linuxBrowsers) {
Path path = which(browser);
if (path != null) {
try {
Runtime.getRuntime().exec(new String[]{path.toString(), link});
return;
} catch (Throwable ignored) {
}
}
}
System.err.println("No known browser found");
}
} catch (Throwable e) {
e1 = e;
}
try {
java.awt.Desktop.getDesktop().browse(new URI(link));
} catch (Throwable e2) {
if (e1 != null)
e2.addSuppressed(e1);
e2.printStackTrace(System.err);
}
}
/// Only {@code http}/{@code https}/{@code mailto} may be handed to the OS URL handler.
static boolean isAllowedOpenLink(String link) {
try {
URI uri = new URI(link);
String scheme = uri.getScheme();
if (scheme == null) {
return false;
}
String lower = scheme.toLowerCase(Locale.ROOT);
return "http".equals(lower) || "https".equals(lower) || "mailto".equals(lower);
} catch (Exception e) {
return false;
}
}
private DesktopUtils() {
}
}