Honor -OutputFormat
if specified in noninteractive, redirected, encoded command used with pwsh (#8115)
[Breaking Change] There is specific code that sets the `OutputFormat` to xml if pwsh is run non-interactive, with redirected output, and the command was encoded. However, it ignored whether OutputFormat was specified. Fix is to track whether `-OutputFormat` was used and respect that value rather than defaulting to xml. Fix https://github.com/PowerShell/PowerShell/issues/5912
This commit is contained in:
parent
8215914b46
commit
1aa5bb3576
|
@ -349,6 +349,16 @@ namespace Microsoft.PowerShell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool OutputFormatSpecified
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Dbg.Assert(_dirty, "Parse has not been called yet");
|
||||||
|
|
||||||
|
return _outputFormatSpecified;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal Serialization.DataFormat InputFormat
|
internal Serialization.DataFormat InputFormat
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -849,6 +859,7 @@ namespace Microsoft.PowerShell
|
||||||
else if (MatchSwitch(switchKey, "outputformat", "o") || MatchSwitch(switchKey, "of", "o"))
|
else if (MatchSwitch(switchKey, "outputformat", "o") || MatchSwitch(switchKey, "of", "o"))
|
||||||
{
|
{
|
||||||
ParseFormat(args, ref i, ref _outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter);
|
ParseFormat(args, ref i, ref _outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter);
|
||||||
|
_outputFormatSpecified = true;
|
||||||
}
|
}
|
||||||
else if (MatchSwitch(switchKey, "inputformat", "in") || MatchSwitch(switchKey, "if", "if"))
|
else if (MatchSwitch(switchKey, "inputformat", "in") || MatchSwitch(switchKey, "if", "if"))
|
||||||
{
|
{
|
||||||
|
@ -1347,6 +1358,7 @@ namespace Microsoft.PowerShell
|
||||||
private uint _exitCode = ConsoleHost.ExitCodeSuccess;
|
private uint _exitCode = ConsoleHost.ExitCodeSuccess;
|
||||||
private bool _dirty;
|
private bool _dirty;
|
||||||
private Serialization.DataFormat _outFormat = Serialization.DataFormat.Text;
|
private Serialization.DataFormat _outFormat = Serialization.DataFormat.Text;
|
||||||
|
private bool _outputFormatSpecified = false;
|
||||||
private Serialization.DataFormat _inFormat = Serialization.DataFormat.Text;
|
private Serialization.DataFormat _inFormat = Serialization.DataFormat.Text;
|
||||||
private Collection<CommandParameter> _collectedArgs = new Collection<CommandParameter>();
|
private Collection<CommandParameter> _collectedArgs = new Collection<CommandParameter>();
|
||||||
private string _file;
|
private string _file;
|
||||||
|
|
|
@ -1194,6 +1194,7 @@ namespace Microsoft.PowerShell
|
||||||
}
|
}
|
||||||
|
|
||||||
internal WrappedSerializer.DataFormat OutputFormat { get; private set; }
|
internal WrappedSerializer.DataFormat OutputFormat { get; private set; }
|
||||||
|
internal bool OutputFormatSpecified { get; private set; }
|
||||||
|
|
||||||
internal WrappedSerializer.DataFormat InputFormat { get; private set; }
|
internal WrappedSerializer.DataFormat InputFormat { get; private set; }
|
||||||
|
|
||||||
|
@ -1203,9 +1204,9 @@ namespace Microsoft.PowerShell
|
||||||
{
|
{
|
||||||
WrappedDeserializer.DataFormat format = OutputFormat;
|
WrappedDeserializer.DataFormat format = OutputFormat;
|
||||||
|
|
||||||
//If this shell is invoked in minishell interop mode and error is redirected,
|
// If this shell is invoked in non-interactive, error is redirected, and OutputFormat was not
|
||||||
//always write data in error stream in xml format.
|
// specified write data in error stream in xml format assuming PowerShell->PowerShell usage.
|
||||||
if (IsInteractive == false && Console.IsErrorRedirected && _wasInitialCommandEncoded)
|
if (!OutputFormatSpecified && IsInteractive == false && Console.IsErrorRedirected && _wasInitialCommandEncoded)
|
||||||
{
|
{
|
||||||
format = Serialization.DataFormat.XML;
|
format = Serialization.DataFormat.XML;
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1316,7 @@ namespace Microsoft.PowerShell
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputFormat = cpp.OutputFormat;
|
OutputFormat = cpp.OutputFormat;
|
||||||
|
OutputFormatSpecified = cpp.OutputFormatSpecified;
|
||||||
InputFormat = cpp.InputFormat;
|
InputFormat = cpp.InputFormat;
|
||||||
_wasInitialCommandEncoded = cpp.WasInitialCommandEncoded;
|
_wasInitialCommandEncoded = cpp.WasInitialCommandEncoded;
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,19 @@ Describe "ConsoleHost unit tests" -tags "Feature" {
|
||||||
# Join (multiple lines) and remove whitespace (we don't care about spacing) to verify we converted to string (by generating a table)
|
# Join (multiple lines) and remove whitespace (we don't care about spacing) to verify we converted to string (by generating a table)
|
||||||
-join (& $powershell -noprofile -outputFormat text { [PSCustomObject]@{X=10;Y=20} }) -replace "\s","" | Should -Be "XY--1020"
|
-join (& $powershell -noprofile -outputFormat text { [PSCustomObject]@{X=10;Y=20} }) -replace "\s","" | Should -Be "XY--1020"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
It "errors are in text if error is redirected, encoded command, non-interactive, and outputformat specified" {
|
||||||
|
$p = [Diagnostics.Process]::new()
|
||||||
|
$p.StartInfo.FileName = "pwsh"
|
||||||
|
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes("throw 'boom'"))
|
||||||
|
$p.StartInfo.Arguments = "-EncodedCommand $encoded -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -OutputFormat text"
|
||||||
|
$p.StartInfo.UseShellExecute = $false
|
||||||
|
$p.StartInfo.RedirectStandardError = $true
|
||||||
|
$p.Start() | Out-Null
|
||||||
|
$out = $p.StandardError.ReadToEnd()
|
||||||
|
$out | Should -Not -BeNullOrEmpty
|
||||||
|
$out.Split([Environment]::NewLine)[0] | Should -BeExactly "boom"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Context "Redirected standard output" {
|
Context "Redirected standard output" {
|
||||||
|
|
Loading…
Reference in a new issue