From 96e1f17aa9e5f7397726fd478f08c229cc727d3c Mon Sep 17 00:00:00 2001 From: Alexey 'Cluster' Avdyukhin Date: Tue, 11 Apr 2017 07:32:55 +0300 Subject: FTP server (seriously!) and many fixes --- FtpServer/FileSystemHelper.cs | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 FtpServer/FileSystemHelper.cs (limited to 'FtpServer/FileSystemHelper.cs') diff --git a/FtpServer/FileSystemHelper.cs b/FtpServer/FileSystemHelper.cs new file mode 100644 index 00000000..36cc4979 --- /dev/null +++ b/FtpServer/FileSystemHelper.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; + +namespace mooftpserv +{ + public class FileSystemHelper + { + /// Handles TVFS path resolution, similar to Path.GetFullPath(Path.Combine(basePath, path)) + public static string ResolvePath(string basePath, string path) + { + // CF is missing String.IsNullOrWhiteSpace + if (path == null || path.Trim() == "") + return null; + + // first, make a complete unix path + string fullPath; + if (path[0] == '/') { + fullPath = path; + } else { + fullPath = basePath; + if (!fullPath.EndsWith("/")) + fullPath += "/"; + fullPath += path; + } + + // then, remove ".." and "." + List tokens = new List(fullPath.Split('/')); + for (int i = 0; i < tokens.Count; ++i) { + if (tokens[i] == "") { + if (i == 0 || i == tokens.Count - 1) { + continue; // ignore, start and end should be empty tokens + } else { + tokens.RemoveAt(i); + --i; + } + } else if (tokens[i] == "..") { + if (i < 2) { + // cannot go higher than root, just remove the token + tokens.RemoveAt(i); + --i; + } else { + tokens.RemoveRange(i - 1, 2); + i -= 2; + } + } else if (i < tokens.Count - 1 && tokens[i].EndsWith(@"\")) { + int slashes = 0; + for (int c = tokens[i].Length - 1; c >= 0 && tokens[i][c] == '\\'; --c) + ++slashes; + + if (slashes % 2 != 0) { + // the slash was actually escaped, merge tokens + tokens[i] += ("/" + tokens[i + 1]); + ++i; + } + } + } + + if (tokens.Count > 1) + return String.Join("/", tokens.ToArray()); + else + return "/"; + } + + } +} + -- cgit v1.2.3