Handle isolated \r in doc string

Doc strings have a trailing \n and these will get interpreted as
\r\n and removed from the string contents.

For nowdoc, fall back to single quote if there's a trailing \r.
For heredoc, escape all isolated \r -- unlike \n and \r\n this is
really a special character, because this is no longer relevant as
an actual newline character.
This commit is contained in:
Nikita Popov 2023-02-27 22:00:49 +01:00
parent 8e100f1e69
commit 57d4a02659
3 changed files with 15 additions and 5 deletions

View File

@ -137,8 +137,11 @@ class Standard extends PrettyPrinterAbstract {
return "<<<'$label'\n$label" . $this->docStringEndToken;
}
return "<<<'$label'\n$node->value\n$label"
. $this->docStringEndToken;
// Make sure trailing \r is not combined with following \n into CRLF.
if ($node->value[strlen($node->value) - 1] !== "\r") {
return "<<<'$label'\n$node->value\n$label"
. $this->docStringEndToken;
}
}
/* break missing intentionally */
// no break
@ -1042,6 +1045,9 @@ class Standard extends PrettyPrinterAbstract {
if (null === $quote) {
// For doc strings, don't escape newlines
$escaped = addcslashes($string, "\t\f\v$\\");
// But do escape isolated \r. Combined with the terminating newline, it might get
// interpreted as \r\n and dropped from the string contents.
$escaped = preg_replace('/\r(?!\n)/', '\\r', $escaped);
} else {
$escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\");
}

View File

@ -122,6 +122,10 @@ class PrettyPrinterTest extends CodeTestAbstract {
[new String_("", $nowdoc), "<<<'STR'\nSTR\n"],
[new String_("", $heredoc), "<<<STR\nSTR\n"],
[new InterpolatedString([new InterpolatedStringPart('')], $heredoc), "<<<STR\nSTR\n"],
// Isolated \r in doc string
[new String_("\r", $heredoc), "<<<STR\n\\r\nSTR\n"],
[new String_("\r", $nowdoc), "'\r'"],
[new String_("\rx", $nowdoc), "<<<'STR'\n\rx\nSTR\n"],
// Encapsed doc string variations
[new InterpolatedString([new InterpolatedStringPart('foo')], $heredoc), "<<<STR\nfoo\nSTR\n"],
[new InterpolatedString([new InterpolatedStringPart('foo'), new Expr\Variable('y')], $heredoc), "<<<STR\nfoo{\$y}\nSTR\n"],

View File

@ -25,9 +25,9 @@ DOC;
"\xd0\x01";
"\xf0\x80\x80";
<<<DOC
@@{ "\n\r" }@@\t\f\v\$\\"\\
\x00\x01\x02\x03\x04\x05\x06\x07\x08\t@@{ "\n" }@@\v\f@@{ "\r" }@@\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
@@{ "\n" }@@\r\t\f\v\$\\"\\
\x00\x01\x02\x03\x04\x05\x06\x07\x08\t@@{ "\n" }@@\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
\x000\x001
äöü
DOC
;
;