diff --git a/lib/cli/Streams.php b/lib/cli/Streams.php index 3d91d0a..71b454f 100755 --- a/lib/cli/Streams.php +++ b/lib/cli/Streams.php @@ -41,9 +41,11 @@ public static function render( $msg ) { // If the first argument is not an array just pass to sprintf if( !is_array( $args[1] ) ) { - // Colorize the message first so sprintf doesn't bitch at us + // Normalize color tokens before sprintf: colorize or strip them so no raw %tokens reach sprintf if ( Colors::shouldColorize() ) { $args[0] = Colors::colorize( $args[0] ); + } else { + $args[0] = Colors::decolorize( $args[0] ); } // Escape percent characters for sprintf diff --git a/tests/Test_Cli.php b/tests/Test_Cli.php index d5101a2..bd4476d 100644 --- a/tests/Test_Cli.php +++ b/tests/Test_Cli.php @@ -553,4 +553,20 @@ function test_safe_strlen() { mb_detect_order( $mb_detect_order ); } } + + function test_render_with_color_tokens_and_sprintf_args_colors_disabled() { + Colors::disable( true ); + + // Color tokens in format string must not cause "sprintf(): Too few arguments". + $result = \cli\render( '[%C%k%s%N] Starting!', '2024-01-01 12:00:00' ); + $this->assertSame( '[2024-01-01 12:00:00] Starting!', $result ); + } + + function test_render_with_color_tokens_and_sprintf_args_colors_enabled() { + Colors::enable( true ); + + $result = \cli\render( '[%C%k%s%N] Starting!', '2024-01-01 12:00:00' ); + $this->assertStringContainsString( '2024-01-01 12:00:00', $result ); + $this->assertStringContainsString( 'Starting!', $result ); + } }