Skip to content

Exception trace arguments can be modified by reference #18614

@kkmuffme

Description

@kkmuffme

Description

The following code:

https://3v4l.org/1SGGd#v8.4.7

<?php

function byref( &$arg ) {
    $arg = 'abc';
}

function bar($a) {
    $x = new Exception();
    $trace = $x->getTrace();
    
    foreach ( $trace as $frame ) {
        if ( empty( $frame['args'] ) ) {
              continue;
        }
        
        foreach ( $frame['args'] as $key => $arg ) {
            if ( is_array( $arg ) ) {
                // array_walk_recursive( $arg, 'byref' );
                // same issue when doing it manually:
                foreach ( $arg as &$foo ) {
                    $foo = 'xyz';
                }
                unset( $foo );
            }
        }
    }
}

$b = array( 'X', 'Y' );
foreach ( $b as &$value ) {
    bar( $b );
    var_dump( $value );
}

Resulted in this output:

xyz
xyz

But I expected this output instead:

X
Y

The practical use case is that when an error (e.g. trigger_error) or exception is thrown and handled, that the error handler is able to modify params by reference (accidentally) that will possible later be used again.
This also means however, that by using a new Exception or possibly by causing an error, any code is suddenly able to modify variables by reference to which the code would usually not have access to.

Is this intended? If yes, do you think this is something that should be explicitly documented on the getTrace() doc page?

PHP Version

8.4.7 (error is there since forever though)

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions