Skip to content

Commit

Permalink
Use IndexOfAnyValues in ArchivingUtils (#79025)
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan authored Nov 30, 2022
1 parent 6772959 commit 063c18a
Showing 1 changed file with 26 additions and 28 deletions.
54 changes: 26 additions & 28 deletions src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Runtime.InteropServices;
using System.Text;

namespace System.IO
{
internal static partial class ArchivingUtils
{
private static readonly IndexOfAnyValues<char> s_illegalChars = IndexOfAnyValues.Create(
"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F" +
"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F" +
"\"*:<>?|");

internal static string SanitizeEntryFilePath(string entryPath)
{
// Find the first illegal character in the entry path.
for (int i = 0; i < entryPath.Length; i++)
int i = entryPath.AsSpan().IndexOfAny(s_illegalChars);
if (i < 0)
{
switch (entryPath[i])
{
// We found at least one character that needs to be replaced.
case < (char)32 or '?' or ':' or '*' or '"' or '<' or '>' or '|':
return string.Create(entryPath.Length, (i, entryPath), (dest, state) =>
{
string entryPath = state.entryPath;
// There weren't any characters to sanitize. Just return the original string.
return entryPath;
}

// We found at least one character that needs to be replaced.
return string.Create(entryPath.Length, (i, entryPath), static (dest, state) =>
{
string entryPath = state.entryPath;

// Copy over to the new string everything until the character, then
// substitute for the found character.
entryPath.AsSpan(0, state.i).CopyTo(dest);
dest[state.i] = '_';
// Copy over to the new string everything until the character, then
// substitute for the found character.
entryPath.AsSpan(0, state.i).CopyTo(dest);
dest[state.i] = '_';

// Continue looking for and replacing any more illegal characters.
for (int i = state.i + 1; i < entryPath.Length; i++)
{
char c = entryPath[i];
dest[i] = c switch
{
< (char)32 or '?' or ':' or '*' or '"' or '<' or '>' or '|' => '_',
_ => c,
};
}
});
// Continue looking for and replacing any more illegal characters.
for (int i = state.i + 1; i < entryPath.Length; i++)
{
char c = entryPath[i];
dest[i] = s_illegalChars.Contains(c) ? '_' : c;
}
}

// There weren't any characters to sanitize. Just return the original string.
return entryPath;
});
}

public static unsafe string EntryFromPath(ReadOnlySpan<char> path, bool appendPathSeparator = false)
Expand Down

0 comments on commit 063c18a

Please sign in to comment.