From 5f92117b97d4e32a39da0b0e8bff3bb6c7317837 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 4 Mar 2022 11:25:01 -0800 Subject: [PATCH] Allow a collection with 'Automation.Null' elements to be piped to pipeline --- .../engine/Pipe.cs | 23 +++++++++++++++---- .../Scripting/PipelineBehaviour.Tests.ps1 | 21 +++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/System.Management.Automation/engine/Pipe.cs b/src/System.Management.Automation/engine/Pipe.cs index 9e24c6471db..2669e41ce31 100644 --- a/src/System.Management.Automation/engine/Pipe.cs +++ b/src/System.Management.Automation/engine/Pipe.cs @@ -559,15 +559,28 @@ internal object Retrieve() else if (_enumeratorToProcess != null) { if (_enumeratorToProcessIsEmpty) - return AutomationNull.Value; - - if (!ParserOps.MoveNext(_context, null, _enumeratorToProcess)) { - _enumeratorToProcessIsEmpty = true; return AutomationNull.Value; } - return ParserOps.Current(null, _enumeratorToProcess); + while (true) + { + if (!ParserOps.MoveNext(_context, errorPosition: null, _enumeratorToProcess)) + { + _enumeratorToProcessIsEmpty = true; + return AutomationNull.Value; + } + + object retValue = ParserOps.Current(errorPosition: null, _enumeratorToProcess); + if (retValue == AutomationNull.Value) + { + // 'AutomationNull.Value' from the enumerator won't be sent to the pipeline. + // We try to get the next value in this case. + continue; + } + + return retValue; + } } else if (ExternalReader != null) { diff --git a/test/powershell/Language/Scripting/PipelineBehaviour.Tests.ps1 b/test/powershell/Language/Scripting/PipelineBehaviour.Tests.ps1 index 0478492c910..04993c80a9f 100644 --- a/test/powershell/Language/Scripting/PipelineBehaviour.Tests.ps1 +++ b/test/powershell/Language/Scripting/PipelineBehaviour.Tests.ps1 @@ -602,3 +602,24 @@ Describe 'Function Pipeline Behaviour' -Tag 'CI' { #> } } + +Describe 'Other Pipeline Behaviour' -Tag 'CI' { + It "Array with 'Automation.Null' elements can be piped to pipeline" { + $automationNull = & {} + + ## 'Automation.Null' elements will not be sent to the pipeline (skipped). + 1, $automationNull, 2, $automationNull, 3, 4, 5 | ForEach-Object { $_ } | Should -Be (1..5) + $array = 1, $automationNull, 2, $automationNull, 3, 4, 5 + $array.Count | Should -Be 7 + $array | ForEach-Object { $_ } | Should -Be (1..5) + } + + It "Automation.Null is not written to pipeline in a function" { + $automationNull = & {} + + function MyTest { 1, $automationNull, 2, $automationNull, 3, 4, 5 } + $result = MyTest + $result.Count | Should -Be 5 + MyTest | Should -Be (1..5) + } +}