@@ -18,44 +18,42 @@ public function test_string_escaping( string $input, string $expected ): void {
1818 }
1919
2020 /**
21- * Data provider for individual escape mappings and basic cases.
21+ * Data provider for string escaping cases.
2222 *
2323 * @return array
2424 */
2525 public static function data_string_escaping (): array {
2626 return array (
27- // Basic behavior.
28- 'empty string ' => array ( '' , '"" ' ),
29- 'simple ASCII ' => array ( 'hello ' , '"hello" ' ),
30- 'spaces preserved ' => array ( 'hello world ' , '"hello world" ' ),
31- 'numbers pass through ' => array ( '12345 ' , '"12345" ' ),
32- 'non-ASCII passthrough ' => array ( 'café ' , '"café" ' ),
27+ // Passthrough — no escaping needed, only quoting.
28+ 'empty string ' => array ( '' , '"" ' ),
29+ 'simple ASCII ' => array ( 'Arial ' , '"Arial" ' ),
30+ 'spaces preserved ' => array ( 'Exo 2 ' , '"Exo 2" ' ),
31+ 'leading/trailing spaces ' => array ( ' Arial ' , '" Arial " ' ),
32+ 'whitespace-only ' => array ( ' ' , '" " ' ),
33+ 'numbers pass through ' => array ( '12345 ' , '"12345" ' ),
34+ 'non-ASCII passthrough ' => array ( 'café ' , '"café" ' ),
3335
34- // Backslash escaping.
35- 'single backslash ' => array ( '\\' , '"\5C " ' ),
36- 'double backslash ' => array ( '\\\\' , '"\5C \5C " ' ),
36+ // Backslash escaping — must happen first to prevent double-escaping.
37+ 'backslash ' => array ( 'Back \\Slash ' , '"Back\5C Slash" ' ),
38+ 'double backslash ' => array ( '\\\\' , '"\5C \5C " ' ),
39+ 'backslash before quote ' => array ( "a \\'b " , '"a\5C \27 b" ' ),
3740
38- // NULL byte.
39- 'null byte ' => array ( "\0 " , "\"\u{FFFD}\"" ),
41+ // NULL byte → U+FFFD replacement character .
42+ 'null byte ' => array ( "a \0 b " , "\"a \u{FFFD}b \"" ),
4043
41- // Newline variants.
42- 'LF ' => array ( "\n " , '"\A " ' ),
43- 'CR ' => array ( "\r " , '"\A " ' ),
44- 'CRLF ' => array ( "\r\n " , '"\A " ' ),
45- 'form feed ' => array ( "\f " , '"\A " ' ),
44+ // Newline normalization — all variants become \A escape .
45+ 'LF ' => array ( "a \n b " , '"a \A b " ' ),
46+ 'CR ' => array ( "a \r b " , '"a \A b " ' ),
47+ 'CRLF as single escape ' => array ( "a \r\n b " , '"a \A b " ' ),
48+ 'form feed ' => array ( "a \f b " , '"a \A b " ' ),
4649
4750 // HTML-problematic characters.
48- 'less than ' => array ( '< ' , '"\3C " ' ),
49- 'greater than ' => array ( '> ' , '"\3E " ' ),
50- 'ampersand ' => array ( '& ' , '"\26 " ' ),
51+ 'HTML characters < > & ' => array ( 'a<b>c&d ' , '"a\3C b\3E c\26 d" ' ),
5152
5253 // CSS-problematic characters.
53- 'comma ' => array ( ', ' , '"\2C " ' ),
54- 'semicolon ' => array ( '; ' , '"\3B " ' ),
55- 'open brace ' => array ( '{ ' , '"\7B " ' ),
56- 'close brace ' => array ( '} ' , '"\7D " ' ),
57- 'double quote ' => array ( '" ' , '"\22 " ' ),
58- 'single quote ' => array ( "' " , '"\27 " ' ),
54+ 'CSS syntax , ; { } ' => array ( 'a,b;c{d} ' , '"a\2C b\3B c\7B d\7D " ' ),
55+ 'single quote ' => array ( "CSS's strings " , '"CSS\27 s strings" ' ),
56+ 'double quote ' => array ( 'Say "Hi" ' , '"Say \22 Hi\22 " ' ),
5957 );
6058 }
6159
0 commit comments