From 1c5f7d6b0b03577ce899ad3e1a042f6ddfaab1e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:58:59 +0000 Subject: [PATCH 1/3] Initial plan From 31bf8158615f6bba9bb37b331e317454937b49e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 17:04:03 +0000 Subject: [PATCH 2/3] Rename internal variables to prevent bleeding into eval context Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/shell.feature | 18 +++++++++++++++ src/WP_CLI/Shell/REPL.php | 48 +++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index d5595506..607c597b 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -77,3 +77,21 @@ Feature: WordPress REPL """ history: -1: invalid option """ + + Scenario: User can define variable named $line + Given a WP install + And a session file: + """ + $line = 'this should work'; + $line; + """ + + When I run `wp shell --basic < session` + Then STDOUT should contain: + """ + => string(16) "this should work" + """ + And STDOUT should contain: + """ + => string(16) "this should work" + """ diff --git a/src/WP_CLI/Shell/REPL.php b/src/WP_CLI/Shell/REPL.php index 99b8f1f8..a7d969ee 100644 --- a/src/WP_CLI/Shell/REPL.php +++ b/src/WP_CLI/Shell/REPL.php @@ -19,38 +19,38 @@ public function __construct( $prompt ) { public function start() { // @phpstan-ignore while.alwaysTrue while ( true ) { - $line = $this->prompt(); + $__repl_input_line = $this->prompt(); - if ( '' === $line ) { + if ( '' === $__repl_input_line ) { continue; } - $line = rtrim( $line, ';' ) . ';'; + $__repl_input_line = rtrim( $__repl_input_line, ';' ) . ';'; - if ( self::starts_with( self::non_expressions(), $line ) ) { + if ( self::starts_with( self::non_expressions(), $__repl_input_line ) ) { ob_start(); // phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval. - eval( $line ); - $out = (string) ob_get_clean(); - if ( 0 < strlen( $out ) ) { - $out = rtrim( $out, "\n" ) . "\n"; + eval( $__repl_input_line ); + $__repl_output = (string) ob_get_clean(); + if ( 0 < strlen( $__repl_output ) ) { + $__repl_output = rtrim( $__repl_output, "\n" ) . "\n"; } - fwrite( STDOUT, $out ); + fwrite( STDOUT, $__repl_output ); } else { - if ( ! self::starts_with( 'return', $line ) ) { - $line = 'return ' . $line; + if ( ! self::starts_with( 'return', $__repl_input_line ) ) { + $__repl_input_line = 'return ' . $__repl_input_line; } // Write directly to STDOUT, to sidestep any output buffers created by plugins ob_start(); // phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval. - $evl = eval( $line ); - $out = (string) ob_get_clean(); - if ( 0 < strlen( $out ) ) { - echo rtrim( $out, "\n" ) . "\n"; + $__repl_eval_result = eval( $__repl_input_line ); + $__repl_output = (string) ob_get_clean(); + if ( 0 < strlen( $__repl_output ) ) { + echo rtrim( $__repl_output, "\n" ) . "\n"; } echo '=> '; - var_dump( $evl ); + var_dump( $__repl_eval_result ); fwrite( STDOUT, (string) ob_get_clean() ); } } @@ -88,25 +88,25 @@ private function prompt() { $fp = popen( self::create_prompt_cmd( $prompt, $this->history_file ), 'r' ); - $line = $fp ? fgets( $fp ) : ''; + $__repl_input_line = $fp ? fgets( $fp ) : ''; if ( $fp ) { pclose( $fp ); } - if ( ! $line ) { + if ( ! $__repl_input_line ) { break; } - $line = rtrim( $line, "\n" ); + $__repl_input_line = rtrim( $__repl_input_line, "\n" ); - if ( $line && '\\' === $line[ strlen( $line ) - 1 ] ) { - $line = substr( $line, 0, -1 ); + if ( $__repl_input_line && '\\' === $__repl_input_line[ strlen( $__repl_input_line ) - 1 ] ) { + $__repl_input_line = substr( $__repl_input_line, 0, -1 ); } else { $done = true; } - $full_line .= $line; + $full_line .= $__repl_input_line; } while ( ! $done ); @@ -150,7 +150,7 @@ private function set_history_file() { $this->history_file = \WP_CLI\Utils\get_temp_dir() . 'wp-cli-history-' . md5( $data ); } - private static function starts_with( $tokens, $line ) { - return preg_match( "/^($tokens)[\(\s]+/", $line ); + private static function starts_with( $tokens, $__repl_input_line ) { + return preg_match( "/^($tokens)[\(\s]+/", $__repl_input_line ); } } From ecaf2e704b7ec69c9d5c3204e4148c4532084e46 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 17:04:33 +0000 Subject: [PATCH 3/3] Add test for $out and $evl variables Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/shell.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/features/shell.feature b/features/shell.feature index 607c597b..052a723d 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -95,3 +95,23 @@ Feature: WordPress REPL """ => string(16) "this should work" """ + + Scenario: User can define variables named $out and $evl + Given a WP install + And a session file: + """ + $out = 'out should work'; + $evl = 'evl should work'; + $out; + $evl; + """ + + When I run `wp shell --basic < session` + Then STDOUT should contain: + """ + => string(15) "out should work" + """ + And STDOUT should contain: + """ + => string(15) "evl should work" + """