2018-11-03 21:21:36 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2019-07-03 16:21:29 +00:00
|
|
|
|
using System.IO;
|
2018-11-03 21:21:36 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace Roadie.Library.Utility
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
/// Cleans paths of invalid characters.
|
2018-11-03 21:21:36 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
public static class PathSanitizer
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
/// The set of invalid filename characters, kept sorted for fast binary search
|
2018-11-03 21:21:36 +00:00
|
|
|
|
/// </summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
private static readonly char[] invalidFilenameChars;
|
2018-11-03 21:21:36 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
/// The set of invalid path characters, kept sorted for fast binary search
|
2018-11-03 21:21:36 +00:00
|
|
|
|
/// </summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
private static readonly char[] invalidPathChars;
|
2018-11-03 21:21:36 +00:00
|
|
|
|
|
|
|
|
|
static PathSanitizer()
|
|
|
|
|
{
|
|
|
|
|
// set up the two arrays -- sorted once for speed.
|
|
|
|
|
var c = new List<char>();
|
2019-07-03 16:21:29 +00:00
|
|
|
|
c.AddRange(Path.GetInvalidFileNameChars());
|
2018-11-03 21:21:36 +00:00
|
|
|
|
|
|
|
|
|
// Some Roadie instances run in Linux to Windows SMB clients via Samba this helps with Windows clients and invalid characters in Windows
|
2019-11-09 17:43:39 +00:00
|
|
|
|
var badWindowsFileAndFoldercharacters = new List<char> { '\\', '"', '/', ':', '*', '$', '?', '\'', '<', '>', '|', '*' };
|
2018-11-03 21:21:36 +00:00
|
|
|
|
foreach (var badWindowsFilecharacter in badWindowsFileAndFoldercharacters)
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
if (!c.Contains(badWindowsFilecharacter))
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
c.Add(badWindowsFilecharacter);
|
2019-11-09 17:43:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-03 21:21:36 +00:00
|
|
|
|
invalidFilenameChars = c.ToArray();
|
|
|
|
|
|
|
|
|
|
var f = new List<char>();
|
2019-07-03 16:21:29 +00:00
|
|
|
|
f.AddRange(Path.GetInvalidPathChars());
|
2018-11-03 21:21:36 +00:00
|
|
|
|
foreach (var badWindowsFilecharacter in badWindowsFileAndFoldercharacters)
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
if (!f.Contains(badWindowsFilecharacter))
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
f.Add(badWindowsFilecharacter);
|
2019-11-09 17:43:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-03 21:21:36 +00:00
|
|
|
|
invalidFilenameChars = c.ToArray();
|
|
|
|
|
invalidPathChars = f.ToArray();
|
|
|
|
|
|
|
|
|
|
Array.Sort(invalidFilenameChars);
|
|
|
|
|
Array.Sort(invalidPathChars);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
/// Cleans a filename of invalid characters
|
2018-11-03 21:21:36 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input">the string to clean</param>
|
|
|
|
|
/// <param name="errorChar">the character which replaces bad characters</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string SanitizeFilename(string input, char errorChar)
|
|
|
|
|
{
|
|
|
|
|
return Sanitize(input, invalidFilenameChars, errorChar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
/// Cleans a path of invalid characters
|
2018-11-03 21:21:36 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input">the string to clean</param>
|
|
|
|
|
/// <param name="errorChar">the character which replaces bad characters</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string SanitizePath(string input, char errorChar)
|
|
|
|
|
{
|
|
|
|
|
return Sanitize(input, invalidPathChars, errorChar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-07-03 16:21:29 +00:00
|
|
|
|
/// Cleans a string of invalid characters.
|
2018-11-03 21:21:36 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <param name="invalidChars"></param>
|
|
|
|
|
/// <param name="errorChar"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static string Sanitize(string input, char[] invalidChars, char errorChar)
|
|
|
|
|
{
|
|
|
|
|
// null always sanitizes to null
|
2019-11-09 17:43:39 +00:00
|
|
|
|
if (input == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2019-07-03 16:21:29 +00:00
|
|
|
|
var result = new StringBuilder();
|
2018-11-03 21:21:36 +00:00
|
|
|
|
foreach (var characterToTest in input)
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
// we binary search for the character in the invalid set. This should be lightning fast.
|
|
|
|
|
if (Array.BinarySearch(invalidChars, characterToTest) >= 0)
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
// we found the character in the array of
|
|
|
|
|
result.Append(errorChar);
|
2019-11-09 17:43:39 +00:00
|
|
|
|
}
|
2018-11-03 21:21:36 +00:00
|
|
|
|
else
|
2019-11-09 17:43:39 +00:00
|
|
|
|
{
|
2018-11-03 21:21:36 +00:00
|
|
|
|
// the character was not found in invalid, so it is valid.
|
|
|
|
|
result.Append(characterToTest);
|
2019-11-09 17:43:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-03 21:21:36 +00:00
|
|
|
|
// we're done.
|
|
|
|
|
return result.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-04 20:33:37 +00:00
|
|
|
|
}
|