Skip to content

Commit 6366639

Browse files
Copilotswissspidy
andauthored
Fix internal variable bleeding in REPL eval context (#80)
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Pascal Birchler <pascal.birchler@gmail.com>
1 parent de92dc6 commit 6366639

2 files changed

Lines changed: 54 additions & 16 deletions

File tree

features/shell.feature

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,44 @@ Feature: WordPress REPL
7878
history: -1: invalid option
7979
"""
8080
81+
Scenario: User can define variable named $line
82+
Given a WP install
83+
And a session file:
84+
"""
85+
$line = 'this should work';
86+
$line;
87+
"""
88+
89+
When I run `wp shell --basic < session`
90+
Then STDOUT should contain:
91+
"""
92+
=> string(16) "this should work"
93+
"""
94+
And STDOUT should contain:
95+
"""
96+
=> string(16) "this should work"
97+
"""
98+
99+
Scenario: User can define variables named $out and $evl
100+
Given a WP install
101+
And a session file:
102+
"""
103+
$out = 'out should work';
104+
$evl = 'evl should work';
105+
$out;
106+
$evl;
107+
"""
108+
109+
When I run `wp shell --basic < session`
110+
Then STDOUT should contain:
111+
"""
112+
=> string(15) "out should work"
113+
"""
114+
And STDOUT should contain:
115+
"""
116+
=> string(15) "evl should work"
117+
"""
118+
81119
Scenario: Shell with hook parameter
82120
Given a WP install
83121
And a session file:

src/WP_CLI/Shell/REPL.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,38 @@ public function __construct( $prompt ) {
1919
public function start() {
2020
// @phpstan-ignore while.alwaysTrue
2121
while ( true ) {
22-
$line = $this->prompt();
22+
$__repl_input_line = $this->prompt();
2323

24-
if ( '' === $line ) {
24+
if ( '' === $__repl_input_line ) {
2525
continue;
2626
}
2727

28-
$line = rtrim( $line, ';' ) . ';';
28+
$__repl_input_line = rtrim( $__repl_input_line, ';' ) . ';';
2929

30-
if ( self::starts_with( self::non_expressions(), $line ) ) {
30+
if ( self::starts_with( self::non_expressions(), $__repl_input_line ) ) {
3131
ob_start();
3232
// phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval.
33-
eval( $line );
34-
$out = (string) ob_get_clean();
35-
if ( 0 < strlen( $out ) ) {
36-
$out = rtrim( $out, "\n" ) . "\n";
33+
eval( $__repl_input_line );
34+
$__repl_output = (string) ob_get_clean();
35+
if ( 0 < strlen( $__repl_output ) ) {
36+
$__repl_output = rtrim( $__repl_output, "\n" ) . "\n";
3737
}
38-
fwrite( STDOUT, $out );
38+
fwrite( STDOUT, $__repl_output );
3939
} else {
40-
if ( ! self::starts_with( 'return', $line ) ) {
41-
$line = 'return ' . $line;
40+
if ( ! self::starts_with( 'return', $__repl_input_line ) ) {
41+
$__repl_input_line = 'return ' . $__repl_input_line;
4242
}
4343

4444
// Write directly to STDOUT, to sidestep any output buffers created by plugins
4545
ob_start();
4646
// phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval.
47-
$evl = eval( $line );
48-
$out = (string) ob_get_clean();
49-
if ( 0 < strlen( $out ) ) {
50-
echo rtrim( $out, "\n" ) . "\n";
47+
$__repl_eval_result = eval( $__repl_input_line );
48+
$__repl_output = (string) ob_get_clean();
49+
if ( 0 < strlen( $__repl_output ) ) {
50+
echo rtrim( $__repl_output, "\n" ) . "\n";
5151
}
5252
echo '=> ';
53-
var_dump( $evl );
53+
var_dump( $__repl_eval_result );
5454
fwrite( STDOUT, (string) ob_get_clean() );
5555
}
5656
}

0 commit comments

Comments
 (0)