From 5a8fa57278f46133f77d5dbc92b0b75dbde82f95 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Thu, 16 Feb 2017 21:25:23 -0800 Subject: [PATCH] Fix PSModuleInfo.CaptureLocals to not do ValidateAttribute check when capturing variables from the caller's scope (#3149) Fix PSModuleInfo.CaptureLocals to not do ValidateAttribute check when capturing variables from the caller's scope --- .../engine/Modules/PSModuleInfo.cs | 5 ++- .../engine/Api/GetNewClosure.Tests.ps1 | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 test/powershell/engine/Api/GetNewClosure.Tests.ps1 diff --git a/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs b/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs index 0afb390cf..0f55de878 100644 --- a/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs +++ b/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs @@ -1378,7 +1378,10 @@ namespace System.Management.Automation // Only copy simple mutable variables... if (v.Options == ScopedItemOptions.None && !(v is NullVariable)) { - PSVariable newVar = new PSVariable(v.Name, v.Value, v.Options, v.Attributes, v.Description); + PSVariable newVar = new PSVariable(v.Name, v.Value, v.Options, v.Description); + // The variable is already defined/set in the scope, and that means the attributes + // have already been checked if it was needed, so we don't do it again. + newVar.AddParameterAttributesNoChecks(v.Attributes); SessionState.Internal.NewVariable(newVar, false); } } diff --git a/test/powershell/engine/Api/GetNewClosure.Tests.ps1 b/test/powershell/engine/Api/GetNewClosure.Tests.ps1 new file mode 100644 index 000000000..78080390c --- /dev/null +++ b/test/powershell/engine/Api/GetNewClosure.Tests.ps1 @@ -0,0 +1,42 @@ +Describe "ScriptBlock.GetNewClosure()" -tags "CI" { + + BeforeAll { + + ## No error should occur when calling GetNewClosure because: + ## 1. ValidateAttributes are not evaluated on parameter default values + ## 2. GetNewClosure no longer forces validation on existing variables + function SimpleFunction_GetNewClosure + { + param([ValidateNotNull()] $Name) + + & { 'OK' }.GetNewClosure() + } + + function ScriptCmdlet_GetNewClosure + { + [CmdletBinding()] + param( + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $Name = "", + + [Parameter()] + [ValidateRange(1,3)] + [int] $Value = 4 + ) + + & { $Value; $Name }.GetNewClosure() + } + } + + It "Parameter attributes should not get evaluated again in GetNewClosure - SimpleFunction" { + SimpleFunction_GetNewClosure | Should Be "OK" + } + + It "Parameter attributes should not get evaluated again in GetNewClosure - ScriptCmdlet" { + $result = ScriptCmdlet_GetNewClosure + $result.Count | Should Be 2 + $result[0] | Should Be 4 + $result[1] | Should Be "" + } +}