Audit culture bugs (#7707)

* Added comments and fixed CultureInfo /  StringComparison where appropriate

* Addressed comments

* Fixed comment
This commit is contained in:
Avneet Kaur 2020-10-30 16:43:09 -07:00 committed by GitHub
parent bd34127cd4
commit 2c5b9b4d52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 160 additions and 28 deletions

View File

@ -20,6 +20,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
Directory.CreateDirectory(ApplicationLogPath);
}
// Using InvariantCulture since this is used for a log file name
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));

View File

@ -45,7 +45,7 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
public static Mock<IIOProvider>GetModuleIOProvider(string version, string module, string fileName)
{
// Using StringComparison.Ordinal / CultureInfo.InvariantCulture since this is used internally
var stubSettingsPath = string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, module, fileName);
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains(module, StringComparison.Ordinal);
var mockIOProvider = IIOProviderMocks.GetMockIOReadWithStubFile(stubSettingsPath, filterExpression);
@ -59,6 +59,7 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
throw new ArgumentNullException(nameof(provider));
}
// Using Ordinal since this is used internally
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains(module, StringComparison.Ordinal);
IIOProviderMocks.VerifyIOReadWithStubFile(provider, filterExpression, expectedCallCount);
@ -66,6 +67,7 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
public static Mock<IIOProvider> GetGeneralSettingsIOProvider(string version)
{
// Using StringComparison.Ordinal / CultureInfo.InvariantCulture since this is used internally for a path
var stubGeneralSettingsPath = string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, string.Empty, "settings.json");
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
var mockGeneralIOProvider = IIOProviderMocks.GetMockIOReadWithStubFile(stubGeneralSettingsPath, filterExpression);
@ -78,7 +80,7 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
{
throw new ArgumentNullException(nameof(provider));
}
// Using Ordinal since this is used internally for a path
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
IIOProviderMocks.VerifyIOReadWithStubFile(provider, filterExpression, expectedCallCount);
}

View File

@ -26,11 +26,13 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.Mocks
savePath = path;
saveContent = content;
});
// Using Ordinal since this is used internally for a path
mockIOProvider.Setup(x => x.ReadAllText(It.Is<string>(x => x.Equals(savePath, StringComparison.Ordinal))))
.Returns(() => saveContent);
// Using Ordinal since this is used internally for a path
mockIOProvider.Setup(x => x.FileExists(It.Is<string>(x => x.Equals(savePath, StringComparison.Ordinal))))
.Returns(true);
// Using Ordinal since this is used internally for a path
mockIOProvider.Setup(x => x.FileExists(It.Is<string>(x => !x.Equals(savePath, StringComparison.Ordinal))))
.Returns(false);

View File

@ -167,6 +167,7 @@ namespace ViewModelTests
var settingUtils = ISettingsUtilsMocks.GetStubSettingsUtils<ImageResizerSettings>();
var expectedSettingsString = new ImageResizerSettings() { Properties = new ImageResizerProperties() { ImageresizerKeepDateModified = new BoolProperty() { Value = true } } }.ToJsonString();
// Using Ordinal since this is used internally
settingUtils.Setup(x => x.SaveSettings(
It.Is<string>(content => content.Equals(expectedSettingsString, StringComparison.Ordinal)),
It.Is<string>(module => module.Equals(ImageResizerSettings.ModuleName, StringComparison.Ordinal)),

View File

@ -66,6 +66,7 @@ namespace ColorPicker.Helpers
saturation = Math.Round(saturation * 100);
lightness = Math.Round(lightness * 100);
// Using InvariantCulture since this is used for color representation
return $"hsl({hue.ToString(CultureInfo.InvariantCulture)}"
+ $", {saturation.ToString(CultureInfo.InvariantCulture)}%"
+ $", {lightness.ToString(CultureInfo.InvariantCulture)}%)";
@ -84,6 +85,7 @@ namespace ColorPicker.Helpers
saturation = Math.Round(saturation * 100);
value = Math.Round(value * 100);
// Using InvariantCulture since this is used for color representation
return $"hsv({hue.ToString(CultureInfo.InvariantCulture)}"
+ $", {saturation.ToString(CultureInfo.InvariantCulture)}%"
+ $", {value.ToString(CultureInfo.InvariantCulture)}%)";
@ -103,6 +105,7 @@ namespace ColorPicker.Helpers
yellow = Math.Round(yellow * 100);
blackKey = Math.Round(blackKey * 100);
// Using InvariantCulture since this is used for color representation
return $"cmyk({cyan.ToString(CultureInfo.InvariantCulture)}%"
+ $", {magenta.ToString(CultureInfo.InvariantCulture)}%"
+ $", {yellow.ToString(CultureInfo.InvariantCulture)}%"

View File

@ -20,7 +20,8 @@ namespace ColorPicker.Helpers
Directory.CreateDirectory(ApplicationLogPath);
}
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.CurrentCulture) + ".txt");
// Using InvariantCulture since this is used for a log file name
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));

View File

@ -157,6 +157,8 @@ namespace FancyZonesEditor
sb.AppendLine("## " + CrashReportEnvironmentTag);
sb.AppendLine(CrashReportCommandLineTag + Environment.CommandLine);
// Using InvariantCulture since this is used for a timestamp internally
sb.AppendLine(CrashReportTimestampTag + DateTime.Now.ToString(CultureInfo.InvariantCulture));
sb.AppendLine(CrashReportOSVersionTag + Environment.OSVersion.VersionString);
sb.AppendLine(CrashReportIntPtrLengthTag + IntPtr.Size);

View File

