Fix variable assignment to not overwrite readonly/constant variables (#2400)

This commit is contained in:
Dongbo Wang 2016-10-03 15:25:52 -07:00 committed by Jason Shirk
parent 5fbde6eb40
commit 13455204a4
2 changed files with 40 additions and 4 deletions

View file

@ -56,7 +56,19 @@ namespace System.Management.Automation
}
else if (attributeAsts != null)
{
var.Attributes.Clear();
// Use bytewise operation directly instead of 'var.IsReadOnly || var.IsConstant' on
// a hot path (setting variable with type constraint) to get better performance.
if ((var.Options & (ScopedItemOptions.ReadOnly | ScopedItemOptions.Constant)) != ScopedItemOptions.None)
{
SessionStateUnauthorizedAccessException e =
new SessionStateUnauthorizedAccessException(
var.Name,
SessionStateCategory.Variable,
"VariableNotWritable",
SessionStateStrings.VariableNotWritable);
throw e;
}
var attributes = GetAttributeCollection(attributeAsts);
value = PSVariable.TransformValue(attributes, value);
if (!PSVariable.IsValidValue(attributes, value))
@ -71,6 +83,8 @@ namespace System.Management.Automation
throw e;
}
var.SetValueRaw(value, true);
// Don't update the PSVariable's attributes until we successfully set the value
var.Attributes.Clear();
var.AddParameterAttributesNoChecks(attributes);
if (executionContext._debuggingMode > 0)

View file

@ -140,10 +140,32 @@ Describe "Assign automatic variables" -Tags "CI" {
& { [string]$PSScriptRoot = 'abc'; $PSScriptRoot } | Should Be abc
& { [string]$PSCommandPath = 'abc'; $PSCommandPath } | Should Be abc
}
}
It "Assign `$? w/o type constraint" {
{ & { $? = 1 } } | Should Throw
{ . { $? = 1 } } | Should Throw
Describe "Assign readonly/constant variables" -Tags "CI" {
$testCase = @(
@{ sb_wo_conversion = { $? = 1 }; name = '$? = 1' }
@{ sb_wo_conversion = { $HOME = 1 }; name = '$HOME = 1' }
@{ sb_wo_conversion = { $PID = 1 }; name = '$PID = 1' }
)
It "Assign readonly/constant variables w/o type constraint - '<name>'" -TestCases $testCase {
param($sb_wo_conversion)
{ & $sb_wo_conversion } | Should Throw
{ . $sb_wo_conversion } | Should Throw
}
$testCase = @(
@{ sb_w_conversion = { [datetime]$? = 1 }; name = '[datetime]$? = 1' }
@{ sb_w_conversion = { [datetime]$HOME = 1 }; name = '[datetime]$HOME = 1' }
@{ sb_w_conversion = { [datetime]$PID = 1 }; name = '[datetime]$PID = 1' }
)
It "Assign readonly/constant variables w/ type constraint - '<name>'" -TestCases $testCase {
param($sb_w_conversion)
{ & $sb_w_conversion } | Should Throw
{ . $sb_w_conversion } | Should Throw
}
}