Skip to content

Commit 9ffd8de

Browse files
committed
fix: constrain dependency download paths
1 parent 3ebabe8 commit 9ffd8de

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

Plain Craft Launcher 2/Modules/Minecraft/ModCompDependency.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,52 @@ public static List<DownloadFile> BuildDependencyDownloads(
202202
continue;
203203
}
204204

205-
var targetPath = Path.Combine(targetModsFolder ?? string.Empty, ModComp.CompFileNameGet(depProject, depCompFile));
205+
var targetPath = BuildSafeDependencyTargetPath(targetModsFolder, ModComp.CompFileNameGet(depProject, depCompFile));
206206
downloads.Add(depCompFile.ToNetFile(targetPath));
207207
}
208208

209209
return downloads;
210210
}
211211

212+
private static string BuildSafeDependencyTargetPath(string targetModsFolder, string fileName)
213+
{
214+
if (string.IsNullOrWhiteSpace(targetModsFolder))
215+
{
216+
throw new IOException("依赖下载路径无效");
217+
}
218+
219+
var safeFileName = SanitizeDependencyFileName(fileName);
220+
var targetRoot = Path.GetFullPath(targetModsFolder);
221+
var targetPath = Path.GetFullPath(Path.Combine(targetRoot, safeFileName));
222+
var normalizedRoot = targetRoot.EndsWith(Path.DirectorySeparatorChar) || targetRoot.EndsWith(Path.AltDirectorySeparatorChar)
223+
? targetRoot
224+
: targetRoot + Path.DirectorySeparatorChar;
225+
226+
if (!targetPath.StartsWith(normalizedRoot, StringComparison.OrdinalIgnoreCase))
227+
{
228+
throw new IOException("依赖下载路径无效");
229+
}
230+
231+
return targetPath;
232+
}
233+
234+
private static string SanitizeDependencyFileName(string fileName)
235+
{
236+
if (string.IsNullOrWhiteSpace(fileName))
237+
{
238+
return "dependency.jar";
239+
}
240+
241+
var invalidChars = Path.GetInvalidFileNameChars()
242+
.Concat(new[] { '/', '\\', ':', '*', '?', '"', '<', '>', '|' })
243+
.ToHashSet();
244+
var safeChars = fileName
245+
.Select(ch => invalidChars.Contains(ch) || char.IsControl(ch) ? '_' : ch)
246+
.ToArray();
247+
var safeFileName = new string(safeChars).Trim();
248+
return string.IsNullOrWhiteSpace(safeFileName) ? "dependency.jar" : safeFileName;
249+
}
250+
212251
/// <summary>
213252
/// Shows confirmation dialog for required dependency installs.
214253
/// Returns true if user confirms, false if user cancels or there are unresolved required deps.

0 commit comments

Comments
 (0)