Skip to content

Commit

Permalink
Merged PR 29197: Backport three PRs to v7.4.1 release
Browse files Browse the repository at this point in the history
  • Loading branch information
daxian-dbw committed Jan 11, 2024
1 parent b3a4019 commit 6a98b28
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,15 @@ private static string BuildName(List<ObjectCommandPropertyValue> propValues)

foreach (object item in propertyValueItems)
{
sb.AppendFormat(CultureInfo.CurrentCulture, $"{item}, ");
sb.Append(CultureInfo.CurrentCulture, $"{item}, ");
}

sb = sb.Length > length ? sb.Remove(sb.Length - 2, 2) : sb;
sb.Append("}, ");
}
else
{
sb.AppendFormat(CultureInfo.CurrentCulture, $"{propValuePropertyValue}, ");
sb.Append(CultureInfo.CurrentCulture, $"{propValuePropertyValue}, ");
}
}
}
Expand Down
56 changes: 29 additions & 27 deletions src/System.Management.Automation/engine/LanguagePrimitives.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3986,44 +3986,46 @@ internal ConvertViaNoArgumentConstructor(ConstructorInfo constructor, Type type)
// - It's in FullLanguage but not because it's part of a parameter binding that is transitioning from ConstrainedLanguage to FullLanguage
// When this is invoked from a parameter binding in transition from ConstrainedLanguage environment to FullLanguage command, we disallow
// the property conversion because it's dangerous.
if (ecFromTLS == null || (ecFromTLS.LanguageMode == PSLanguageMode.FullLanguage && !ecFromTLS.LanguageModeTransitionInParameterBinding))
bool canProceedWithConversion = ecFromTLS == null || (ecFromTLS.LanguageMode == PSLanguageMode.FullLanguage && !ecFromTLS.LanguageModeTransitionInParameterBinding);
if (!canProceedWithConversion)
{
result = _constructor();
var psobject = valueToConvert as PSObject;
if (psobject != null)
{
// Use PSObject properties to perform conversion.
SetObjectProperties(result, psobject, resultType, CreateMemberNotFoundError, CreateMemberSetValueError, formatProvider, recursion, ignoreUnknownMembers);
}
else
if (SystemPolicy.GetSystemLockdownPolicy() != SystemEnforcementMode.Audit)
{
// Use provided property dictionary to perform conversion.
// The method invocation is disabled for "Hashtable to Object conversion" (Win8:649519), but we need to keep it enabled for New-Object for compatibility to PSv2
IDictionary properties = valueToConvert as IDictionary;
SetObjectProperties(result, properties, resultType, CreateMemberNotFoundError, CreateMemberSetValueError, enableMethodCall: false);
throw InterpreterError.NewInterpreterException(
valueToConvert,
typeof(RuntimeException),
errorPosition: null,
"HashtableToObjectConversionNotSupportedInDataSection",
ParserStrings.HashtableToObjectConversionNotSupportedInDataSection,
resultType.ToString());
}

typeConversion.WriteLine("Constructor result: \"{0}\".", result);
}
else
{
if (SystemPolicy.GetSystemLockdownPolicy() == SystemEnforcementMode.Audit)
{
SystemPolicy.LogWDACAuditMessage(
// When in audit mode, we report but don't enforce, so we will proceed with the conversion.
SystemPolicy.LogWDACAuditMessage(
context: ecFromTLS,
title: ExtendedTypeSystem.WDACHashTypeLogTitle,
message: StringUtil.Format(ExtendedTypeSystem.WDACHashTypeLogMessage, resultType.FullName),
fqid: "LanguageHashtableConversionNotAllowed",
dropIntoDebugger: true);
}
else
{
RuntimeException rte = InterpreterError.NewInterpreterException(valueToConvert, typeof(RuntimeException), null,
"HashtableToObjectConversionNotSupportedInDataSection", ParserStrings.HashtableToObjectConversionNotSupportedInDataSection, resultType.ToString());
throw rte;
}
}

result = _constructor();
var psobject = valueToConvert as PSObject;
if (psobject != null)
{
// Use PSObject properties to perform conversion.
SetObjectProperties(result, psobject, resultType, CreateMemberNotFoundError, CreateMemberSetValueError, formatProvider, recursion, ignoreUnknownMembers);
}
else
{
// Use provided property dictionary to perform conversion.
// The method invocation is disabled for "Hashtable to Object conversion" (Win8:649519), but we need to keep it enabled for New-Object for compatibility to PSv2
IDictionary properties = valueToConvert as IDictionary;
SetObjectProperties(result, properties, resultType, CreateMemberNotFoundError, CreateMemberSetValueError, enableMethodCall: false);
}

typeConversion.WriteLine("Constructor result: \"{0}\".", result);

return result;
}
catch (TargetInvocationException ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Management.Automation.Internal;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Runspaces.Internal;
using System.Management.Automation.Security;

using Dbg = System.Management.Automation.Diagnostics;

Expand Down Expand Up @@ -94,7 +95,22 @@ private PSCommand ParsePsCommandUsingScriptBlock(string line, bool? useLocalScop
// to be parsed and evaluated on the remote session (not in the current local session).
RemoteRunspace remoteRunspace = _runspaceRef.Value as RemoteRunspace;
bool isConfiguredLoopback = remoteRunspace != null && remoteRunspace.IsConfiguredLoopBack;
bool isTrustedInput = !isConfiguredLoopback && (localRunspace.ExecutionContext.LanguageMode == PSLanguageMode.FullLanguage);

bool inFullLanguage = context.LanguageMode == PSLanguageMode.FullLanguage;
if (context.LanguageMode == PSLanguageMode.ConstrainedLanguage
&& SystemPolicy.GetSystemLockdownPolicy() == SystemEnforcementMode.Audit)
{
// In audit mode, report but don't enforce.
inFullLanguage = true;
SystemPolicy.LogWDACAuditMessage(
context: context,
title: RemotingErrorIdStrings.WDACGetPowerShellLogTitle,
message: RemotingErrorIdStrings.WDACGetPowerShellLogMessage,
fqid: "GetPowerShellMayFail",
dropIntoDebugger: true);
}

bool isTrustedInput = !isConfiguredLoopback && inFullLanguage;

// Create PowerShell from ScriptBlock.
ScriptBlock scriptBlock = ScriptBlock.Create(context, line);
Expand Down Expand Up @@ -350,7 +366,7 @@ internal void Override(RemoteRunspace remoteRunspace, object syncObject, out boo
/// <param name="eventArgs"></param>
private void HandleHostCall(object sender, RemoteDataEventArgs<RemoteHostCall> eventArgs)
{
System.Management.Automation.Runspaces.Internal.ClientRemotePowerShell.ExitHandler(sender, eventArgs);
ClientRemotePowerShell.ExitHandler(sender, eventArgs);
}

#region Robust Connection Support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2278,7 +2278,7 @@ private System.Management.Automation.PowerShell GetPowerShellForPSv3OrLater(stri
// Semantic checks on the using statement have already validated that there are no arbitrary expressions,
// so we'll allow these expressions in everything but NoLanguage mode.

bool allowUsingExpressions = (Context.SessionState.LanguageMode != PSLanguageMode.NoLanguage);
bool allowUsingExpressions = Context.SessionState.LanguageMode != PSLanguageMode.NoLanguage;
object[] usingValuesInArray = null;
IDictionary usingValuesInDict = null;

Expand Down Expand Up @@ -2428,7 +2428,7 @@ private List<object> GetUsingVariableValues(List<VariableExpressionAst> paramUsi
// GetExpressionValue ensures that it only does variable access when supplied a VariableExpressionAst.
// So, this is still safe to use in ConstrainedLanguage and will not result in arbitrary code
// execution.
bool allowVariableAccess = (Context.SessionState.LanguageMode != PSLanguageMode.NoLanguage);
bool allowVariableAccess = Context.SessionState.LanguageMode != PSLanguageMode.NoLanguage;

foreach (var varAst in paramUsingVars)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5524,7 +5524,7 @@ private Expression ThrowPropertyNotFoundStrict()
return target.ThrowRuntimeError(args, moreTests, errorID, resourceString);
}

string targetName = (targetValue as Type)?.FullName;
string targetName = (targetValue as Type)?.FullName ?? targetValue?.GetType().FullName;
SystemPolicy.LogWDACAuditMessage(
context: context,
title: ParameterBinderStrings.WDACBinderInvocationLogTitle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,18 @@ internal static SteppablePipeline GetSteppablePipeline(PipelineAst pipelineAst,
// of invoking it. So the trustworthiness is defined by the trustworthiness of the
// script block's language mode.
bool isTrusted = scriptBlock.LanguageMode == PSLanguageMode.FullLanguage;
if (scriptBlock.LanguageMode == PSLanguageMode.ConstrainedLanguage
&& SystemPolicy.GetSystemLockdownPolicy() == SystemEnforcementMode.Audit)
{
// In audit mode, report but don't enforce.
isTrusted = true;
SystemPolicy.LogWDACAuditMessage(
context: context,
title: ParserStrings.WDACGetSteppablePipelineLogTitle,
message: ParserStrings.WDACGetSteppablePipelineLogMessage,
fqid: "GetSteppablePipelineMayFail",
dropIntoDebugger: true);
}

foreach (var commandAst in pipelineAst.PipelineElements.Cast<CommandAst>())
{
Expand All @@ -729,7 +741,7 @@ internal static SteppablePipeline GetSteppablePipeline(PipelineAst pipelineAst,

var exprAst = (ExpressionAst)commandElement;
var argument = Compiler.GetExpressionValue(exprAst, isTrusted, context);
var splatting = (exprAst is VariableExpressionAst && ((VariableExpressionAst)exprAst).Splatted);
var splatting = exprAst is VariableExpressionAst && ((VariableExpressionAst)exprAst).Splatted;
commandParameters.Add(CommandParameterInternal.CreateArgument(argument, exprAst, splatting));
}

Expand Down Expand Up @@ -797,8 +809,8 @@ private static CommandParameterInternal GetCommandParameter(CommandParameterAst
}

object argumentValue = Compiler.GetExpressionValue(argumentAst, isTrusted, context);
bool spaceAfterParameter = (errorPos.EndLineNumber != argumentAst.Extent.StartLineNumber ||
errorPos.EndColumnNumber != argumentAst.Extent.StartColumnNumber);
bool spaceAfterParameter = errorPos.EndLineNumber != argumentAst.Extent.StartLineNumber ||
errorPos.EndColumnNumber != argumentAst.Extent.StartColumnNumber;
return CommandParameterInternal.CreateParameterWithArgument(commandParameterAst, commandParameterAst.ParameterName,
errorPos.Text, argumentAst, argumentValue,
spaceAfterParameter);
Expand Down
6 changes: 6 additions & 0 deletions src/System.Management.Automation/resources/ParserStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1361,4 +1361,10 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent
<data name="WDACParserForEachOperatorLogMessage" xml:space="preserve">
<value>The ForEach keyword will fail '{0}' iteration item method invocation when run in Constrained Language mode.</value>
</data>
<data name="WDACGetSteppablePipelineLogTitle" xml:space="preserve">
<value>Expression Evaluation May Fail</value>
</data>
<data name="WDACGetSteppablePipelineLogMessage" xml:space="preserve">
<value>Creating a steppable pipeline from a script block may require evaluating some expressions within the script block. The expression evaluation will silently fail and return 'null' in Constrained Language mode, unless the expression represents a constant value.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1714,4 +1714,10 @@ SSH client process terminated before connection could be established.</value>
<data name="DISCUnknownConfigName" xml:space="preserve">
<value>The session configuration file contains an unknown configuration option: {0}.</value>
</data>
<data name="WDACGetPowerShellLogTitle" xml:space="preserve">
<value>Expression Evaluation May Fail</value>
</data>
<data name="WDACGetPowerShellLogMessage" xml:space="preserve">
<value>Creating a PowerShell object from a script block may require evaluating some expressions within the script block. The expression evaluation will silently fail and return 'null' in Constrained Language mode, unless the expression represents a constant value.</value>
</data>
</root>
2 changes: 1 addition & 1 deletion src/System.Management.Automation/utils/tracing/PSEtwLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ internal static void LogAmsiUtilStateEvent(string state, string context)
int querySuccess,
int queryResult)
{
provider.LogWDACQueryEvent(queryName, fileName, querySuccess, queryResult);
provider.LogWDACQueryEvent(queryName, fileName ?? string.Empty, querySuccess, queryResult);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ Describe "Group-Object" -Tags "CI" {
$result[0].Name | Should -Be ""
$result[0].Group | Should -Be '@{X=}'
}

It "Should handle format-like strings with curly braces like normal strings" {
$result = '{', '}', '{0}' | Group-Object
$result.Count | Should -Be 3
$result[0].Name | Should -BeExactly '{'
$result[1].Name | Should -BeExactly '{0}'
$result[2].Name | Should -BeExactly '}'
}
}

Describe "Check 'Culture' parameter in order object cmdlets (Group-Object, Sort-Object, Compare-Object)" -Tags "CI" {
Expand Down

0 comments on commit 6a98b28

Please sign in to comment.