Skip to content

Commit a68b139

Browse files
authored
Fix PSSA for Turkish culture and tests when culture is not en-US (#1099)
* Fix Parsing of settings that occurs when using turkish culture * use german culture before running tests to exhibit failures * set ui culture as well * fix communityanalyzer for turkish culture * fix ProvideCommentHelp for turkish culture (i problem again) * update comments * fix for import-localizedDatabug in pscore (opened issue 8219 in ps core repo) * change to UI culture * use invariant culture comparison instead of tolowerinvariant and revert change where it is not needed * finish with comments * Use OrdinalIgnoreCase * revert accidental change from 2 commits before * trigger ci * Apply suggestions from code review Co-Authored-By: bergmeister <[email protected]> * Use else-less approach to address PR comment
1 parent a15d260 commit a68b139

File tree

11 files changed

+156
-152
lines changed

11 files changed

+156
-152
lines changed

Engine/Generic/ModuleDependencyHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public ModuleDependencyHandler(
271271
? "PSScriptAnalyzer"
272272
: pssaAppDataPath);
273273

274-
modulesFound = new Dictionary<string, PSObject>();
274+
modulesFound = new Dictionary<string, PSObject>(StringComparer.OrdinalIgnoreCase);
275275

276276
// TODO Add PSSA Version in the path
277277
symLinkPath = Path.Combine(pssaAppDataPath, symLinkName);

Engine/Generic/RuleSuppression.cs

Lines changed: 52 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -202,61 +202,56 @@ public RuleSuppression(AttributeAst attrAst, int start, int end)
202202
break;
203203
}
204204

