Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion Plain Craft Launcher 2/Modules/Minecraft/ModCompDependency.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,52 @@ public static List<DownloadFile> BuildDependencyDownloads(
continue;
}

var targetPath = Path.Combine(targetModsFolder ?? string.Empty, ModComp.CompFileNameGet(depProject, depCompFile));
var targetPath = BuildSafeDependencyTargetPath(targetModsFolder, ModComp.CompFileNameGet(depProject, depCompFile));
downloads.Add(depCompFile.ToNetFile(targetPath));
}

return downloads;
}

private static string BuildSafeDependencyTargetPath(string targetModsFolder, string fileName)
{
if (string.IsNullOrWhiteSpace(targetModsFolder))
{
throw new IOException("依赖下载路径无效");
}

var safeFileName = SanitizeDependencyFileName(fileName);
var targetRoot = Path.GetFullPath(targetModsFolder);
var targetPath = Path.GetFullPath(Path.Combine(targetRoot, safeFileName));
var normalizedRoot = targetRoot.EndsWith(Path.DirectorySeparatorChar) || targetRoot.EndsWith(Path.AltDirectorySeparatorChar)
? targetRoot
: targetRoot + Path.DirectorySeparatorChar;

if (!targetPath.StartsWith(normalizedRoot, StringComparison.OrdinalIgnoreCase))
{
throw new IOException("依赖下载路径无效");
}

return targetPath;
}

private static string SanitizeDependencyFileName(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return "dependency.jar";
}

var invalidChars = Path.GetInvalidFileNameChars()
.Concat(new[] { '/', '\\', ':', '*', '?', '"', '<', '>', '|' })
.ToHashSet();
var safeChars = fileName
.Select(ch => invalidChars.Contains(ch) || char.IsControl(ch) ? '_' : ch)
.ToArray();
var safeFileName = new string(safeChars).Trim();
return string.IsNullOrWhiteSpace(safeFileName) ? "dependency.jar" : safeFileName;
}

/// <summary>
/// Shows confirmation dialog for required dependency installs.
/// Returns true if user confirms, false if user cancels or there are unresolved required deps.
Expand Down
Loading