Skip to content

Bound member invocation logging argument strings#27513

Open
KirtiRamchandani wants to merge 2 commits into
PowerShell:masterfrom
KirtiRamchandani:fix/bound-member-invocation-logging
Open

Bound member invocation logging argument strings#27513
KirtiRamchandani wants to merge 2 commits into
PowerShell:masterfrom
KirtiRamchandani:fix/bound-member-invocation-logging

Conversation

@KirtiRamchandani
Copy link
Copy Markdown

@KirtiRamchandani KirtiRamchandani commented May 24, 2026

PR Summary

Bounds long string values included in member invocation logging while preserving the method invocation and recording the original string length.

PR Context

Addresses #21473.

MemberInvocationLoggingOps.ArgumentToString() currently returns full string arguments, so LogMemberInvocation() can build very large AMSI report content for calls such as FromBase64String with large strings. This change keeps strings at or below the limit unchanged, caps longer logged string values to 4096 characters total, and appends a marker with the original length. It also applies the same bound to special primitive-like ToString() results, such as very large BigInteger values.

PR Checklist

  • PR has a meaningful title
  • Summarized changes
  • This PR is focused on one issue
  • Make sure all .h, .cpp, .cs, .ps1 and .psm1 files have the correct copyright header
  • This PR is ready to merge and is not work-in-progress
  • Breaking change: No
  • User-facing change: Not required
  • Tests added/updated

Validation

  • Start-PSBuild -PSModuleRestore -UseNuGetOrg built pwsh.exe. The Windows PowerShell 5.1 build wrapper emitted post-build ConvertFrom-Json -Depth compatibility warnings after build output was produced.
  • Start-PSPester -Path test/powershell/engine/Logging/MemberInvocationLogging.Tests.ps1 -UseNuGetOrg -ThrowOnFailure -Terse -SkipTestToolBuild passed: 4 passed, 0 failed.

@KirtiRamchandani KirtiRamchandani marked this pull request as ready for review May 24, 2026 07:31
@KirtiRamchandani KirtiRamchandani requested a review from a team as a code owner May 24, 2026 07:31
Copilot AI review requested due to automatic review settings May 24, 2026 07:31
@KirtiRamchandani
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@KirtiRamchandani KirtiRamchandani requested a review from Copilot May 24, 2026 08:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

Comment on lines +3670 to +3674
return string.Concat(
value.AsSpan(0, MaxLoggedArgumentStringLength),
"...<truncated; original length: ".AsSpan(),
originalLength.AsSpan(),
">".AsSpan());
);
#endif

private const int MaxLoggedArgumentStringLength = 4096;
Comment on lines +12 to +26
It 'Keeps short string arguments unchanged' {
$value = 'short argument'

$argumentToString.Invoke($null, [object[]]@($value)) | Should -BeExactly $value
}

It 'Limits long string arguments' {
$value = 'a' * 5000

$result = $argumentToString.Invoke($null, [object[]]@($value))

$result.Length | Should -BeLessThan $value.Length
$result.StartsWith(('a' * 4096), [System.StringComparison]::Ordinal) | Should -BeTrue
$result | Should -Match '<truncated; original length: 5000>'
}
Comment on lines +19 to +25
$value = 'a' * 5000

$result = $argumentToString.Invoke($null, [object[]]@($value))

$result.Length | Should -BeLessThan $value.Length
$result.StartsWith(('a' * 4096), [System.StringComparison]::Ordinal) | Should -BeTrue
$result | Should -Match '<truncated; original length: 5000>'
Comment on lines +19 to +25
$value = 'a' * 5000

$result = $argumentToString.Invoke($null, [object[]]@($value))

$result.Length | Should -BeLessThan $value.Length
$result.StartsWith(('a' * 4096), [System.StringComparison]::Ordinal) | Should -BeTrue
$result | Should -Match '<truncated; original length: 5000>'
@KirtiRamchandani KirtiRamchandani requested a review from Copilot May 24, 2026 13:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

$value = 'a' * $originalLength

$result = $argumentToString.Invoke($null, [object[]]@($value))
$truncationMarker = "...<truncated; original length: $originalLength>"

$result.Length | Should -Be $maxLoggedArgumentStringLength
$result.StartsWith(('a' * $expectedPrefixLength), [System.StringComparison]::Ordinal) | Should -BeTrue
$result | Should -Match $truncationMarker

$result.Length | Should -Be $maxLoggedArgumentStringLength
$result.Length | Should -BeLessThan $value.Length
$result | Should -Match "<truncated; original length: $originalLength>"
|| baseType == typeof(decimal))
{
return baseObj.ToString();
return LimitLoggedArgumentString(baseObj.ToString());
$type = [psobject].Assembly.GetType('System.Management.Automation.MemberInvocationLoggingOps')
$argumentToString = $type.GetMethod(
'ArgumentToString',
[System.Reflection.BindingFlags]'NonPublic, Static')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants