feat: add fnOS packaging, storage workflows and release pipeline
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
namespace dy.net.storage
|
||||
{
|
||||
public static class SafeLocalMigrationFile
|
||||
{
|
||||
public static bool TryResolve(string path, IEnumerable<string> allowedRoots, out string fullPath, out string error)
|
||||
{
|
||||
fullPath = null;
|
||||
error = null;
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
error = "本地路径为空";
|
||||
return false;
|
||||
}
|
||||
|
||||
try { fullPath = Path.GetFullPath(path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "本地路径无效:" + ex.Message;
|
||||
return false;
|
||||
}
|
||||
|
||||
var resolvedPath = fullPath;
|
||||
var root = (allowedRoots ?? Array.Empty<string>())
|
||||
.Select(Path.GetFullPath)
|
||||
.Where(candidate => IsWithin(resolvedPath, candidate))
|
||||
.OrderByDescending(x => x.Length)
|
||||
.FirstOrDefault();
|
||||
if (root == null)
|
||||
{
|
||||
error = "文件不在账号配置的旧存储根目录内";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
error = "本地文件不存在";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
for (var current = fullPath; !string.IsNullOrWhiteSpace(current); current = Path.GetDirectoryName(current))
|
||||
{
|
||||
FileSystemInfo info = File.Exists(current) ? new FileInfo(current) : new DirectoryInfo(current);
|
||||
if (!string.IsNullOrWhiteSpace(info.LinkTarget))
|
||||
{
|
||||
error = "旧文件路径包含符号链接,已拒绝迁移";
|
||||
return false;
|
||||
}
|
||||
if (string.Equals(current, root, StringComparison.Ordinal)) break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "无法验证旧文件路径:" + ex.Message;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsWithin(string candidate, string root)
|
||||
{
|
||||
var fullCandidate = Path.GetFullPath(candidate).TrimEnd(Path.DirectorySeparatorChar);
|
||||
var fullRoot = Path.GetFullPath(root).TrimEnd(Path.DirectorySeparatorChar);
|
||||
return string.Equals(fullCandidate, fullRoot, StringComparison.Ordinal)
|
||||
|| fullCandidate.StartsWith(fullRoot + Path.DirectorySeparatorChar, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user