diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs
index 9195e49052..53dc461dfb 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs
@@ -39,6 +39,13 @@ namespace Microsoft.PowerShell.Commands
set { _isLiteralPath = true; Path = value; }
}
+ ///
+ /// Gets or sets switch that determines if built-in limits are applied to the data.
+ ///
+ [Experimental("Microsoft.PowerShell.Utility.PSImportPSDataFileSkipLimitCheck", ExperimentAction.Show)]
+ [Parameter]
+ public SwitchParameter SkipLimitCheck { get; set; }
+
///
/// For each path, resolve it, parse it and write all hashtables to the output stream.
///
@@ -61,7 +68,7 @@ namespace Microsoft.PowerShell.Commands
var data = ast.Find(a => a is HashtableAst, false);
if (data != null)
{
- WriteObject(data.SafeGetValue());
+ WriteObject(data.SafeGetValue(SkipLimitCheck));
}
else
{
diff --git a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1
index 1ef5f3328e..b883acdd0d 100644
--- a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1
+++ b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1
@@ -38,6 +38,10 @@ PrivateData = @{
Name = 'Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace'
Description = 'Enables -BreakAll parameter on Debug-Runspace and Debug-Job cmdlets to allow users to decide if they want PowerShell to break immediately in the current location when they attach a debugger. Enables -Runspace parameter on *-PSBreakpoint cmdlets to support management of breakpoints in another runspace.'
}
+ @{
+ Name = 'Microsoft.PowerShell.Utility.PSImportPSDataFileSkipLimitCheck'
+ Description = 'Enable -SkipLimitCheck switch for Import-PowerShellDataFile to not enforce built-in hashtable limits'
+ }
)
}
}
diff --git a/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1
index 3b401f039e..5ea504197f 100644
--- a/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1
+++ b/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1
@@ -37,6 +37,10 @@ PrivateData = @{
Name = 'Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace'
Description = 'Enables -BreakAll parameter on Debug-Runspace and Debug-Job cmdlets to allow users to decide if they want PowerShell to break immediately in the current location when they attach a debugger. Enables -Runspace parameter on *-PSBreakpoint cmdlets to support management of breakpoints in another runspace.'
}
+ @{
+ Name = 'Microsoft.PowerShell.Utility.PSImportPSDataFileSkipLimitCheck'
+ Description = 'Enable -NoLimit switch for Import-PowerShellDataFile to not enforce built-in hashtable limits'
+ }
)
}
}
diff --git a/src/System.Management.Automation/engine/parser/SafeValues.cs b/src/System.Management.Automation/engine/parser/SafeValues.cs
index d7ef5b4cae..a727ae1d28 100644
--- a/src/System.Management.Automation/engine/parser/SafeValues.cs
+++ b/src/System.Management.Automation/engine/parser/SafeValues.cs
@@ -362,7 +362,8 @@ namespace System.Management.Automation.Language
{
Default,
GetPowerShell,
- ModuleAnalysis
+ ModuleAnalysis,
+ SkipHashtableSizeCheck,
}
// future proofing
@@ -371,7 +372,8 @@ namespace System.Management.Automation.Language
public static object GetSafeValue(Ast ast, ExecutionContext context, SafeValueContext safeValueContext)
{
t_context = context;
- if (IsSafeValueVisitor.IsAstSafe(ast, safeValueContext))
+
+ if (safeValueContext == SafeValueContext.SkipHashtableSizeCheck || IsSafeValueVisitor.IsAstSafe(ast, safeValueContext))
{
return ast.Accept(new GetSafeValueVisitor());
}
diff --git a/src/System.Management.Automation/engine/parser/ast.cs b/src/System.Management.Automation/engine/parser/ast.cs
index b9404afa73..e99fd1001c 100644
--- a/src/System.Management.Automation/engine/parser/ast.cs
+++ b/src/System.Management.Automation/engine/parser/ast.cs
@@ -198,6 +198,19 @@ namespace System.Management.Automation.Language
/// If is deemed unsafe
///
public object SafeGetValue()
+ {
+ return SafeGetValue(skipHashtableSizeCheck: false);
+ }
+
+ ///
+ /// Constructs the resultant object from the AST and returns it if it is safe.
+ ///
+ /// Set to skip hashtable limit validation.
+ /// The object represented by the AST as a safe object.
+ ///
+ /// If is deemed unsafe.
+ ///
+ public object SafeGetValue(bool skipHashtableSizeCheck)
{
try
{
@@ -207,7 +220,7 @@ namespace System.Management.Automation.Language
context = System.Management.Automation.Runspaces.Runspace.DefaultRunspace.ExecutionContext;
}
- return GetSafeValueVisitor.GetSafeValue(this, context, GetSafeValueVisitor.SafeValueContext.Default);
+ return GetSafeValueVisitor.GetSafeValue(this, context, skipHashtableSizeCheck ? GetSafeValueVisitor.SafeValueContext.SkipHashtableSizeCheck : GetSafeValueVisitor.SafeValueContext.Default);
}
catch
{
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1
index 6d13be5005..222bbf7e90 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1
@@ -1,6 +1,19 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Tests for the Import-PowerShellDataFile cmdlet" -Tags "CI" {
+ BeforeAll {
+ $largePsd1Path = Join-Path -Path $TestDrive -ChildPath 'large.psd1'
+ $largePsd1Builder = [System.Text.StringBuilder]::new('@{')
+ 1..501 | ForEach-Object {
+ $largePsd1Builder.Append("key$_ = $_;")
+ }
+ $largePsd1Builder.Append('}')
+ Set-Content -Path $largePsd1Path -Value $largePsd1Builder.ToString()
+
+ if ((Get-ExperimentalFeature Microsoft.PowerShell.Utility.PSImportPSDataFileSkipLimitCheck).Enabled -ne $true) {
+ $skipTest = $true
+ }
+ }
It "Validates error on a missing path" {
{ Import-PowerShellDataFile -Path /SomeMissingDirectory -ErrorAction Stop } |
@@ -32,4 +45,12 @@ Describe "Tests for the Import-PowerShellDataFile cmdlet" -Tags "CI" {
$result.Hello | Should -BeExactly "World"
}
+ It 'Fails if psd1 file has more than 500 keys' {
+ { Import-PowerShellDataFile $largePsd1Path } | Should -Throw -ErrorId 'System.InvalidOperationException,Microsoft.PowerShell.Commands.ImportPowerShellDataFileCommand'
+ }
+
+ It 'Succeeds if -NoLimit is used and has more than 500 keys' -Skip:$skipTest {
+ $result = Import-PowerShellDataFile $largePsd1Path -SkipLimitCheck
+ $result.Keys.Count | Should -Be 501
+ }
}