diff --git a/lib/PhpParser/PrettyPrinter/Standard.php b/lib/PhpParser/PrettyPrinter/Standard.php index 1e9aa4b1..99cfd17c 100644 --- a/lib/PhpParser/PrettyPrinter/Standard.php +++ b/lib/PhpParser/PrettyPrinter/Standard.php @@ -997,7 +997,12 @@ class Standard extends PrettyPrinterAbstract } protected function pSingleQuotedString(string $string) { - return '\'' . addcslashes($string, '\'\\') . '\''; + // It is idiomatic to only escape backslashes when necessary, i.e. when followed by ', \ or + // the end of the string ('Foo\Bar' instead of 'Foo\\Bar'). However, we also don't want to + // produce an odd number of backslashes, so '\\\\a' should not get rendered as '\\\a', even + // though that would be legal. + $regex = '/\'|\\\\(?=[\'\\\\]|$)|(?<=\\\\)\\\\/'; + return '\'' . preg_replace($regex, '\\\\$0', $string) . '\''; } protected function escapeString($string, $quote) { diff --git a/test/code/prettyPrinter/expr/literals.test b/test/code/prettyPrinter/expr/literals.test index f649b5d0..0d92b388 100644 --- a/test/code/prettyPrinter/expr/literals.test +++ b/test/code/prettyPrinter/expr/literals.test @@ -47,6 +47,8 @@ b'; 'a\'b'; 'a\b'; 'a\\'; +'a\\\\b'; +'a\\\'b'; // strings (double quoted) "a"; @@ -122,8 +124,10 @@ FALSE; 'a b'; 'a\'b'; -'a\\b'; +'a\b'; 'a\\'; +'a\\\\b'; +'a\\\'b'; // strings (double quoted) "a"; "a\nb"; @@ -155,4 +159,4 @@ b'; `foo`; `foo{$a}`; `foo{$a}bar`; -`\`\\'\\"`; \ No newline at end of file +`\`\\'\\"`;