Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1520,11 +1520,7 @@ private static bool WriteScriptBlockToLog(ScriptBlock scriptBlock, int segment,

Comment thread
TravisEz13 marked this conversation as resolved.
Comment thread
TravisEz13 marked this conversation as resolved.
Comment thread
TravisEz13 marked this conversation as resolved.
Comment thread
TravisEz13 marked this conversation as resolved.
if (!wasEncoded)
{
// The logging mechanism(s) cannot handle null and rendering may not be able to handle
// null as we have the string defined as a null terminated string in the manifest.
// So, replace null characters with the Unicode `SYMBOL FOR NULL`
// We don't just remove the characters to preserve the fact that a null character was there.
textToLog = textToLog.Replace('\u0000', '\u2400');
textToLog = FormatLogString(textToLog);
}

if (scriptBlock._scriptBlockData.HasSuspiciousContent)
Expand Down Expand Up @@ -1557,6 +1553,50 @@ private static bool WriteScriptBlockToLog(ScriptBlock scriptBlock, int segment,
return true;
}

private static string FormatLogString(string textToLog)
{
const char NullControlChar = '\u0000';

// The null symbol - `␀`
const char NullSymbolChar = '\u2400';

// No logging mechanism(s) cannot handle null and rendering may not be able to handle
// null as we have the string defined as a null terminated string in the manifest.
// So, replace null characters with the Unicode `SYMBOL FOR NULL`
// We don't just remove the characters to preserve the fact that a null character was there.
#if UNIX
const char LinefeedControlChar = '\u000A';
const char CarriageReturnControlChar = '\u000D';

// We chose the return symbol because we believe it is more associated with these concepts
// than the carriage return (␍), line feed (␊), or new line (␤) symbols.
// The return symbol - `⏎`
const char ReturnSymbolChar = '\u23CE';

if (Platform.IsLinux)
{
// Because the creation of the string builder is expensive
// We only do this on Linux where we are doing multiple replace operations
StringBuilder logBuilder = new StringBuilder(textToLog);

logBuilder.Replace(NullControlChar, NullSymbolChar);

// Syslog (only used on Linux) encodes CR and NL to their octal values.
// We will replace them with a unicode 'RETURN SYMBOL' (U+23CE) charater for easier viewing
logBuilder.Replace(LinefeedControlChar, ReturnSymbolChar);
logBuilder.Replace(CarriageReturnControlChar, ReturnSymbolChar);

return logBuilder.ToString();
}
else
{
return textToLog.Replace(NullControlChar, NullSymbolChar);
}
#else
return textToLog.Replace(NullControlChar, NullSymbolChar);
#endif
}

private static bool GetAndValidateEncryptionRecipients(
ScriptBlock scriptBlock,
ProtectedEventLogging logSetting)
Expand Down
10 changes: 5 additions & 5 deletions test/powershell/Host/Logging.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ Describe 'Basic SysLog tests on Linux' -Tag @('CI','RequireSudoOnUnix') {
$IsSupportedEnvironment = $false
}
[string] $powershell = Join-Path -Path $PSHome -ChildPath 'pwsh'
$scriptBlockCreatedRegExTemplate = @'
Creating Scriptblock text \(1 of 1\):#012{0}(#012)*ScriptBlock ID: [0-9a-z\-]*#012Path:.*
'@
$scriptBlockCreatedRegExTemplate = @"
Creating Scriptblock text \(1 of 1\):#012{0}(⏎|#012)*ScriptBlock ID: [0-9a-z\-]*#012Path:.*
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? `u{23CE} looks more clear for me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests fail if we use the escape sequence.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to copy and paster the code in console and lost the char. Also the tests become unreadable. I wonder why doesn't the Unicode syntax sugar work?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iSazonov that's going to vary by the font you use. I worked with @rjmholt to come up with this solution. The previous solution that was working, was actually just looking for a ? which is less specific.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember that we had Unicode chars in files and it was a headache - editors silently break them. After that we made a conclusion to keep all files in ASCII.

"@

}
}
Expand Down Expand Up @@ -211,7 +211,7 @@ $pid
$createdEvents[0].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f ".*/$testFileName")

# Verify we log that we are the script to create the scriptblock
$createdEvents[1].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f (Get-RegEx -SimpleMatch $Script.Replace([System.Environment]::NewLine,'#012')))
$createdEvents[1].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f (Get-RegEx -SimpleMatch $Script.Replace([System.Environment]::NewLine,"⏎")))

# Verify we log that we are excuting the created scriptblock
$createdEvents[2].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f "Write\-Verbose 'testheader123' ;Write\-verbose 'after'")
Expand Down Expand Up @@ -240,7 +240,7 @@ $pid
$createdEvents[0].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f ".*/$testFileName")

# Verify we log that we are the script to create the scriptblock
$createdEvents[1].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f (Get-RegEx -SimpleMatch $Script.Replace([System.Environment]::NewLine,'#012')))
$createdEvents[1].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f (Get-RegEx -SimpleMatch $Script.Replace([System.Environment]::NewLine,"⏎")))

# Verify we log that we are excuting the created scriptblock
$createdEvents[2].Message | Should -Match ($scriptBlockCreatedRegExTemplate -f "Write\-Verbose 'testheader123␀' ;Write\-verbose 'after'")
Expand Down