Use IndexOfAnyValues in ArchivingUtils (#79025)
authorMiha Zupan <mihazupan.zupan1@gmail.com>
Wed, 30 Nov 2022 16:57:23 +0000 (16:57 +0000)
committerGitHub <noreply@github.com>
Wed, 30 Nov 2022 16:57:23 +0000 (08:57 -0800)
src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs

index beceebc..73eddcc 100644 (file)
@@ -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)