diff --git a/src/xsprintf/PhutilTerminalString.php b/src/xsprintf/PhutilTerminalString.php index 8d99b093..1d42f288 100644 --- a/src/xsprintf/PhutilTerminalString.php +++ b/src/xsprintf/PhutilTerminalString.php @@ -1,75 +1,82 @@ string = $string; } public function __toString() { return $this->string; } public function applyWrap() { $string = (string)$this; $string = phutil_console_wrap($string); return new self($string); } public function applyIndent($depth, $with_prefix = true) { $string = (string)$this; $string = phutil_console_wrap($string, $depth, $with_prefix); return new self($string); } public static function escapeStringValue($value, $allow_whitespace) { if ($value instanceof PhutilTerminalString) { return (string)$value; } $value = (string)$value; static $escape_map; if ($escape_map === null) { $escape_map = array( chr(0x00) => '', chr(0x07) => '', chr(0x08) => '', chr(0x09) => '', chr(0x0A) => '', chr(0x0D) => '', chr(0x1B) => '', chr(0x7F) => '', ); for ($ii = 0; $ii < 32; $ii++) { $c = chr($ii); if (empty($escape_map[$c])) { $escape_map[$c] = sprintf('<0x%02X>', $ii); } } } $map = $escape_map; if ($allow_whitespace) { unset($map["\r"]); unset($map["\n"]); unset($map["\t"]); } $value = str_replace(array_keys($map), array_values($map), $value); // In this mode, we additionally escape any which is not immediately // followed by . if ($allow_whitespace) { $value = preg_replace('/\r(?!\n)/', '', $value); } + // See T13209. If we print certain invalid unicode byte sequences to the + // terminal under "cmd.exe", the entire string is silently dropped. Avoid + // printing invalid sequences. + if (phutil_is_windows()) { + $value = phutil_utf8ize($value); + } + return $value; } }