205-
switch (name.ArgumentName.ToLower())
205+
string argumentName = name.ArgumentName;
206+
if (argumentName.Equals("rulename", StringComparison.OrdinalIgnoreCase))
206207
{
207-
case "rulename":
208-
if (!String.IsNullOrWhiteSpace(RuleName))
209-
{
210-
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
211-
}
212-
213-
RuleName = (name.Argument as StringConstantExpressionAst).Value;
214-
goto default;
215-
216-
case "rulesuppressionid":
217-
if (!String.IsNullOrWhiteSpace(RuleSuppressionID))
218-
{
219-
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
220-
}
221-
222-
RuleSuppressionID = (name.Argument as StringConstantExpressionAst).Value;
223-
goto default;
224-
225-
case "scope":
226-
if (!String.IsNullOrWhiteSpace(Scope))
227-
{
228-
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
229-
}
230-
231-
Scope = (name.Argument as StringConstantExpressionAst).Value;
232-
233-
if (!scopeSet.Contains(Scope))
234-
{
235-
Error = Strings.WrongScopeArgumentSuppressionAttributeError;
236-
}
208+
if (!String.IsNullOrWhiteSpace(RuleName))
209+
{
210+
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
211+
}
237212

238-
goto default;
213+
RuleName = (name.Argument as StringConstantExpressionAst).Value;
214+
}
215+
else if (argumentName.Equals("rulesuppressionid", StringComparison.OrdinalIgnoreCase))
216+
{
217+
if (!String.IsNullOrWhiteSpace(RuleName))
218+
{
219+
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
220+
}
239221

240-
case "target":
241-
if (!String.IsNullOrWhiteSpace(Target))
242-
{
243-
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
244-
}
222+
RuleName = (name.Argument as StringConstantExpressionAst).Value;
223+
}
224+
else if (argumentName.Equals("scope", StringComparison.OrdinalIgnoreCase))
225+
{
226+
if (!String.IsNullOrWhiteSpace(Scope))
227+
{
228+
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
229+
}
245230

246-
Target = (name.Argument as StringConstantExpressionAst).Value;
247-
goto default;
231+
Scope = (name.Argument as StringConstantExpressionAst).Value;
248232

249-
case "justification":
250-
if (!String.IsNullOrWhiteSpace(Justification))
251-
{
252-
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
253-
}
233+
if (!scopeSet.Contains(Scope))
234+
{
235+
Error = Strings.WrongScopeArgumentSuppressionAttributeError;
236+
}
237+
}
238+
else if (argumentName.Equals("target", StringComparison.OrdinalIgnoreCase))
239+
{
240+
if (!String.IsNullOrWhiteSpace(Target))
241+
{
242+
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
243+
}
254244

255-
Justification = (name.Argument as StringConstantExpressionAst).Value;
256-
goto default;
245+
Target = (name.Argument as StringConstantExpressionAst).Value;
246+
}
247+
else if (argumentName.Equals("justification", StringComparison.OrdinalIgnoreCase))
248+
{
249+
if (!String.IsNullOrWhiteSpace(Justification))
250+
{
251+
Error = String.Format(Strings.NamedAndPositionalArgumentsConflictError, name);
252+
}
257253

258-
default:
259-
break;
254+
Justification = (name.Argument as StringConstantExpressionAst).Value;
260255
}
261256
}
262257
}
@@ -354,23 +349,17 @@ public static List<RuleSuppression> GetSuppressions(IEnumerable<AttributeAst> at
354349
Regex reg = new Regex(String.Format("^{0}$", ruleSupp.Target.Replace(@"*", ".*")), RegexOptions.IgnoreCase);
355350
IEnumerable<Ast> targetAsts = null;
356351

357-
switch (ruleSupp.Scope.ToLower())
352+
string scope = ruleSupp.Scope;
353+
if (scope.Equals("function", StringComparison.OrdinalIgnoreCase))
358354
{
359-
case "function":
360-
targetAsts = scopeAst.FindAll(item => item is FunctionDefinitionAst && reg.IsMatch((item as FunctionDefinitionAst).Name), true);
361-
goto default;
362-
363-
#if !(PSV3||PSV4)
364-
365-
case "class":
366-
targetAsts = scopeAst.FindAll(item => item is TypeDefinitionAst && reg.IsMatch((item as TypeDefinitionAst).Name), true);
367-
goto default;
368-
369-
#endif
370-
371-
default:
372-
break;
355+
targetAsts = scopeAst.FindAll(ast => ast is FunctionDefinitionAst && reg.IsMatch((ast as FunctionDefinitionAst).Name), true);
356+
}
357+
#if !(PSV3 || PSV4)
358+
else if (scope.Equals("class", StringComparison.OrdinalIgnoreCase))
359+
{
360+
targetAsts = scopeAst.FindAll(ast => ast is TypeDefinitionAst && reg.IsMatch((ast as TypeDefinitionAst).Name), true);
373361
}
362+
#endif
374363

375364
if (targetAsts != null)
376365
{

Engine/ScriptAnalyzer.cs

Lines changed: 66 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -283,21 +283,18 @@ private bool AddProfileItem(
283283
Debug.Assert(includeRuleList != null);
284284
Debug.Assert(excludeRuleList != null);
285285

286-
switch (key.ToLower())
286+
if (key.Equals("severity", StringComparison.OrdinalIgnoreCase))
287287
{
288-
case "severity":
289-
severityList.AddRange(values);
290-
break;
291-
case "includerules":
292-
includeRuleList.AddRange(values);
293-
break;
294-
case "excluderules":
295-
excludeRuleList.AddRange(values);
296-
break;
297-
default:
298-
return false;
288+
severityList.AddRange(values);
289+
return true;
299290
}
300-
return true;
291+
if (key.Equals("includerules", StringComparison.OrdinalIgnoreCase))
292+
{
293+
includeRuleList.AddRange(values);
294+
return true;
295+
}
296+
297+
return false;
301298
}
302299

303300
private Dictionary<string, object> GetDictionaryFromHashTableAst(
@@ -510,75 +507,70 @@ private bool ParseProfileHashtable(Hashtable profile, PathIntrinsics path, IOutp
510507
settings.Keys.CopyTo(settingsKeys, 0);
511508
foreach (var settingKey in settingsKeys)
512509
{
513-
var key = settingKey.ToLower();
514-
object value = settings[key];
515-
switch (key)
516-
{
517-
case "severity":
518-
case "includerules":
519-
case "excluderules":
520-
// value must be either string or collections of string or array
521-
if (value == null
522-
|| !(value is string
523-
|| value is IEnumerable<string>
524-
|| value.GetType().IsArray))
525-
{
526-
writer.WriteError(
527-
new ErrorRecord(
528-
new InvalidDataException(string.Format(CultureInfo.CurrentCulture, Strings.WrongValueHashTable, value, key)),
529-
Strings.WrongConfigurationKey,
530-
ErrorCategory.InvalidData,
531-
profile));
532-
hasError = true;
533-
break;
534-
}
535-
List<string> values = new List<string>();
536-
if (value is string)
537-
{
538-
values.Add(value as string);
539-
}
540-
else if (value is IEnumerable<string>)
541-
{
542-
values.Union(value as IEnumerable<string>);
543-
}
544-
else if (value.GetType().IsArray)
545-
{
546-
// for array case, sometimes we won't be able to cast it directly to IEnumerable<string>
547-
foreach (var val in value as IEnumerable)
548-
{
549-
if (val is string)
550-
{
551-
values.Add(val as string);
552-
}
553-
else
554-
{
555-
writer.WriteError(
556-
new ErrorRecord(
557-
new InvalidDataException(string.Format(CultureInfo.CurrentCulture, Strings.WrongValueHashTable, val, key)),
558-
Strings.WrongConfigurationKey,
559-
ErrorCategory.InvalidData,
560-
profile));
561-
hasError = true;
562-
break;
563-
}
564-
}
565-
}
566-
AddProfileItem(key, values, severityList, includeRuleList, excludeRuleList);
567-
settings[key] = values;
568-
break;
569-
570-
case "rules":
571-
break;
510+
object value = settings[settingKey];
572511

573-
default:
512+
if (settingKey.Equals("severity", StringComparison.OrdinalIgnoreCase) ||
513+
settingKey.Equals("includerules", StringComparison.OrdinalIgnoreCase) ||
514+
settingKey.Equals("excluderules", StringComparison.OrdinalIgnoreCase))
515+
{
516+
// value must be either string or collections of string or array
517+
if (value == null
518+
|| !(value is string
519+
|| value is IEnumerable<string>
520+
|| value.GetType().IsArray))
521+
{
574522
writer.WriteError(
575523
new ErrorRecord(
576-
new InvalidDataException(string.Format(CultureInfo.CurrentCulture, Strings.WrongKeyHashTable, key)),
524+
new InvalidDataException(string.Format(CultureInfo.CurrentCulture, Strings.WrongValueHashTable, value, settingKey)),
577525
Strings.WrongConfigurationKey,
578526
ErrorCategory.InvalidData,
579527
profile));
580528
hasError = true;
581529
break;
530+
}
531+
var values = new List<string>();
532+
if (value is string)
533+
{
534+
values.Add(value as string);
535+
}
536+
else if (value is IEnumerable<string>)
537+
{
538+
values.Union(value as IEnumerable<string>);
539+
}
540+
else if (value.GetType().IsArray)
541+
{
542+
// for array case, sometimes we won't be able to cast it directly to IEnumerable<string>
543+
foreach (var val in value as IEnumerable)
544+
{
545+
if (val is string)
546+
{
547+
values.Add(val as string);
548+
}
549+
else
550+
{
551+
writer.WriteError(
552+
new ErrorRecord(
553+
new InvalidDataException(string.Format(CultureInfo.CurrentCulture, Strings.WrongValueHashTable, val, settingKey)),
554+
Strings.WrongConfigurationKey,
555+
ErrorCategory.InvalidData,
556+
profile));
557+
hasError = true;
558+
break;
559+
}
560+
}
561+
}
562+
AddProfileItem(settingKey, values, severityList, includeRuleList, excludeRuleList);
563+
settings[settingKey] = values;
564+
}
565+
else if (settingKey.Equals("excluderules", StringComparison.OrdinalIgnoreCase))
566+
{
567+
writer.WriteError(
568+
new ErrorRecord(
569+
new InvalidDataException(string.Format(CultureInfo.CurrentCulture, Strings.WrongKeyHashTable, settingKey)),
570+
Strings.WrongConfigurationKey,
571+
ErrorCategory.InvalidData,
572+
profile));
573+
hasError = true;
582574
}
583575
}
584576
return hasError;

Engine/Settings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ private void parseSettingsHashtable(Hashtable settingsHashtable)
395395
var settings = GetDictionaryFromHashtable(settingsHashtable);
396396
foreach (var settingKey in settings.Keys)
397397
{
398-
var key = settingKey.ToLower();
398+
var key = settingKey.ToLowerInvariant(); // ToLowerInvariant is important to also work with turkish culture, see https://github.com/PowerShell/PSScriptAnalyzer/issues/1095
399399
object val = settings[key];
400400
switch (key)
401401
{
@@ -514,7 +514,7 @@ private static object GetSafeValueFromExpressionAst(ExpressionAst exprAst)
514514

515515
case VariableExpressionAst varExprAst:
516516
// $true and $false are VariableExpressionAsts, so look for them here
517-
switch (varExprAst.VariablePath.UserPath.ToLower())
517+
switch (varExprAst.VariablePath.UserPath.ToLowerInvariant())
518518
{
519519
case "true":
520520
return true;

PSCompatibilityAnalyzer/Microsoft.PowerShell.CrossCompatibility/Utility/PlatformNaming.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ public static string GetPlatformName(PlatformData platform)
3535
{
3636
string psVersion = platform.PowerShell.Version?.ToString();
3737
string osVersion = platform.OperatingSystem.Version;
38-
string osArch = platform.OperatingSystem.Architecture.ToString().ToLower();
39-
string pArch = platform.PowerShell.ProcessArchitecture.ToString().ToLower();
40-
string dotnetVersion = platform.Dotnet.ClrVersion.ToString().ToLower();
41-
string dotnetEdition = platform.Dotnet.Runtime.ToString().ToLower();
38+
string osArch = platform.OperatingSystem.Architecture.ToString().ToLowerInvariant();
39+
string pArch = platform.PowerShell.ProcessArchitecture.ToString().ToLowerInvariant();
40+
string dotnetVersion = platform.Dotnet.ClrVersion.ToString().ToLowerInvariant();
41+
string dotnetEdition = platform.Dotnet.Runtime.ToString().ToLowerInvariant();
4242

4343
string[] platformNameComponents;
4444
switch (platform.OperatingSystem.Family)

Rules/ProvideCommentHelp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ public override string ToString()
419419
public virtual string ToString(int? tabStop)
420420
{
421421
var sb = new StringBuilder();
422-
sb.Append(".").AppendLine(Name.ToUpper());
422+
sb.Append(".").AppendLine(Name.ToUpperInvariant()); // ToUpperInvariant is important to also work with turkish culture, see https://github.com/PowerShell/PSScriptAnalyzer/issues/1095
423423
if (!String.IsNullOrWhiteSpace(Description))
424424
{
425425
sb.Append(Snippetify(tabStop, Description));

Rules/UseShouldProcessCorrectly.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ public override bool Equals(Object other)
451451
/// </summary>
452452
public override int GetHashCode()
453453
{
454-
return name.ToLower().GetHashCode();
454+
return name.ToLowerInvariant().GetHashCode();
455455
}
456456
}
457457

ScriptRuleDocumentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ function Measure-RequiresRunAsAdministrator
155155
if ($Ast -is [System.Management.Automation.Language.AssignmentStatementAst])
156156
{
157157
[System.Management.Automation.Language.AssignmentStatementAst]$asAst = $Ast
158-
if ($asAst.Right.ToString().ToLower() -eq '[system.security.principal.windowsbuiltinrole]::administrator')
158+
if ($asAst.Right.ToString() -eq '[system.security.principal.windowsbuiltinrole]::administrator')
159159
{
160160
$returnValue = $true
161161
}

0 commit comments

Comments
 (0)