@ -170,6 +170,7 @@ namespace ImageResizer.Properties
var result = ((IDataErrorInfo)settings)["JpegQualityLevel"];
// Using InvariantCulture since this is used internally
Assert.Equal(
string.Format(CultureInfo.InvariantCulture, Resources.ValueMustBeBetween, 1, 100),
result);

View File

@ -28,6 +28,7 @@ namespace ImageResizer.Views
var timeRemaining = new TimeSpan(hours, minutes, seconds);
var converter = new TimeRemainingConverter();
// Using InvariantCulture since these are internal
var result = converter.Convert(
timeRemaining,
targetType: null,

View File

@ -189,6 +189,7 @@ namespace ImageResizer.Models
extension = supportedExtensions.FirstOrDefault();
}
// Using CurrentCulture since this is user facing
var fileName = string.Format(
CultureInfo.CurrentCulture,
_settings.FileNameFormat,

View File

@ -63,6 +63,7 @@ namespace ImageResizer.Properties
public IEnumerable<ResizeSize> AllSizes { get; set; }
// Using OrdinalIgnoreCase since this is internal and used for comparison with symbols
public string FileNameFormat
=> _fileNameFormat
?? (_fileNameFormat = FileName
@ -111,6 +112,7 @@ namespace ImageResizer.Properties
if (JpegQualityLevel < 1 || JpegQualityLevel > 100)
{
// Using CurrentCulture since this is user facing
return string.Format(CultureInfo.CurrentCulture, Resources.ValueMustBeBetween, 1, 100);
}

View File

@ -68,6 +68,7 @@ namespace Microsoft.Plugin.Calculator.UnitTests
var engine = new CalculateEngine();
// Act
// Using InvariantCulture since this is internal
var result = engine.Interpret(input, CultureInfo.InvariantCulture);
// Assert
@ -84,6 +85,7 @@ namespace Microsoft.Plugin.Calculator.UnitTests
var engine = new CalculateEngine();
// Act
// Using InvariantCulture since this is internal
var result = engine.Interpret(input, CultureInfo.InvariantCulture);
// Assert
@ -140,6 +142,7 @@ namespace Microsoft.Plugin.Calculator.UnitTests
var engine = new CalculateEngine();
// Act
// Using InvariantCulture since this is internal
var result = engine.Interpret(input, CultureInfo.InvariantCulture);
// Assert
@ -158,6 +161,7 @@ namespace Microsoft.Plugin.Calculator.UnitTests
var engine = new CalculateEngine();
// Act
// Using InvariantCulture since this is internal
var result = engine.Interpret(input, CultureInfo.InvariantCulture);
// Assert

View File

@ -15,6 +15,7 @@ namespace Microsoft.Plugin.Calculator
public CalculateResult Interpret(string input)
{
// Using CurrentCulture this is user facing
return Interpret(input, CultureInfo.CurrentCulture);
}

View File

@ -35,6 +35,7 @@ namespace Microsoft.Plugin.Calculator
try
{
// Using CurrentUICulture since this is user facing
var result = CalculateEngine.Interpret(query.Search, CultureInfo.CurrentUICulture);
// This could happen for some incorrect queries, like pi(2)

View File

@ -27,6 +27,7 @@ namespace Microsoft.Plugin.Calculator
return new Result
{
// Using CurrentCulture since this is user facing
Title = roundedResult?.ToString(CultureInfo.CurrentCulture),
IcoPath = iconPath,
Score = 300,
@ -45,6 +46,7 @@ namespace Microsoft.Plugin.Calculator
{
try
{
// Using CurrentUICulture since this is user facing
Clipboard.SetText(roundedResult?.ToString(CultureInfo.CurrentUICulture.NumberFormat));
ret = true;
}

View File

@ -69,8 +69,10 @@ namespace Microsoft.Plugin.Folder.UnitTests
{
// Setup
var folderHelperMock = new Mock<IFolderHelper>();
// Using Ordinal since this is used with paths
folderHelperMock.Setup(r => r.IsDriveOrSharedFolder(It.IsAny<string>()))
.Returns<string>(s => s.StartsWith("C:", StringComparison.CurrentCultureIgnoreCase));
.Returns<string>(s => s.StartsWith("C:", StringComparison.Ordinal));
var itemResultMock = new Mock<IItemResult>();

View File

@ -73,15 +73,17 @@ namespace Microsoft.Plugin.Folder.UnitTests
switch (isRecursive)
{
case false:
folderSearchFunc = s => s.Equals(search, StringComparison.CurrentCultureIgnoreCase);
// Using Ordinal since this is internal
folderSearchFunc = s => s.Equals(search, StringComparison.Ordinal);
var regexSearch = TrimDirectoryEnd(search);
fileSearchFunc = s => Regex.IsMatch(s, $"^{Regex.Escape(regexSearch)}[^\\\\]*$");
break;
case true:
folderSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
fileSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
// Using Ordinal since this is internal
folderSearchFunc = s => s.StartsWith(search, StringComparison.Ordinal);
fileSearchFunc = s => s.StartsWith(search, StringComparison.Ordinal);
break;
}

View File

@ -17,6 +17,8 @@ namespace Microsoft.Plugin.Folder.Sources
private static IEnumerable<string> InitialDriverList()
{
var directorySeparatorChar = System.IO.Path.DirectorySeparatorChar;
// Using InvariantCulture since this is internal
return DriveInfo.GetDrives()
.Select(driver => driver.Name.ToLower(CultureInfo.InvariantCulture).TrimEnd(directorySeparatorChar));
}

View File

@ -27,6 +27,7 @@ namespace Microsoft.Plugin.Folder.Sources
throw new ArgumentNullException(paramName: nameof(query));
}
// Using OrdinalIgnoreCase since this is internal
return _folderLinks.FolderLinks()
.Where(x => x.Nickname.StartsWith(query, StringComparison.OrdinalIgnoreCase));
}
@ -38,7 +39,8 @@ namespace Microsoft.Plugin.Folder.Sources
throw new ArgumentNullException(nameof(search));
}
if (search.StartsWith(@"\\", StringComparison.InvariantCulture))
// Using Ordinal this is internal and we're comparing symbols
if (search.StartsWith(@"\\", StringComparison.Ordinal))
{ // share folder
return true;
}
@ -48,6 +50,7 @@ namespace Microsoft.Plugin.Folder.Sources
if (driverNames.Any())
{
// Using InvariantCultureIgnoreCase since this is searching for drive names
if (driverNames.Any(dn => search.StartsWith(dn, StringComparison.InvariantCultureIgnoreCase)))
{
// normal drive letter

View File

@ -60,6 +60,7 @@ namespace Microsoft.Plugin.Folder.Sources
}
// Remove everything after the last \ and add *
// Using InvariantCulture since this is internal
incompleteName = search.Substring(index + 1)
.ToLower(CultureInfo.InvariantCulture) + "*";
search = search.Substring(0, index + 1);
@ -71,7 +72,8 @@ namespace Microsoft.Plugin.Folder.Sources
else
{
// folder exist, add \ at the end of doesn't exist
if (!search.EndsWith(@"\", StringComparison.InvariantCulture))
// Using Ordinal since this is internal and is used for a symbol
if (!search.EndsWith(@"\", StringComparison.Ordinal))
{
search += @"\";
}

View File

@ -24,6 +24,8 @@ namespace Microsoft.Plugin.Folder.Sources.Result
var result = new Wox.Plugin.Result(StringMatcher.FuzzySearch(Search, Path.GetFileName(FilePath)).MatchData)
{
Title = Title,
// Using CurrentCulture since this is user facing
SubTitle = string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_folder_select_file_result_subtitle, FilePath),
IcoPath = FilePath,
Action = c => ShellAction.Execute(FilePath, contextApi),

View File

@ -37,6 +37,8 @@ namespace Microsoft.Plugin.Folder.Sources.Result
{
Title = Title,
IcoPath = Path,
// Using CurrentCulture since this is user facing
SubTitle = string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_folder_select_folder_result_subtitle, Subtitle),
QueryTextDisplay = Path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = Path },

View File

@ -23,6 +23,8 @@ namespace Microsoft.Plugin.Folder.Sources.Result
{
Title = Properties.Resources.Microsoft_plugin_folder_truncation_warning_title,
QueryTextDisplay = Search,
// Using CurrentCulture since this is user facing
SubTitle = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Microsoft_plugin_folder_truncation_warning_subtitle, PostTruncationCount, PreTruncationCount),
IcoPath = WarningIconPath,
};

View File

@ -39,7 +39,8 @@ namespace Microsoft.Plugin.Folder.Sources
var sanitizedPath = Regex.Replace(search, @"[\/\\]+", "\\");
// A network path must start with \\
if (!sanitizedPath.StartsWith("\\", StringComparison.InvariantCulture))
// Using Ordinal since this is internal and used with a symbol
if (!sanitizedPath.StartsWith("\\", StringComparison.Ordinal))
{
return sanitizedPath;
}

View File

@ -28,6 +28,8 @@ namespace Microsoft.Plugin.Folder
{
Title = Title,
IcoPath = Path,
// Using CurrentCulture since this is user facing
SubTitle = string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_folder_select_folder_result_subtitle, Subtitle),
QueryTextDisplay = Path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = Path },

View File

@ -150,6 +150,7 @@ namespace Microsoft.Plugin.Indexer
string fileExtension = Path.GetExtension(path);
foreach (string extension in appExtensions)
{
// Using OrdinalIgnoreCase since this is internal
if (extension.Equals(fileExtension, StringComparison.OrdinalIgnoreCase))
{
return true;

View File

@ -110,6 +110,8 @@ namespace Microsoft.Plugin.Indexer
foreach (var searchResult in searchResultsList)
{
var path = searchResult.Path;
// Using CurrentCulture since this is user facing
var toolTipTitle = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", Properties.Resources.Microsoft_plugin_indexer_name, searchResult.Title);
var toolTipText = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", Properties.Resources.Microsoft_plugin_indexer_path, path);
string workingDir = null;

View File

@ -59,6 +59,7 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
}
// # is URI syntax for the fragment component, need to be encoded so LocalPath returns complete path
// Using OrdinalIgnoreCase since this is internal and used with symbols
var string_path = ((string)oleDBResult.FieldData[0]).Replace("#", "%23", StringComparison.OrdinalIgnoreCase);
var uri_path = new Uri(string_path);
@ -89,10 +90,11 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
// convert file pattern if it is not '*'. Don't create restriction for '*' as it includes all files.
if (pattern != "*")
{
pattern = pattern.Replace("*", "%", StringComparison.InvariantCulture);
pattern = pattern.Replace("?", "_", StringComparison.InvariantCulture);
// Using Ordinal since these are internal and used with symbols
pattern = pattern.Replace("*", "%", StringComparison.Ordinal);
pattern = pattern.Replace("?", "_", StringComparison.Ordinal);
if (pattern.Contains("%", StringComparison.InvariantCulture) || pattern.Contains("_", StringComparison.InvariantCulture))
if (pattern.Contains("%", StringComparison.Ordinal) || pattern.Contains("_", StringComparison.Ordinal))
{
queryHelper.QueryWhereRestrictions += " AND System.FileName LIKE '" + pattern + "' ";
}

View File

@ -567,6 +567,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
var result = _cmderRunCommand.Result("cmder", string.Empty, mock.Object);
// Assert
// Using Ordinal since this is used internally
Assert.IsTrue(result.Title.Equals(_cmderRunCommand.Name, StringComparison.Ordinal));
Assert.IsFalse(result.Title.Equals(_cmderRunCommand.Description, StringComparison.Ordinal));
}

View File

@ -23,6 +23,7 @@ namespace Microsoft.Plugin.Program
{
for (var i = 1; i < query.Terms.Count; i++)
{
// Using Ordinal since this is internal and used with a symbol
if (!string.Equals(query.Terms[i], DoubleDash, StringComparison.Ordinal))
{
continue;

View File

@ -204,6 +204,7 @@ namespace Microsoft.Plugin.Program.Programs
{
if (obj is UWP uwp)
{
// Using CurrentCultureIgnoreCase since this is used with FamilyName
return FamilyName.Equals(uwp.FamilyName, StringComparison.CurrentCultureIgnoreCase);
}
else
@ -214,6 +215,7 @@ namespace Microsoft.Plugin.Program.Programs
public override int GetHashCode()
{
// Using CurrentCultureIgnoreCase since this is used with FamilyName
return FamilyName.GetHashCode(StringComparison.CurrentCultureIgnoreCase);
}

View File

@ -111,6 +111,7 @@ namespace Microsoft.Plugin.Program.Programs
result.Title = DisplayName;
result.SetTitleHighlightData(StringMatcher.FuzzySearch(query, Name).MatchData);
// Using CurrentCulture since this is user facing
var toolTipTitle = string.Format(CultureInfo.CurrentCulture, "{0}: {1}", Properties.Resources.powertoys_run_plugin_program_file_name, result.Title);
var toolTipText = string.Format(CultureInfo.CurrentCulture, "{0}: {1}", Properties.Resources.powertoys_run_plugin_program_file_path, Package.Location);
result.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);
@ -263,6 +264,8 @@ namespace Microsoft.Plugin.Program.Programs
if (File.Exists(manifest))
{
var file = File.ReadAllText(manifest);
// Using OrdinalIgnoreCase since this is used internally
if (file.Contains("TrustLevel=\"mediumIL\"", StringComparison.OrdinalIgnoreCase))
{
return true;
@ -276,12 +279,16 @@ namespace Microsoft.Plugin.Program.Programs
internal string ResourceFromPri(string packageFullName, string resourceReference)
{
const string prefix = "ms-resource:";
// Using OrdinalIgnoreCase since this is used internally
if (!string.IsNullOrWhiteSpace(resourceReference) && resourceReference.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
// magic comes from @talynone
// https://github.com/talynone/Wox.Plugin.WindowsUniversalAppLauncher/blob/master/StoreAppLauncher/Helpers/NativeApiHelper.cs#L139-L153
string key = resourceReference.Substring(prefix.Length);
string parsed;
// Using Ordinal/OrdinalIgnorcase since these are used internally
if (key.StartsWith("//", StringComparison.Ordinal))
{
parsed = prefix + key;
@ -540,6 +547,8 @@ namespace Microsoft.Plugin.Program.Programs
// windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx
string path;
bool isLogoUriSet;
// Using Ordinal since this is used internally with uri
if (uri.Contains("\\", StringComparison.Ordinal))
{
path = Path.Combine(Package.Location, uri);
@ -598,6 +607,7 @@ namespace Microsoft.Plugin.Program.Programs
string currentBackgroundColor;
if (BackgroundColor == "transparent")
{
// Using InvariantCulture since this is internal
currentBackgroundColor = SystemParameters.WindowGlassBrush.ToString(CultureInfo.InvariantCulture);
}
else

View File

@ -98,6 +98,7 @@ namespace Microsoft.Plugin.Program.Programs
// To Filter PWAs when the user searches for the main application
// All Chromium based applications contain the --app-id argument
// Reference : https://codereview.chromium.org/399045/show
// Using Ordinal IgnoreCase since this is used internally
bool isWebApplication = FullPath.Contains(ProxyWebApp, StringComparison.OrdinalIgnoreCase) && Arguments.Contains(AppIdArgument, StringComparison.OrdinalIgnoreCase);
return isWebApplication;
}
@ -121,6 +122,7 @@ namespace Microsoft.Plugin.Program.Programs
// check if any space separated query is a part of the app name or path name
foreach (var subquery in subqueries)
{
// Using OrdinalIgnoreCase since these are used internally
if (FullPath.Contains(subquery, StringComparison.OrdinalIgnoreCase))
{
pathContainsQuery = true;
@ -172,6 +174,7 @@ namespace Microsoft.Plugin.Program.Programs
{
if (query != null && AppType == ApplicationType.RunCommand)
{
// Using OrdinalIgnoreCase since this is used internally
if (!query.Equals(Name, StringComparison.OrdinalIgnoreCase) && !query.Equals(ExecutableName, StringComparison.OrdinalIgnoreCase))
{
return false;
@ -235,6 +238,7 @@ namespace Microsoft.Plugin.Program.Programs
result.Title = Name;
result.SetTitleHighlightData(StringMatcher.FuzzySearch(query, Name).MatchData);
// Using CurrentCulture since this is user facing
var toolTipTitle = string.Format(CultureInfo.CurrentCulture, "{0}: {1}", Properties.Resources.powertoys_run_plugin_program_file_name, result.Title);
var toolTipText = string.Format(CultureInfo.CurrentCulture, "{0}: {1}", Properties.Resources.powertoys_run_plugin_program_file_path, FullPath);
result.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);
@ -342,6 +346,8 @@ namespace Microsoft.Plugin.Program.Programs
Name = Path.GetFileNameWithoutExtension(path),
ExecutableName = Path.GetFileName(path),
IcoPath = path,
// Using CurrentCulture since this is user facing
FullPath = path.ToLower(CultureInfo.CurrentCulture),
UniqueIdentifier = path,
ParentDirectory = Directory.GetParent(path).FullName,
@ -384,6 +390,7 @@ namespace Microsoft.Plugin.Program.Programs
foreach (string line in lines)
{
// Using OrdinalIgnoreCase since this is used internally
if (line.StartsWith(urlPrefix, StringComparison.OrdinalIgnoreCase))
{
urlPath = line.Substring(urlPrefix.Length);
@ -407,6 +414,7 @@ namespace Microsoft.Plugin.Program.Programs
}
}
// Using OrdinalIgnoreCase since this is used internally
if (line.StartsWith(iconFilePrefix, StringComparison.OrdinalIgnoreCase))
{
iconPath = line.Substring(iconFilePrefix.Length);
@ -465,6 +473,8 @@ namespace Microsoft.Plugin.Program.Programs
if (File.Exists(target) || Directory.Exists(target))
{
program.LnkResolvedPath = program.FullPath;
// Using CurrentCulture since this is user facing
program.FullPath = Path.GetFullPath(target).ToLower(CultureInfo.CurrentCulture);
program.AppType = GetAppTypeFromPath(target);
@ -543,6 +553,7 @@ namespace Microsoft.Plugin.Program.Programs
string extension = Extension(path);
ApplicationType appType = ApplicationType.GenericFile;
// Using OrdinalIgnoreCase since these are used internally with paths
if (ExecutableApplicationExtensions.Contains(extension))
{
appType = ApplicationType.Win32Application;
@ -677,6 +688,7 @@ namespace Microsoft.Plugin.Program.Programs
private static string Extension(string path)
{
// Using CurrentCulture since this is user facing
var extension = Path.GetExtension(path)?.ToLower(CultureInfo.CurrentCulture);
if (!string.IsNullOrEmpty(extension))
@ -734,6 +746,7 @@ namespace Microsoft.Plugin.Program.Programs
.Distinct()
.ToArray();
// Using OrdinalIgnoreCase since this is used internally with paths
var programs1 = allPaths.AsParallel().Where(p => Extension(p).Equals(ShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(LnkProgram);
var programs2 = allPaths.AsParallel().Where(p => Extension(p).Equals(ApplicationReferenceExtension, StringComparison.OrdinalIgnoreCase)).Select(CreateWin32Program);
var programs3 = allPaths.AsParallel().Where(p => Extension(p).Equals(InternetShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(InternetShortcutProgram);
@ -768,6 +781,7 @@ namespace Microsoft.Plugin.Program.Programs
.Distinct()
.ToArray();
// Using OrdinalIgnoreCase since this is used internally with paths
var programs1 = paths.AsParallel().Where(p => Extension(p).Equals(ShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(LnkProgram);
var programs2 = paths.AsParallel().Where(p => Extension(p).Equals(ApplicationReferenceExtension, StringComparison.OrdinalIgnoreCase)).Select(CreateWin32Program);
var programs3 = paths.AsParallel().Where(p => Extension(p).Equals(InternetShortcutExtension, StringComparison.OrdinalIgnoreCase)).Select(InternetShortcutProgram);
@ -908,6 +922,7 @@ namespace Microsoft.Plugin.Program.Programs
&& !string.IsNullOrEmpty(app1.ExecutableName) && !string.IsNullOrEmpty(app2.ExecutableName)
&& !string.IsNullOrEmpty(app1.FullPath) && !string.IsNullOrEmpty(app2.FullPath))
{
// Using OrdinalIgnoreCase since this is used internally
return app1.Name.Equals(app2.Name, StringComparison.OrdinalIgnoreCase)
&& app1.ExecutableName.Equals(app2.ExecutableName, StringComparison.OrdinalIgnoreCase)
&& app1.FullPath.Equals(app2.FullPath, StringComparison.OrdinalIgnoreCase);
@ -924,6 +939,8 @@ namespace Microsoft.Plugin.Program.Programs
int fullPathPrime = 31;
int result = 1;
// Using Ordinal since this is used internally
result = (result * namePrime) + obj.Name.ToUpperInvariant().GetHashCode(StringComparison.Ordinal);
result = (result * executablePrime) + obj.ExecutableName.ToUpperInvariant().GetHashCode(StringComparison.Ordinal);
result = (result * fullPathPrime) + obj.FullPath.ToUpperInvariant().GetHashCode(StringComparison.Ordinal);

View File

@ -24,6 +24,7 @@ namespace Microsoft.Plugin.Program.Storage
// To obtain the last event associated with a particular app.
while (eventHandlingQueue.TryPeek(out string currentAppPath))
{
// Using OrdinalIgnoreCase since this is used internally with paths
if (string.IsNullOrEmpty(previousAppPath) || previousAppPath.Equals(currentAppPath, StringComparison.OrdinalIgnoreCase))
{
// To dequeue a path only if it is the first one in the queue or if the path was the same as thre previous one (to avoid trying to create apps on duplicate events)

View File

@ -145,6 +145,7 @@ namespace Microsoft.Plugin.Program.Storage
try
{
// To mitigate the issue of not having a FullPath for a shortcut app, we iterate through the items and find the app with the same hashcode.
// Using OrdinalIgnoreCase since this is used internally
if (extension.Equals(LnkExtension, StringComparison.OrdinalIgnoreCase))
{
app = GetAppWithSameLnkResolvedPath(path);
@ -174,6 +175,7 @@ namespace Microsoft.Plugin.Program.Storage
{
foreach (Win32Program app in Items)
{
// Using CurrentCultureIgnoreCase since application names could be dependent on currentculture See: https://github.com/microsoft/PowerToys/pull/5847/files#r468245190
if (name.Equals(app.Name, StringComparison.CurrentCultureIgnoreCase) && executableName.Equals(app.ExecutableName, StringComparison.CurrentCultureIgnoreCase))
{
return app;
@ -189,7 +191,8 @@ namespace Microsoft.Plugin.Program.Storage
{
foreach (Programs.Win32Program app in Items)
{
if (lnkResolvedPath.ToLower(CultureInfo.CurrentCulture).Equals(app.LnkResolvedPath, StringComparison.CurrentCultureIgnoreCase))
// Using Invariant / OrdinalIgnoreCase since we're comparing paths
if (lnkResolvedPath.ToUpperInvariant().Equals(app.LnkResolvedPath, StringComparison.OrdinalIgnoreCase))
{
return app;
}
@ -201,7 +204,9 @@ namespace Microsoft.Plugin.Program.Storage
private void OnAppCreated(object sender, FileSystemEventArgs e)
{
string path = e.FullPath;
if (!Path.GetExtension(path).Equals(UrlExtension, StringComparison.CurrentCultureIgnoreCase) && !Path.GetExtension(path).Equals(LnkExtension, StringComparison.CurrentCultureIgnoreCase))
// Using OrdinalIgnoreCase since we're comparing extensions
if (!Path.GetExtension(path).Equals(UrlExtension, StringComparison.OrdinalIgnoreCase) && !Path.GetExtension(path).Equals(LnkExtension, StringComparison.OrdinalIgnoreCase))
{
Programs.Win32Program app = Programs.Win32Program.GetAppFromPath(path);
if (app != null)
@ -214,7 +219,9 @@ namespace Microsoft.Plugin.Program.Storage
private void OnAppChanged(object sender, FileSystemEventArgs e)
{
string path = e.FullPath;
if (Path.GetExtension(path).Equals(UrlExtension, StringComparison.CurrentCultureIgnoreCase) || Path.GetExtension(path).Equals(LnkExtension, StringComparison.CurrentCultureIgnoreCase))
// Using OrdinalIgnoreCase since we're comparing extensions
if (Path.GetExtension(path).Equals(UrlExtension, StringComparison.OrdinalIgnoreCase) || Path.GetExtension(path).Equals(LnkExtension, StringComparison.OrdinalIgnoreCase))
{
// When a url or lnk app is installed, multiple created and changed events are triggered.
// To prevent the code from acting on the first such event (which may still be during app installation), the events are added a common queue and dequeued by a background task at regular intervals - https://github.com/microsoft/PowerToys/issues/6429.

View File

@ -84,6 +84,7 @@ namespace Microsoft.Plugin.Shell
{
if (m.Key == cmd)
{
// Using CurrentCulture since this is user facing
result.SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + ": " + string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_cmd_cmd_has_been_executed_times, m.Value);
return null;
}
@ -91,6 +92,8 @@ namespace Microsoft.Plugin.Shell
var ret = new Result
{
Title = m.Key,
// Using CurrentCulture since this is user facing
SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + ": " + string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_cmd_cmd_has_been_executed_times, m.Value),
IcoPath = IconPath,
Action = c =>
@ -128,6 +131,8 @@ namespace Microsoft.Plugin.Shell
.Select(m => new Result
{
Title = m.Key,
// Using CurrentCulture since this is user facing
SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + ": " + string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_cmd_cmd_has_been_executed_times, m.Value),
IcoPath = IconPath,
Action = c =>

View File

@ -119,6 +119,7 @@ namespace Microsoft.Plugin.Uri
?? _registeryWrapper.GetRegistryValue("HKEY_CLASSES_ROOT\\" + progId + "\\DefaultIcon", null);
// "Handles 'Indirect Strings' (UWP programs)"
// Using Ordinal since this is internal and used with a symbol
if (programLocation.StartsWith("@", StringComparison.Ordinal))
{
var directProgramLocationStringBuilder = new StringBuilder(128);
@ -137,6 +138,7 @@ namespace Microsoft.Plugin.Uri
}
else
{
// Using Ordinal since this is internal and used with a symbol
var indexOfComma = programLocation.IndexOf(',', StringComparison.Ordinal);
BrowserIconPath = indexOfComma > 0
? programLocation.Substring(0, indexOfComma)

View File

@ -18,9 +18,10 @@ namespace Microsoft.Plugin.Uri.UriHelper
}
// Handle common cases UriBuilder does not handle
if (input.EndsWith(":", StringComparison.Ordinal)
|| input.EndsWith(".", StringComparison.Ordinal)
|| input.EndsWith(":/", StringComparison.Ordinal))
// Using CurrentCulture since this is a user typed string
if (input.EndsWith(":", StringComparison.CurrentCulture)
|| input.EndsWith(".", StringComparison.CurrentCulture)
|| input.EndsWith(":/", StringComparison.CurrentCulture))
{
result = default;
return false;

View File

@ -37,6 +37,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
throw new ArgumentNullException(nameof(text));
}
// Using CurrentCulture since this is user facing
searchText = searchText.ToLower(CultureInfo.CurrentCulture);
text = text.ToLower(CultureInfo.CurrentCulture);

View File

@ -563,6 +563,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
public override string ToString()
{
// Using CurrentCulture since this is user facing
return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
}
}

View File

@ -54,6 +54,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
set
{
// Using CurrentCulture since this is user facing
searchText = value.ToLower(CultureInfo.CurrentCulture).Trim();
}
}

View File

@ -252,6 +252,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
// 1) There is a weird flashing behavior when trying
// to use ShowWindow for switching tabs in IE
// 2) SetForegroundWindow fails on minimized windows
// Using Ordinal since this is internal
if (ProcessName.ToUpperInvariant().Equals("IEXPLORE.EXE", StringComparison.Ordinal) || !Minimized)
{
NativeMethods.SetForegroundWindow(Hwnd);
@ -270,6 +271,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
/// <returns>The title of the window</returns>
public override string ToString()
{
// Using CurrentCulture since this is user facing
return Title + " (" + ProcessName.ToUpper(CultureInfo.CurrentCulture) + ")";
}

View File

@ -34,7 +34,8 @@ namespace PowerLauncher.Helper
{
string uriString = uri.AbsoluteUri;
int commaIndex = uriString.IndexOf(',', StringComparison.InvariantCultureIgnoreCase);
// Using Ordinal since this is internal and used with a symbol
int commaIndex = uriString.IndexOf(',', StringComparison.Ordinal);
var headers = uriString.Substring(0, commaIndex).Split(';');
_contentType = headers[0];
string dataString = uriString.Substring(commaIndex + 1);

View File

@ -44,7 +44,9 @@ namespace PowerLauncher
StringBuilder content = new StringBuilder();
content.AppendLine(ErrorReporting.RuntimeInfo());
content.AppendLine($"Date: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}");
// Using CurrentCulture since this is displayed to user in the report window
content.AppendLine($"Date: {DateTime.Now.ToString(CultureInfo.CurrentCulture)}");
content.AppendLine("Exception:");
content.AppendLine(exception.ToString());
var paragraph = new Paragraph();

View File

@ -92,6 +92,7 @@ namespace PowerLauncher
_settings.IgnoreHotkeysOnFullscreen = overloadSettings.Properties.IgnoreHotkeysInFullscreen;
}
// Using OrdinalIgnoreCase since this is internal
var indexer = PluginManager.AllPlugins.Find(p => p.Metadata.Name.Equals("Windows Indexer", StringComparison.OrdinalIgnoreCase));
if (indexer != null)
{

View File

@ -132,6 +132,7 @@ namespace PowerLauncher.ViewModel
if (index != null)
{
// Using InvariantCulture since this is internal
results.SelectedIndex = int.Parse(index.ToString(), CultureInfo.InvariantCulture);
}
@ -438,8 +439,9 @@ namespace PowerLauncher.ViewModel
private void QueryHistory()
{
// Using CurrentCulture since query is received from user and used in downstream comparisons using CurrentCulture
#pragma warning disable CA1308 // Normalize strings to uppercase
var query = QueryText.ToLower(CultureInfo.InvariantCulture).Trim();
var query = QueryText.ToLower(CultureInfo.CurrentCulture).Trim();
#pragma warning restore CA1308 // Normalize strings to uppercase
History.Clear();
@ -528,6 +530,7 @@ namespace PowerLauncher.ViewModel
lock (_addResultsLock)
{
// Using CurrentCultureIgnoreCase since this is user facing
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
{
Results.Clear();
@ -565,6 +568,7 @@ namespace PowerLauncher.ViewModel
{
lock (_addResultsLock)
{
// Using CurrentCultureIgnoreCase since this is user facing
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
{
currentCancellationToken.ThrowIfCancellationRequested();
@ -630,6 +634,7 @@ namespace PowerLauncher.ViewModel
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
// Using CurrentCultureIgnoreCase since this is user facing
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
{
Results.Results.NotifyChanges();
@ -818,6 +823,7 @@ namespace PowerLauncher.ViewModel
}
}
// Using CurrentCultureIgnoreCase since this is user facing
if (originQuery.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
{
ct.ThrowIfCancellationRequested();
@ -879,6 +885,7 @@ namespace PowerLauncher.ViewModel
}
else
{
// Using Ordinal this is internal
return string.IsNullOrEmpty(queryText) || autoCompleteText.IndexOf(queryText, StringComparison.Ordinal) != 0;
}
}
@ -889,6 +896,7 @@ namespace PowerLauncher.ViewModel
{
if (index == 0)
{
// Using OrdinalIgnoreCase because we want the characters to be exact in autocomplete text and the query
if (input.IndexOf(query, StringComparison.OrdinalIgnoreCase) == 0)
{
// Use the same case as the input query for the matched portion of the string
@ -906,6 +914,7 @@ namespace PowerLauncher.ViewModel
{
if (index == 0 && !string.IsNullOrEmpty(query))
{
// Using OrdinalIgnoreCase since this is internal
if (input.IndexOf(query, StringComparison.OrdinalIgnoreCase) == 0)
{
return query + input.Substring(query.Length);

View File

@ -70,6 +70,8 @@ namespace Wox.Infrastructure.Exception
sb.AppendLine("## Environment");
sb.AppendLine($"* Command Line: {Environment.CommandLine}");
// Using InvariantCulture since this is internal
sb.AppendLine($"* Timestamp: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}");
sb.AppendLine($"* Wox version: {Constant.Version}");
sb.AppendLine($"* OS Version: {Environment.OSVersion.VersionString}");

View File

@ -131,6 +131,7 @@ namespace Wox.Infrastructure.Image
return new ImageResult(ImageCache[path], ImageType.Cache);
}
// Using OrdinalIgnoreCase since this is internal and used with paths
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
{
var imageSource = new BitmapImage(new Uri(path));

View File

@ -106,8 +106,8 @@ namespace Wox.Infrastructure.Storage
private void BackupOriginFile()
{
// Using CurrentCulture since this is user facing
var timestamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.CurrentCulture);
// Using InvariantCulture since this is internal
var timestamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.InvariantCulture);
var directory = Path.GetDirectoryName(FilePath).NonNull();
var originName = Path.GetFileNameWithoutExtension(FilePath);
var backupName = $"{originName}-{timestamp}{FileSuffix}";

View File

@ -249,6 +249,7 @@ namespace Wox.Infrastructure
}
}
// Using CurrentCultureIgnoreCase since this relates to queries input by user
if (string.Equals(query, stringToCompare, StringComparison.CurrentCultureIgnoreCase))
{
var bonusForExactMatch = 10;

View File

@ -380,6 +380,8 @@ namespace Wox.Test.Plugins
// Assert
string expectedSqlQuery = "SELECT TOP 30 \"System.ItemUrl\", \"System.FileName\", \"System.FileAttributes\" FROM \"SystemIndex\" WHERE (CONTAINS(System.FileName,'\"abcd.*\"',1033)) AND scope='file:' ORDER BY System.DateModified DESC";
// Using InvariantCultureIgnoreCase since this relates to sql code in string form
Assert.IsFalse(simplifiedSqlQuery.Equals(sqlQuery, StringComparison.InvariantCultureIgnoreCase));
Assert.IsTrue(simplifiedSqlQuery.Equals(expectedSqlQuery, StringComparison.InvariantCultureIgnoreCase));
}
@ -394,6 +396,7 @@ namespace Wox.Test.Plugins
var simplifiedSqlQuery = WindowsSearchAPI.SimplifyQuery(sqlQuery);
// Assert
// Using InvariantCultureIgnoreCase since this relates to sql code in string form
Assert.IsTrue(simplifiedSqlQuery.Equals(sqlQuery, StringComparison.InvariantCultureIgnoreCase));
}
@ -408,6 +411,8 @@ namespace Wox.Test.Plugins
// Assert
string expectedSqlQuery = "SELECT TOP 30 \"System.ItemUrl\", \"System.FileName\", \"System.FileAttributes\", \"System.FileExtension\" FROM \"SystemIndex\" WHERE (CONTAINS(System.FileName,'\"ab.*\"',1033)) AND (CONTAINS(System.FileName,'\".cd*\"',1033)) AND scope='file:' ORDER BY System.DateModified DESC";
// Using InvariantCultureIgnoreCase since this relates to sql code in string form
Assert.IsFalse(simplifiedSqlQuery.Equals(sqlQuery, StringComparison.InvariantCultureIgnoreCase));
Assert.IsTrue(simplifiedSqlQuery.Equals(expectedSqlQuery, StringComparison.InvariantCultureIgnoreCase));
}
@ -423,6 +428,8 @@ namespace Wox.Test.Plugins
// Assert
string expectedSqlQuery = "SELECT TOP 30 \"System.ItemUrl\", \"System.FileName\", \"System.FileAttributes\" FROM \"SystemIndex\" WHERE (CONTAINS(System.FileName,'\"'ab.cd'*\"',1033)) AND scope='file:' ORDER BY System.DateModified DESC";
// Using InvariantCultureIgnoreCase since this relates to sql code in string form
Assert.IsFalse(simplifiedSqlQuery.Equals(sqlQuery, StringComparison.InvariantCultureIgnoreCase));
Assert.IsTrue(simplifiedSqlQuery.Equals(expectedSqlQuery, StringComparison.InvariantCultureIgnoreCase));
}

View File

@ -47,7 +47,10 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg.Utilities
var elements = doc.Descendants().ToList();
foreach (XElement element in elements)
{
var elementName = element?.Name?.LocalName?.ToLower(CultureInfo.CurrentCulture);
// Using Invariant since we are doing an exact match for HTML tags and we want it to behave the same in every culture
#pragma warning disable CA1308 // Normalize strings to uppercase
var elementName = element?.Name?.LocalName?.ToLowerInvariant();
#pragma warning restore CA1308 // Normalize strings to uppercase
if (elementName != null && blockedElementsName.ContainsKey(elementName))
{
foundBlockedElement = true;

View File

@ -166,7 +166,9 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
{0}
</body>
</html>";
return string.Format(CultureInfo.CurrentCulture, html, svg);
// Using InvariantCulture since this should be displayed as it is
return string.Format(CultureInfo.InvariantCulture, html, svg);
}
/// <summary>

View File

@ -54,6 +54,7 @@ namespace PreviewHandlerCommon
if (name != null && name.Equals(DISPIDAMBIENTDLCONTROL, StringComparison.CurrentCulture))
{
// Using InvariantCulture since this is used for web browser configurations
result = Convert.ToInt32(
WebBrowserDownloadControlFlags.DLIMAGES |
WebBrowserDownloadControlFlags.PRAGMA_NO_CACHE |
@ -66,7 +67,7 @@ namespace PreviewHandlerCommon
WebBrowserDownloadControlFlags.NO_DLACTIVEXCTLS |
WebBrowserDownloadControlFlags.NO_RUNACTIVEXCTLS |
WebBrowserDownloadControlFlags.NO_BEHAVIORS |
WebBrowserDownloadControlFlags.SILENT, CultureInfo.CurrentCulture);
WebBrowserDownloadControlFlags.SILENT, CultureInfo.InvariantCulture);
}
else
{