Skip to content

Overriding .NETs ToString() method can cause unexpected behaviour when using Transcripts #23804

Open
@dhermanconsulting

Description

@dhermanconsulting

Prerequisites

Steps to reproduce

When PowerShell Transcripting is enabled, this code is invoked, which calls ToString() against any parameter passed to a cmdlet, regardless of type.

If the ToString() method which is called also calls a cmdlet with $this, this creates infinite recursion as the linked code keeps calling ToString(), which calls a cmdlet, which calls ToString() etc.

The issue is not observed when transcription is disabled.

This recursion causes the script to slow dramatically - I assume it is exhausting the stack, throwing a handled exception, which then allows everything to unwind and continue execution.

The below is a contrived/minimal example to demonstrate the issue:

Start-Transcript

$global:CountCalls = 0

function Get-Name {

    param(
        [TestClassA] $Arg
    )

    return $testClassA.NameProperty

}

function Random-CmdLet {

    param(
        [TestClassA] $Arg
    )

    return $true

}

class TestClassA {

    [string] $NameProperty = "MyName"

     [string] ToString() {

        $global:CountCalls++

        return Get-Name -Arg $this
    }

}

[System.Diagnostics.Stopwatch] $stopWatchA = [System.Diagnostics.Stopwatch]::StartNew()

$testClassA = [TestClassA]::New()

Random-CmdLet -Arg $testClassA

$stopWatchA.Stop()

$stopWatchA.Elapsed.TotalMilliseconds | Write-Host

"Calls to ToString(): {0}" -f $CountCalls | Write-Host 

Expected behavior

Transcript started, output file is xyz.txt
True
4
Calls to ToString(): 0

Actual behavior

Transcript started, output file is xyz.txt
True
82.7247
Calls to ToString(): 418

Error details

No response

Environment data

PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Microsoft Windows 10.0.22631
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions