Skip to content

Instantly share code, notes, and snippets.

@carbonphyber
Last active March 31, 2021 05:35
Show Gist options
  • Save carbonphyber/5094431 to your computer and use it in GitHub Desktop.
Save carbonphyber/5094431 to your computer and use it in GitHub Desktop.
Unit tests for new BBCode Parser
<?php
/**
* Unit Tests for BBCode parser
* Uses OWASP cheatsheet to prevent XSS
* @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
*
* @author CarbonPhyber
*/
require dirname(dirname(dirname(__FILE__))) . '/private/common.php';
/**
* Optional CLI parameter to limit the tests to a group
*/
if($argc > 1) {
$group = ctype_digit((string) $argv[1]) ? intval($argv[1]) : 0;
} else {
$group = 'all';
}
$test_count = 0;
$success_count = 0;
$average_time = 0;
/**
* Tests to run
*/
$tests = array(
array('group' => 0, 'input' => '1', 'expected' => '1'),
array('group' => 0, 'input' => "a
b", 'expected' => "a<br />b"),
// unclosed tags
array('group' => 4, 'input' => '[qq]', 'expected' => '[qq]'),
array('group' => 0, 'input' => '[b]', 'expected' => '<strong class="bbcode-tag-b"></strong>'),
array('group' => 4, 'input' => '[/b]', 'expected' => '[/b]'),
array('group' => 0, 'input' => '[i]', 'expected' => '<em class="bbcode-tag-i"></em>'),
array('group' => 0, 'input' => '[u]', 'expected' => '<span class="bbcode-tag-u"></span>'),
array('group' => 0, 'input' => '[s]', 'expected' => '<del class="bbcode-tag-strike"></del>'),
array('group' => 0, 'input' => '[strike]', 'expected' => '<del class="bbcode-tag-strike"></del>'),
array('group' => 0, 'input' => '[color]', 'expected' => '[color]'),
array('group' => 0, 'input' => '[hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:#ff0;"></span>'),
array('group' => 0, 'input' => '[size]', 'expected' => '[size]'),
array('group' => 0, 'input' => '[quote]', 'expected' => '<div class="bbcode-tag-quote"><div class="bbcode-tag-quotecite">Quote:</div><div class="bbcode-tag-quotequoted"></div></div>'),
array('group' => 0, 'input' => '[code]', 'expected' => '<pre class="bbcode-tag-code"><code></code></pre>'),
array('group' => 0, 'input' => '[codein]', 'expected' => '<code class="bbcode-tag-codein"></code>'),
array('group' => 0, 'input' => '[left]', 'expected' => '<div class="bbcode-tag-left"></div>'),
array('group' => 0, 'input' => '[center]', 'expected' => '<div class="bbcode-tag-center"></div>'),
array('group' => 0, 'input' => '[right]', 'expected' => '<div class="bbcode-tag-right"></div>'),
array('group' => 0, 'input' => '[justify]', 'expected' => '<div class="bbcode-tag-justify"></div>'),
array('group' => 0, 'input' => '[indent]', 'expected' => '<div class="bbcode-tag-indentleft"></div>'),
array('group' => 0, 'input' => '[*]', 'expected' => '[*]'),
array('group' => 0, 'input' => '[list]', 'expected' => '<ul class="bbcode-tag-list"></ul>'),
array('group' => 0, 'input' => '[spoiler]', 'expected' => '<div class="bbcode-tag-spoiler-wrapper bbcode-tag-spoiler-hidden"><div class="spoiler-title"><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-show cta-button-sm gray-button"><span>Show Spoiler</span></button><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-hide cta-button-sm gray-button"><span>Hide Spoiler</span></button></div><div class="bbcode-tag-spoiler"></div></div>'),
array('group' => 0, 'input' => '[url]', 'expected' => '<a class="bbcode-tag-url"></a>'),
array('group' => 0, 'input' => '[img]', 'expected' => '<img class="bbcode-tag-img" />'),
array('group' => 0, 'input' => '[imgleft]', 'expected' => '<img class="bbcode-tag-img bbcode-tag-img-left" />'),
array('group' => 0, 'input' => '[imgright]', 'expected' => '<img class="bbcode-tag-img bbcode-tag-img-right" />'),
// well-closed and empty tags
array('group' => 4, 'input' => '[qq][/qq]', 'expected' => '[qq][/qq]'),
array('group' => 1, 'input' => '[b][/b]', 'expected' => '<strong class="bbcode-tag-b"></strong>'),
array('group' => 1, 'input' => '[i][/i]', 'expected' => '<em class="bbcode-tag-i"></em>'),
array('group' => 1, 'input' => '[u][/u]', 'expected' => '<span class="bbcode-tag-u"></span>'),
array('group' => 1, 'input' => '[s][/s]', 'expected' => '<del class="bbcode-tag-strike"></del>'),
array('group' => 1, 'input' => '[strike][/strike]', 'expected' => '<del class="bbcode-tag-strike"></del>'),
array('group' => 1, 'input' => '[color][/color]', 'expected' => '[color][/color]'),
array('group' => 1, 'input' => '[hilite][/hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:#ff0;"></span>'),
array('group' => 1, 'input' => '[size][/size]', 'expected' => '[size][/size]'),
array('group' => 1, 'input' => '[quote][/quote]', 'expected' => '<div class="bbcode-tag-quote"><div class="bbcode-tag-quotecite">Quote:</div><div class="bbcode-tag-quotequoted"></div></div>'),
array('group' => 1, 'input' => '[code][/code]', 'expected' => '<pre class="bbcode-tag-code"><code></code></pre>'),
array('group' => 1, 'input' => '[codein][/codein]', 'expected' => '<code class="bbcode-tag-codein"></code>'),
array('group' => 1, 'input' => '[left][/left]', 'expected' => '<div class="bbcode-tag-left"></div>'),
array('group' => 1, 'input' => '[center][/center]', 'expected' => '<div class="bbcode-tag-center"></div>'),
array('group' => 1, 'input' => '[right][/right]', 'expected' => '<div class="bbcode-tag-right"></div>'),
array('group' => 1, 'input' => '[justify][/justify]', 'expected' => '<div class="bbcode-tag-justify"></div>'),
array('group' => 1, 'input' => '[indent][/indent]', 'expected' => '<div class="bbcode-tag-indentleft"></div>'),
array('group' => 1, 'input' => '[*][/*]', 'expected' => '[*][/*]'),
array('group' => 1, 'input' => '[list][/list]', 'expected' => '<ul class="bbcode-tag-list"></ul>'),
array('group' => 1, 'input' => '[spoiler][/spoiler]', 'expected' => '<div class="bbcode-tag-spoiler-wrapper bbcode-tag-spoiler-hidden"><div class="spoiler-title"><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-show cta-button-sm gray-button"><span>Show Spoiler</span></button><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-hide cta-button-sm gray-button"><span>Hide Spoiler</span></button></div><div class="bbcode-tag-spoiler"></div></div>'),
array('group' => 1, 'input' => '[url][/url]', 'expected' => '<a class="bbcode-tag-url"></a>'),
array('group' => 1, 'input' => '[img][/img]', 'expected' => '<img class="bbcode-tag-img" />'),
array('group' => 1, 'input' => '[imgleft][/imgleft]', 'expected' => '<img class="bbcode-tag-img bbcode-tag-img-left" />'),
array('group' => 1, 'input' => '[imgright][/imgright]', 'expected' => '<img class="bbcode-tag-img bbcode-tag-img-right" />'),
// well-closed tags with text before, after, and inside
array('group' => 4, 'input' => 'before [qq]qq[/qq] after', 'expected' => 'before [qq]qq[/qq] after'),
array('group' => 2, 'input' => 'before [b]strong[/b] after', 'expected' => 'before <strong class="bbcode-tag-b">strong</strong> after'),
array('group' => 2, 'input' => 'before [i]italics[/i] after', 'expected' => 'before <em class="bbcode-tag-i">italics</em> after'),
array('group' => 2, 'input' => 'before [u]underline[/u] after', 'expected' => 'before <span class="bbcode-tag-u">underline</span> after'),
array('group' => 2, 'input' => 'before [s]strike[/s] after', 'expected' => 'before <del class="bbcode-tag-strike">strike</del> after'),
array('group' => 2, 'input' => 'before [strike]strike[/strike] after', 'expected' => 'before <del class="bbcode-tag-strike">strike</del> after'),
array('group' => 2, 'input' => 'before [color]color[/color] after', 'expected' => 'before [color]color[/color] after'),
array('group' => 2, 'input' => 'before [hilite]hilite[/hilite] after', 'expected' => 'before <span class="bbcode-tag-hilite" style="background-color:#ff0;">hilite</span> after'),
array('group' => 2, 'input' => 'before [size]size[/size] after', 'expected' => 'before [size]size[/size] after'),
array('group' => 2, 'input' => 'before [quote]quote[/quote] after', 'expected' => 'before <div class="bbcode-tag-quote"><div class="bbcode-tag-quotecite">Quote:</div><div class="bbcode-tag-quotequoted">quote</div></div> after'),
array('group' => 2, 'input' => 'before [code]code[/code] after', 'expected' => 'before <pre class="bbcode-tag-code"><code>code</code></pre> after'),
array('group' => 2, 'input' => 'before [codein]codein[/codein] after', 'expected' => 'before <code class="bbcode-tag-codein">codein</code> after'),
array('group' => 2, 'input' => 'before [left]left[/left] after', 'expected' => 'before <div class="bbcode-tag-left">left</div> after'),
array('group' => 2, 'input' => 'before [center]center[/center] after', 'expected' => 'before <div class="bbcode-tag-center">center</div> after'),
array('group' => 2, 'input' => 'before [right]right[/right] after', 'expected' => 'before <div class="bbcode-tag-right">right</div> after'),
array('group' => 2, 'input' => 'before [justify]justify[/justify] after', 'expected' => 'before <div class="bbcode-tag-justify">justify</div> after'),
array('group' => 2, 'input' => 'before [indent]indent[/indent] after', 'expected' => 'before <div class="bbcode-tag-indentleft">indent</div> after'),
array('group' => 2, 'input' => 'before [*]*[/*] after', 'expected' => 'before [*]*[/*] after'),
array('group' => 2, 'input' => 'before [list]list[/list] after', 'expected' => 'before <ul class="bbcode-tag-list">list</ul> after'), // should we allow a list without list-items as children?
array('group' => 2, 'input' => 'before [spoiler]spoiler[/spoiler] after', 'expected' => 'before <div class="bbcode-tag-spoiler-wrapper bbcode-tag-spoiler-hidden"><div class="spoiler-title"><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-show cta-button-sm gray-button"><span>Show Spoiler</span></button><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-hide cta-button-sm gray-button"><span>Hide Spoiler</span></button></div><div class="bbcode-tag-spoiler">spoiler</div></div> after'),
array('group' => 2, 'input' => 'before [url]url[/url] after', 'expected' => 'before [url]url[/url] after'),
array('group' => 2, 'input' => 'before [img]img[/img] after', 'expected' => 'before [img]img[/img] after'),
array('group' => 2, 'input' => 'before [imgleft]imgleft[/imgleft] after', 'expected' => 'before [imgleft]imgleft[/imgleft] after'),
array('group' => 2, 'input' => 'before [imgright]imgright[/imgright] after', 'expected' => 'before [imgright]imgright[/imgright] after'),
);
$tests = array_merge($tests, array(
array('group' => 1, 'input' => '[hilite][/hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:#ff0;"></span>'),
array('group' => 1, 'input' => '[hilite=red][/hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:red;"></span>'),
array('group' => 1, 'input' => '[hilite="blue"][/hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:blue;"></span>'),
array('group' => 1, 'input' => '[hilite=\'#fF0\'][/hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:#ff0;"></span>'),
array('group' => 1, 'input' => '[hilite=transparent][/hilite]', 'expected' => '<span class="bbcode-tag-hilite" style="background-color:transparent;"></span>'),
array('group' => 1, 'input' => '[color][/color]', 'expected' => '[color][/color]'),
array('group' => 1, 'input' => '[color=red][/color]', 'expected' => '<span class="bbcode-tag-color" style="color:red;"></span>'),
array('group' => 1, 'input' => '[color="blue"][/color]', 'expected' => '<span class="bbcode-tag-color" style="color:blue;"></span>'),
array('group' => 1, 'input' => '[color=\'#fF0\'][/color]', 'expected' => '<span class="bbcode-tag-color" style="color:#ff0;"></span>'),
array('group' => 1, 'input' => '[color=transparent][/color]', 'expected' => '<span class="bbcode-tag-color" style="color:transparent;"></span>'),
array('group' => 2, 'input' => '[size=1][/size]', 'expected' => '<span class="bbcode-tag-size" style="font-size:1px;"></span>'),
array('group' => 2, 'input' => '[size=\'2\'][/size]', 'expected' => '<span class="bbcode-tag-size" style="font-size:2px;"></span>'),
array('group' => 2, 'input' => '[size="3"][/size]', 'expected' => '<span class="bbcode-tag-size" style="font-size:3px;"></span>'),
array('group' => 2, 'input' => '[size=128][/size]', 'expected' => '<span class="bbcode-tag-size" style="font-size:128px;"></span>'),
array('group' => 2, 'input' => '[size=129][/size]', 'expected' => '[size=129][/size]'),
array('group' => 2, 'input' => '[indent=left][/indent]', 'expected' => '<div class="bbcode-tag-indentleft"></div>'),
array('group' => 2, 'input' => '[indent=\'right\'][/indent]', 'expected' => '<div class="bbcode-tag-indentright"></div>'),
array('group' => 2, 'input' => '[align=left][/align]', 'expected' => '<div class="bbcode-tag-left"></div>'),
array('group' => 2, 'input' => '[align=\'right\'][/align]', 'expected' => '<div class="bbcode-tag-right"></div>'),
array('group' => 2, 'input' => '[align="center"][/align]', 'expected' => '<div class="bbcode-tag-center"></div>'),
array('group' => 2, 'input' => '[align=justify][/align]', 'expected' => '<div class="bbcode-tag-justify"></div>'),
array('group' => 2, 'input' => '[spoiler=My-special_spoiler 123]spoiler[/spoiler]', 'expected' => '<div class="bbcode-tag-spoiler-wrapper bbcode-tag-spoiler-hidden"><div class="spoiler-title"><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-show cta-button-sm gray-button"><span>Show My-special_spoiler 123</span></button><button type="button" class="bbcode-tag-spoiler-control bbcode-tag-spoiler-control-hide cta-button-sm gray-button"><span>Hide My-special_spoiler 123</span></button></div><div class="bbcode-tag-spoiler">spoiler</div></div>'),
array('group' => 3, 'input' => '[list=1][/list]', 'expected' => '<ul style="list-style-type:decimal;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=\'01\'][/list]', 'expected' => '<ul style="list-style-type:decimal-leading-zero;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list="a"][/list]', 'expected' => '<ul style="list-style-type:lower-alpha;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=A][/list]', 'expected' => '<ul style="list-style-type:upper-alpha;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=i][/list]', 'expected' => '<ul style="list-style-type:lower-roman;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=I][/list]', 'expected' => '<ul style="list-style-type:upper-roman;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=alpha][/list]', 'expected' => '<ul style="list-style-type:lower-greek;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=α][/list]', 'expected' => '<ul style="list-style-type:lower-greek;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=א][/list]', 'expected' => '<ul style="list-style-type:hebrew;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=あ][/list]', 'expected' => '<ul style="list-style-type:hiragana;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=い][/list]', 'expected' => '<ul style="list-style-type:hiragana-iroha;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=ア][/list]', 'expected' => '<ul style="list-style-type:katakana;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=イ][/list]', 'expected' => '<ul style="list-style-type:katakana-iroha;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[list=一][/list]', 'expected' => '<ul style="list-style-type:cjk-ideographic;" class="bbcode-tag-list"></ul>'),
array('group' => 3, 'input' => '[img="http://apple.com/"][/img]', 'expected' => '<img src="http://apple.com/" class="bbcode-tag-img" />'),
array('group' => 3, 'input' => '[img]http://apple.com/[/img]', 'expected' => '<img src="http://apple.com/" class="bbcode-tag-img" />'),
array('group' => 3, 'input' => '[url="http://apple.com/"]url[/url]', 'expected' => '<a href="http://apple.com/" class="bbcode-tag-url">url</a>'),
array('group' => 3, 'input' => '[url]http://apple.com/[/url]', 'expected' => '<a href="http://apple.com/" class="bbcode-tag-url">http://apple.com/</a>'),
array('group' => 3, 'input' => '[list]list[/list]', 'expected' => '<ul class="bbcode-tag-list">list</ul>'),
array('group' => 3, 'input' => '[list][*]list[/list]', 'expected' => '<ul class="bbcode-tag-list"><li class="bbcode-tag-listitem">list</li></ul>'),
));
if(DJW\BBCode::AMAZON_ASSOCIATE_ID) {
$tests []= array('group' => 3, 'input' => '[url=http://www.amazon.com/gp/product/B00005JG32/]strong[/url]', 'expected' => '<a href="http://www.amazon.com/gp/product/B00005JG32/?tag=' . urlencode(DJW\BBCode::AMAZON_ASSOCIATE_ID) . '" class="bbcode-tag-url">strong</a>');
} else {
$tests []= array('group' => 3, 'input' => '[url=http://www.amazon.com/gp/product/B00005JG32/]strong[/url]', 'expected' => '<a href="http://www.amazon.com/gp/product/B00005JG32/" class="bbcode-tag-url">strong</a>');
}
$tests = array_merge($tests, array(
// invalid close tag
array('group' => 4, 'input' => 'strong[/b=foo]', 'expected' => 'strong[/b=foo]'),
array('group' => 4, 'input' => '[b]strong[/b=foo]', 'expected' => '<strong class="bbcode-tag-b">strong[/b=foo]</strong>'),
// invalid parameters
array('group' => 4, 'input' => '[img=aim:carbonphyber_gaia]CarbonPhyber AOL IM[/img]', 'expected' => '[img=aim:carbonphyber_gaia]CarbonPhyber AOL IM[/img]'),
array('group' => 4, 'input' => '[img]aim:carbonphyber_gaia[/img]', 'expected' => '[img]aim:carbonphyber_gaia[/img]'),
array('group' => 4, 'input' => '[url=aim:carbonphyber_gaia]CarbonPhyber AOL IM[/url]', 'expected' => '[url=aim:carbonphyber_gaia]CarbonPhyber AOL IM[/url]'),
array('group' => 4, 'input' => '[url]aim:carbonphyber_gaia[/url]', 'expected' => '[url]aim:carbonphyber_gaia[/url]'),
array('group' => 4, 'input' => '[url=http://apple. com/]url[/url]', 'expected' => '[url=http://apple. com/]url[/url]'),
array('group' => 4, 'input' => '[url]http://apple. com/[/url]', 'expected' => '[url]http://apple. com/[/url]'),
array('group' => 4, 'input' => '[hilite=][/hilite]', 'expected' => '[hilite=][/hilite]'),
array('group' => 4, 'input' => '[hilite=translucent][/hilite]', 'expected' => '[hilite=translucent][/hilite]'),
));
$tests = array_merge($tests, array(
array('group' => 5, 'input' => '[code]code[i]italics[/i]code[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>code[i]italics[/i]code</code></pre>'),
array('group' => 5, 'input' => '[codein]codein[i]italics[/i]codein[/codein]', 'expected' => '<code class="bbcode-tag-codein">codein[i]italics[/i]codein</code>'),
array('group' => 5, 'input' => '[b]strong[/b] between [i]italics[/i]', 'expected' => '<strong class="bbcode-tag-b">strong</strong> between <em class="bbcode-tag-i">italics</em>'),
array('group' => 5, 'input' => '[url=http://apple.com/]nested [b]strong[/b] between [i]italics[/i] nested[/url]', 'expected' => '<a href="http://apple.com/" class="bbcode-tag-url">nested <strong class="bbcode-tag-b">strong</strong> between <em class="bbcode-tag-i">italics</em> nested</a>'),
array('group' => 5, 'input' => '[code]code[i]italics[/i]code[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>code[i]italics[/i]code</code></pre>'),
));
$tests = array_merge($tests, array(
array('group' => 6, 'input' => '<script>alert(String.fromCharCode(88,83,83))</script>', 'expected' => '&lt;script&gt;alert(String.fromCharCode(88,83,83))&lt;/script&gt;'),
array('group' => 6, 'input' => '\x3cscript\x3ealert(String.fromCharCode(88,83,83))\x3c/script\x3e', 'expected' => '&lt;script&gt;alert(String.fromCharCode(88,83,83))&lt;/script&gt;'),
array('group' => 6, 'input' => '\u003cscript\u003ealert(String.fromCharCode(88,83,83))\u003c/script\u003e', 'expected' => '&lt;script&gt;alert(String.fromCharCode(88,83,83))&lt;/script&gt;'),
array('group' => 6, 'input' => '[img=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==][/img]', 'expected' => '[img=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==][/img]'),
array('group' => 6, 'input' => '[url=javascript:String.fromCharCode(88,83,83)]lowercase javascript: URL[/url]', 'expected' => '[url=javascript:String.fromCharCode(88,83,83)]lowercase javascript: URL[/url]'),
array('group' => 6, 'input' => '[url=jAVasCRipt:String.fromCharCode(88,83,83)]mixed case javascript: URL[/url]', 'expected' => '[url=jAVasCRipt:String.fromCharCode(88,83,83)]mixed case javascript: URL[/url]'),
array('group' => 6, 'input' => '[url= &#14; javascript:String.fromCharCode(88,83,83)]javascript: URL with prefixed characters[/url]', 'expected' => '[url= &amp;#14; javascript:String.fromCharCode(88,83,83)]javascript: URL with prefixed characters[/url]'),
array('group' => 6, 'input' => '[url=jav ascript:String.fromCharCode(88,83,83)]embedded tab javascript: URL[/url]', 'expected' => '[url=jav ascript:String.fromCharCode(88,83,83)]embedded tab javascript: URL[/url]'),
array('group' => 6, 'input' => '[url=jav&#x09;ascript:String.fromCharCode(88,83,83)]embedded encoded tab javascript: URL[/url]', 'expected' => '[url=jav&amp;#x09;ascript:String.fromCharCode(88,83,83)]embedded encoded tab javascript: URL[/url]'),
array('group' => 6, 'input' => '[url=jav&#x0A;ascript:String.fromCharCode(88,83,83)]embedded newline javascript: URL[/url]', 'expected' => '[url=jav&amp;#x0A;ascript:String.fromCharCode(88,83,83)]embedded newline javascript: URL[/url]'),
array('group' => 6, 'input' => '[url=&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;]hex data: URL[/url]', 'expected' => '[url=&amp;#x6A;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x73;&amp;#x63;&amp;#x72;&amp;#x69;&amp;#x70;&amp;#x74;&amp;#x3A;&amp;#x61;&amp;#x6C;&amp;#x65;&amp;#x72;&amp;#x74;&amp;#x28;&amp;#x27;&amp;#x58;&amp;#x53;&amp;#x53;&amp;#x27;&amp;#x29;]hex data: URL[/url]'),
array('group' => 6, 'input' => '[url=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29]hex data: URL[/url]', 'expected' => '[url=&amp;#x6A&amp;#x61&amp;#x76&amp;#x61&amp;#x73&amp;#x63&amp;#x72&amp;#x69&amp;#x70&amp;#x74&amp;#x3A&amp;#x61&amp;#x6C&amp;#x65&amp;#x72&amp;#x74&amp;#x28&amp;#x27&amp;#x58&amp;#x53&amp;#x53&amp;#x27&amp;#x29]hex data: URL[/url]'),
array('group' => 6, 'input' => '[url=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;]UTF8 entities javascript: URL[/url]', 'expected' => '[url=&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116;&amp;#58;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#39;&amp;#88;&amp;#83;&amp;#83;&amp;#39;&amp;#41;]UTF8 entities javascript: URL[/url]'),
array('group' => 6, 'input' => '[url=&#106&#97&#118&#97&#115&#99&#114&#105&#112&#116&#58&#97&#108&#101&#114&#116&#40&#39&#88&#83&#83&#39&#41]UTF8 entities javascript: URL without semicolons[/url]', 'expected' => '[url=&amp;#106&amp;#97&amp;#118&amp;#97&amp;#115&amp;#99&amp;#114&amp;#105&amp;#112&amp;#116&amp;#58&amp;#97&amp;#108&amp;#101&amp;#114&amp;#116&amp;#40&amp;#39&amp;#88&amp;#83&amp;#83&amp;#39&amp;#41]UTF8 entities javascript: URL without semicolons[/url]'),
array('group' => 6, 'input' => '[url=&#0000106;&#0000097;&#0000118;&#0000097;&#0000115;&#0000099;&#0000114;&#0000105;&#0000112;&#0000116;&#0000058;&#0000097;&#0000108;&#0000101;&#0000114;&#0000116;&#0000040;&#0000039;&#0000088;&#0000083;&#0000083;&#0000039;&#0000041;]UTF8 entities data: URL[/url]', 'expected' => '[url=&amp;#0000106;&amp;#0000097;&amp;#0000118;&amp;#0000097;&amp;#0000115;&amp;#0000099;&amp;#0000114;&amp;#0000105;&amp;#0000112;&amp;#0000116;&amp;#0000058;&amp;#0000097;&amp;#0000108;&amp;#0000101;&amp;#0000114;&amp;#0000116;&amp;#0000040;&amp;#0000039;&amp;#0000088;&amp;#0000083;&amp;#0000083;&amp;#0000039;&amp;#0000041;]UTF8 entities data: URL[/url]'),
array('group' => 6, 'input' => '[url=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041]UTF8 entities data: URL[/url]', 'expected' => '[url=&amp;#0000106&amp;#0000097&amp;#0000118&amp;#0000097&amp;#0000115&amp;#0000099&amp;#0000114&amp;#0000105&amp;#0000112&amp;#0000116&amp;#0000058&amp;#0000097&amp;#0000108&amp;#0000101&amp;#0000114&amp;#0000116&amp;#0000040&amp;#0000039&amp;#0000088&amp;#0000083&amp;#0000083&amp;#0000039&amp;#0000041]UTF8 entities data: URL[/url]'),
));
/**
* @author greyfade
*/
$tests = array_merge($tests, array(
array('group' => 7, 'input' => '[code]#include <stdio.h>
int foo() { return 6; }
int main() {
int bar = foo();
printf("%l\n", &bar);
printf("\n");
return bar==6?EXIT_SUCCESS:3;
}[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>#include &lt;stdio.h&gt;<br />int foo() { return 6; }<br />int main() {<br /> int bar = foo();<br /> printf(&quot;%l\n&quot;, &amp;bar);<br /> printf(&quot;\n&quot;);<br /> return bar==6?EXIT_SUCCESS:3;<br />}</code></pre>'),
array('group' => 7, 'input' => '[list][*][code][/list][/code][/list]', 'expected' => '<ul class="bbcode-tag-list"><li class="bbcode-tag-listitem"><pre class="bbcode-tag-code"><code>[/list]</code></pre></li></ul>'),
array('group' => 7, 'input' => '[list][*][code][list][/list][/code][/list]', 'expected' => '<ul class="bbcode-tag-list"><li class="bbcode-tag-listitem"><pre class="bbcode-tag-code"><code>[list][/list]</code></pre></li></ul>'),
array('group' => 7, 'input' => '[code][url=http://rdio.com]Rdio[/url][/code]', 'expected' => '<pre class="bbcode-tag-code"><code>[url=http://rdio.com]Rdio[/url]</code></pre>'),
array('group' => 7, 'input' => '[code]:) :( T_T[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>:) :( T_T</code></pre>'),
array('group' => 7, 'input' => 'c:\Program Files\Mozilla Firefox', 'expected' => 'c:\Program Files\Mozilla Firefox'),
array('group' => 7, 'input' => '[code]c:\Program Files\Mozilla Firefox[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>c:\Program Files\Mozilla Firefox</code></pre>'),
array('group' => 7, 'input' => '[code]%APPDIR%\Mozilla\Firefox[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>%APPDIR%\Mozilla\Firefox</code></pre>'),
array('group' => 7, 'input' => '[code]%AARDVARK%[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>%AARDVARK%</code></pre>'),
array('group' => 7, 'input' => 'DOS variable: %AARDVARK%', 'expected' => 'DOS variable: %AARDVARK%'),
array('group' => 7, 'input' => '[url]mailto:user@gmail.com[/url]', 'expected' => '[url]mailto:user@gmail.com[/url]'),
array('group' => 7, 'input' => '[url=mailto:user@gmail.com]email me[/url]', 'expected' => '[url=mailto:user@gmail.com]email me[/url]'),
array('group' => 7, 'input' => '[url]steam://friends/add/username[/url]', 'expected' => '[url]steam://friends/add/username[/url]'),
array('group' => 7, 'input' => '[url=steam://friends/add/username]add me[/url]', 'expected' => '[url=steam://friends/add/username]add me[/url]'),
array('group' => 7, 'input' => '[url]skype:username[/url]', 'expected' => '[url]skype:username[/url]'),
array('group' => 7, 'input' => '[url=skype:username]skype me[/url]', 'expected' => '[url=skype:username]skype me[/url]'),
array('group' => 7, 'input' => '[url]aim:username[/url]', 'expected' => '[url]aim:username[/url]'),
array('group' => 7, 'input' => '[url=aim:username]add me[/url]', 'expected' => '[url=aim:username]add me[/url]'),
array('group' => 7, 'input' => '[url]ftp://someserver/somefile[/url]', 'expected' => '[url]ftp://someserver/somefile[/url]'),
array('group' => 7, 'input' => '[url=ftp://someserver/somefile]ftp file[/url]', 'expected' => '[url=ftp://someserver/somefile]ftp file[/url]'),
array('group' => 7, 'input' => '[url]http://www.josscrowcroft.com/2011/code/utf-8-multibyte-characters-in-url-parameters-%E2%9C%93/[/url]', 'expected' => '<a href="http://www.josscrowcroft.com/2011/code/utf-8-multibyte-characters-in-url-parameters-%E2%9C%93/" class="bbcode-tag-url">http://www.josscrowcroft.com/2011/code/utf-8-multibyte-characters-in-url-parameters-%E2%9C%93/</a>'),
array('group' => 7, 'input' => '[url]http://www.josscrowcroft.com/2011/code/utf-8-multibyte-characters-in-url-parameters-✓/[/url]', 'expected' => '<a href="http://www.josscrowcroft.com/2011/code/utf-8-multibyte-characters-in-url-parameters-✓/" class="bbcode-tag-url">http://www.josscrowcroft.com/2011/code/utf-8-multibyte-characters-in-url-parameters-✓/</a>'),
array('group' => 7, 'input' => '[code]<!DOCTYPE html> <html lang="en-US"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>HTML test</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><script type="text/javascript">$(function(){alert("Test")})</script> </head><body></body></html>[/code]', 'expected' => '<pre class="bbcode-tag-code"><code>&lt;!DOCTYPE html&gt; &lt;html lang=&quot;en-US&quot;&gt; &lt;head&gt; &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt; &lt;title&gt;HTML test&lt;/title&gt; &lt;script src=&quot;//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt;$(function(){alert(&quot;Test&quot;)})&lt;/script&gt; &lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;</code></pre>'),
array('group' => 7, 'input' => 'Sometimes we talk about Windows (even Win8).', 'expected' => 'Sometimes we talk about Windows (even Win8).'),
array('group' => 7, 'input' => 'Sometimes we need to recommend [url=http://www.amazon.com/gp/product/0596517742/?tag=greyfadeorg-20]JavaScript: The Good Parts[/url] (©2008)', 'expected' => 'Sometimes we need to recommend <a href="http://www.amazon.com/gp/product/0596517742/?tag=greyfadeorg-20" class="bbcode-tag-url">JavaScript: The Good Parts</a> (&copy;2008)'),
array('group' => 7, 'input' => 'Sometimes we need to recommend [url=http://www.amazon.com/gp/product/0596517742/?hl=en&tag=greyfadeorg-20]JavaScript: The Good Parts[/url] (©2008)', 'expected' => 'Sometimes we need to recommend <a href="http://www.amazon.com/gp/product/0596517742/?hl=en&amp;tag=greyfadeorg-20" class="bbcode-tag-url">JavaScript: The Good Parts</a> (&copy;2008)'),
array('group' => 7, 'input' => 'C&T is demanding.™', 'expected' => 'C&amp;T is demanding.&trade;'),
array('group' => 7, 'input' => 'C&T is demanding.&trade;', 'expected' => 'C&amp;T is demanding.&amp;trade;'),
array('group' => 7, 'input' => 'C&T is demanding.&#8482;', 'expected' => 'C&amp;T is demanding.&amp;#8482;'),
));
// assemble a very long input
$log_input_parts = array();
$log_output_open_parts = array();
$log_output_close_parts = array();
for($i = 0; $i < 100; $i++) {
$log_input_parts []= '[b]:) :( T_T';
$log_output_open_parts []= '<strong class="bbcode-tag-b">:) <span class="emoticon emoticon-sad phark">sad</span> <span class="emoticon emoticon-crying phark">crying</span>';
$log_output_close_parts []= '</strong>';
}
$tests = array_merge($tests, array(
// security tests
array('group' => 8, 'input' => implode('', $log_input_parts), 'expected' => implode('', $log_output_open_parts) . implode('', $log_output_close_parts)),
));
/**
* equals
* Run a single test
*/
function equals($raw, $expected) {
global $test_count;
global $success_count;
global $average_time;
$time_before = microtime(TRUE);
$translated = DJW\GaiaCode::toHtml($raw);
$time_after = microtime(TRUE);
$average_time = (($average_time * $test_count) + ($time_after - $time_before)) / ($test_count + 1);
$test_count++;
if($is_success = ($expected === $translated)) {
$success_count++;
} else {
echo '<pre>' . print_r(array(
'input' => $raw,
'expected' => $expected,
'actual' => $translated,
$is_success ? 'SUCCESS' : 'FAILURE',
), TRUE) . '</pre>' . "\n";
}
}
/**
* Run the tests!
*/
foreach($tests as $this_test) {
if($this_test['group'] === $group || $group === 'all') {
equals($this_test['input'], $this_test['expected']);
}
}
echo "\nAverage time = {$average_time}s.\n";
echo "\nPassed ($success_count/$test_count) tests.\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment