Path: blob/master/src/infrastructure/markup/__tests__/PhutilMarkupTestCase.php
12241 views
<?php12final class PhutilMarkupTestCase extends PhutilTestCase {34public function testTagDefaults() {5$this->assertEqual(6(string)phutil_tag('br'),7(string)phutil_tag('br', array()));89$this->assertEqual(10(string)phutil_tag('br', array()),11(string)phutil_tag('br', array(), null));12}1314public function testTagEmpty() {15$this->assertEqual(16'<br />',17(string)phutil_tag('br', array(), null));1819$this->assertEqual(20'<div></div>',21(string)phutil_tag('div', array(), null));2223$this->assertEqual(24'<div></div>',25(string)phutil_tag('div', array(), ''));26}2728public function testTagBasics() {29$this->assertEqual(30'<br />',31(string)phutil_tag('br'));3233$this->assertEqual(34'<div>y</div>',35(string)phutil_tag('div', array(), 'y'));36}3738public function testTagAttributes() {39$this->assertEqual(40'<div u="v">y</div>',41(string)phutil_tag('div', array('u' => 'v'), 'y'));4243$this->assertEqual(44'<br u="v" />',45(string)phutil_tag('br', array('u' => 'v')));46}4748public function testTagEscapes() {49$this->assertEqual(50'<br u="<" />',51(string)phutil_tag('br', array('u' => '<')));5253$this->assertEqual(54'<div><br /></div>',55(string)phutil_tag('div', array(), phutil_tag('br')));56}5758public function testTagNullAttribute() {59$this->assertEqual(60'<br />',61(string)phutil_tag('br', array('y' => null)));62}6364public function testTagJavascriptProtocolRejection() {65$hrefs = array(66'javascript:alert(1)' => true,67'JAVASCRIPT:alert(2)' => true,6869// NOTE: When interpreted as a URI, this is dropped because of leading70// whitespace.71' javascript:alert(3)' => array(true, false),72'/' => false,73'/path/to/stuff/' => false,74'' => false,75'http://example.com/' => false,76'#' => false,77'javascript://anything' => true,7879// Chrome 33 and IE11, at a minimum, treat this as Javascript.80"javascript\n:alert(4)" => true,8182// Opera currently accepts a variety of unicode spaces. This test case83// has a smattering of them.84"\xE2\x80\x89javascript:" => true,85"javascript\xE2\x80\x89:" => true,86"\xE2\x80\x84javascript:" => true,87"javascript\xE2\x80\x84:" => true,8889// Because we're aggressive, all of unicode should trigger detection90// by default.91"\xE2\x98\x83javascript:" => true,92"javascript\xE2\x98\x83:" => true,93"\xE2\x98\x83javascript\xE2\x98\x83:" => true,9495// We're aggressive about this, so we'll intentionally raise false96// positives in these cases.97'javascript~:alert(5)' => true,98'!!!javascript!!!!:alert(6)' => true,99100// However, we should raise true negatives in these slightly more101// reasonable cases.102'javascript/:docs.html' => false,103'javascripts:x.png' => false,104'COOLjavascript:page' => false,105'/javascript:alert(1)' => false,106);107108foreach (array(true, false) as $use_uri) {109foreach ($hrefs as $href => $expect) {110if (is_array($expect)) {111$expect = ($use_uri ? $expect[1] : $expect[0]);112}113114if ($use_uri) {115$href_value = new PhutilURI($href);116} else {117$href_value = $href;118}119120$caught = null;121try {122phutil_tag('a', array('href' => $href_value), 'click for candy');123} catch (Exception $ex) {124$caught = $ex;125}126127$desc = pht(128'Unexpected result for "%s". <uri = %s, expect exception = %s>',129$href,130$use_uri ? pht('Yes') : pht('No'),131$expect ? pht('Yes') : pht('No'));132133$this->assertEqual(134$expect,135$caught instanceof Exception,136$desc);137}138}139}140141public function testURIEscape() {142$this->assertEqual(143'%2B/%20%3F%23%26%3A%21xyz%25',144phutil_escape_uri('+/ ?#&:!xyz%'));145}146147public function testURIPathComponentEscape() {148$this->assertEqual(149'a%252Fb',150phutil_escape_uri_path_component('a/b'));151152$str = '';153for ($ii = 0; $ii <= 255; $ii++) {154$str .= chr($ii);155}156157$this->assertEqual(158$str,159phutil_unescape_uri_path_component(160rawurldecode( // Simulates webserver.161phutil_escape_uri_path_component($str))));162}163164public function testHsprintf() {165$this->assertEqual(166'<div><3</div>',167(string)hsprintf('<div>%s</div>', '<3'));168}169170public function testAppendHTML() {171$html = phutil_tag('hr');172$html->appendHTML(phutil_tag('br'), '<evil>');173$this->assertEqual('<hr /><br /><evil>', $html->getHTMLContent());174}175176public function testArrayEscaping() {177$this->assertEqual(178'<div><div></div>',179phutil_escape_html(180array(181hsprintf('<div>'),182array(183array(184'<',185array(186'd',187array(188array(189hsprintf('i'),190),191'v',192),193),194array(195array(196'>',197),198),199),200),201hsprintf('</div>'),202)));203204$this->assertEqual(205'<div><br /><hr /><wbr /></div>',206phutil_tag(207'div',208array(),209array(210array(211array(212phutil_tag('br'),213array(214phutil_tag('hr'),215),216phutil_tag('wbr'),217),218),219))->getHTMLContent());220}221222}223224225