| [ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Escaping formatting functions. 5 * Note: tests about escaping and sanitizing URLs are in URLTest.php 6 */ 7 #[\PHPUnit\Framework\Attributes\Group('formatting')] 8 class EscTest extends PHPUnit\Framework\TestCase { 9 10 /** 11 * Attributes and how they should be escaped 12 */ 13 static function html_attributes(): \Iterator 14 { 15 yield array( 16 '"double quotes"', 17 '"double quotes"', 18 ); 19 yield array( 20 "'single quotes'", 21 ''single quotes'', 22 ); 23 yield array( 24 "'mixed' " . '"quotes"', 25 ''mixed' "quotes"', 26 ); 27 yield array( 28 'foo & bar &baz; '', 29 'foo & bar &baz; '', 30 ); 31 } 32 33 34 /** 35 * Attribute escaping 36 */ 37 #[\PHPUnit\Framework\Attributes\DataProvider('html_attributes')] 38 function test_esc_attr( $attr, $escaped ) { 39 $this->assertSame( $escaped, yourls_esc_attr( $attr ) ); 40 } 41 42 /** 43 * Attribute escaping -- escaping twice shouldn't change 44 */ 45 #[\PHPUnit\Framework\Attributes\DataProvider('html_attributes')] 46 function test_esc_attr_twice( $attr, $escaped ) { 47 $this->assertSame( $escaped, yourls_esc_attr( yourls_esc_attr( $attr ) ) ); 48 } 49 50 /** 51 * HTML string and how they should be escaped 52 */ 53 static function html_strings(): \Iterator 54 { 55 // Simple string 56 yield array( 57 'The quick brown fox.', 58 'The quick brown fox.', 59 ); 60 // URL with & 61 yield array( 62 'https://127.0.0.1/admin/admin-ajax.php?id=y1120844669&action=edit&keyword=1a&nonce=bf3115ac3a', 63 'https://127.0.0.1/admin/admin-ajax.php?id=y1120844669&action=edit&keyword=1a&nonce=bf3115ac3a', 64 ); 65 // More ampersands 66 yield array( 67 'H&M and Dungeons & Dragons', 68 'H&M and Dungeons & Dragons', 69 ); 70 // Simple quotes 71 yield array( 72 "SELECT stuff FROM table WHERE blah IN ('omg', 'wtf') AND foo = 1", 73 'SELECT stuff FROM table WHERE blah IN ('omg', 'wtf') AND foo = 1', 74 ); 75 // Double quotes 76 yield array( 77 'I am "special"', 78 'I am "special"', 79 ); 80 // Greater and less than 81 yield array( 82 'this > that < that <randomhtml />', 83 'this > that < that <randomhtml />', 84 ); 85 // Ignore actual entities 86 yield array( 87 '& £ " &', 88 '& £ " &', 89 ); 90 // Empty string 91 yield array( 92 '', 93 '', 94 ); 95 } 96 97 /** 98 * HTML escaping 99 */ 100 #[\PHPUnit\Framework\Attributes\DataProvider('html_strings')] 101 function test_esc_html( $html, $escaped ) { 102 $this->assertSame( $escaped, yourls_esc_html( $html ) ); 103 // Double escaping shouldn't change 104 $this->assertSame( $escaped, yourls_esc_html( yourls_esc_html( $html ) ) ); 105 } 106 107 /** 108 * List of URLs and how they should be escaped 109 */ 110 static function list_of_URLs(): \Iterator 111 { 112 yield array( 113 'http://example.com/?this=that&that=this', 114 'http://example.com/?this=that&that=this', 115 ); 116 yield array( 117 'http://example.com/?this=that&that="this"', 118 'http://example.com/?this=that&that=this', 119 ); 120 yield array( 121 "http://example.com/?this=that&that='this'", 122 'http://example.com/?this=that&that='this'', 123 ); 124 yield array( 125 "http://example.com/?this=that&that=<this>", 126 'http://example.com/?this=that&that=this', 127 ); 128 } 129 130 /** 131 * Escape URLs for display 132 */ 133 #[\PHPUnit\Framework\Attributes\DataProvider('list_of_URLs')] 134 #[\PHPUnit\Framework\Attributes\Group('url')] 135 function test_esc_urls( $url, $escaped ) { 136 $this->assertEquals( $escaped, yourls_esc_url( $url ) ); 137 } 138 139 /** 140 * Some strings and how they should be escaped in javascript 141 */ 142 static function list_of_JS(): \Iterator 143 { 144 yield array( 145 'hello world();', 146 'hello world();', 147 ); 148 yield array( 149 'hello("world");', 150 'hello("world");', 151 ); 152 yield array( 153 'foo & bar &baz; '', 154 'foo & bar &baz; '', 155 ); 156 } 157 158 /** 159 * Escape JS 160 */ 161 #[\PHPUnit\Framework\Attributes\DataProvider('list_of_JS')] 162 function test_esc_js( $js, $escaped ) { 163 $this->assertEquals( $escaped, yourls_esc_js( $js ) ); 164 } 165 166 /** 167 * Strings in a textarea and how they should be escaped 168 */ 169 static function list_of_textarea(): \Iterator 170 { 171 yield array( 172 'hello<br/>world', 173 'hello<br/>world', 174 ); 175 yield array( 176 '"omg"', 177 '"omg"', 178 ); 179 yield array( 180 "'omg'", 181 ''omg'', 182 ); 183 } 184 185 /** 186 * Escape JS 187 */ 188 #[\PHPUnit\Framework\Attributes\DataProvider('list_of_textarea')] 189 function test_esc_textarea( $text, $escaped ) { 190 $this->assertEquals( $escaped, yourls_esc_textarea( $text ) ); 191 } 192 193 /** 194 * Strings, whitelist of allowed tags/attributes, and expected escaped output 195 */ 196 static function list_of_whitelisted_html(): \Iterator 197 { 198 // yield array( 'string to escape', 'allowed tags/attributes', 'expected escaped output' ); 199 200 yield 'empty whitelist escapes everything' => array( 201 '<b>only</b>', 202 array(), 203 '<b>only</b>', 204 ); 205 // Allowed tag is un-escaped, the rest stays escaped 206 yield 'allowed tag, disallowed tag' => array( 207 '<b>bold</b> <i>x</i>', 208 array( 'b' => array() ), 209 '<b>bold</b> <i>x</i>', 210 ); 211 // Text content of an allowed tag is still escaped 212 yield 'text content stays escaped' => array( 213 '<b>x & y < z</b>', 214 array( 'b' => array() ), 215 '<b>x & y < z</b>', 216 ); 217 // Tag matching is case-insensitive and output is lowercased 218 yield 'tag name is case-insensitive' => array( 219 '<B>x</B>', 220 array( 'b' => array() ), 221 '<b>x</b>', 222 ); 223 // An allowed tag with an empty attribute list keeps the tag but strips attributes 224 yield 'attributes stripped when none allowed' => array( 225 '<b class="foo">x</b>', 226 array( 'b' => array() ), 227 '<b>x</b>', 228 ); 229 // An allowed attribute is kept... 230 yield 'allowed attribute kept' => array( 231 '<a href="http://example.com">link</a>', 232 array( 'a' => array( 'href' => true ) ), 233 '<a href="http://example.com">link</a>', 234 ); 235 // ...while non-whitelisted attributes on the same tag are dropped 236 yield 'disallowed attribute dropped' => array( 237 '<a href="http://example.com" onclick="evil()">x</a>', 238 array( 'a' => array( 'href' => true ) ), 239 '<a href="http://example.com">x</a>', 240 ); 241 // Single-quoted attribute values are normalized to double quotes 242 yield 'single quotes normalized to double quotes' => array( 243 "<a href='http://example.com'>x</a>", 244 array( 'a' => array( 'href' => true ) ), 245 '<a href="http://example.com">x</a>', 246 ); 247 // The allowed tag/attribute map itself is case-insensitive 248 yield 'whitelist keys are case-insensitive' => array( 249 '<A HREF="http://example.com">x</A>', 250 array( 'A' => array( 'HREF' => true ) ), 251 '<a href="http://example.com">x</a>', 252 ); 253 // href values are sanitized: a javascript: scheme is neutralized to an empty URL 254 yield 'javascript scheme in href is neutralized' => array( 255 '<a href="javascript:alert(1)">x</a>', 256 array( 'a' => array( 'href' => true ) ), 257 '<a href="">x</a>', 258 ); 259 } 260 261 /** 262 * Escape HTML but allow a whitelist of tags and attributes 263 */ 264 #[\PHPUnit\Framework\Attributes\DataProvider('list_of_whitelisted_html')] 265 function test_esc_html_with_whitelist( $string, $allowed, $escaped ) { 266 $this->assertSame( $escaped, yourls_esc_html_with_whitelist( $string, $allowed ) ); 267 } 268 269 /** 270 * With no whitelist argument, yourls_esc_html_with_whitelist() is equivalent to yourls_esc_html() 271 */ 272 #[\PHPUnit\Framework\Attributes\DataProvider('html_strings')] 273 function test_esc_html_with_whitelist_defaults_to_esc_html( $html, $escaped ) { 274 $this->assertSame( yourls_esc_html( $html ), yourls_esc_html_with_whitelist( $html ) ); 275 $this->assertSame( $escaped, yourls_esc_html_with_whitelist( $html ) ); 276 } 277 278 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sat Jun 13 05:10:47 2026 | Cross-referenced by PHPXref 0.7.1 |