diff --git a/bbcode-filter.inc b/bbcode-filter.inc index 52ed76943ebacda5571be4c9c7aabb050843535d..a97f2ae0e39fa20484c0111acc7fb7eb1f51d9eb 100644 --- a/bbcode-filter.inc +++ b/bbcode-filter.inc @@ -1,5 +1,4 @@ ' . $parts[$i] . '

'; } } $body = implode("\n\n", $parts); } + } - // Reinsert preformatted code blocks - foreach ($pre as $i => $code_tag) { - $body = str_replace("***pRe_sTrInG$i***", $code_tag, $body); - } + // Reinsert preformatted code blocks + foreach ($pre as $i => $code_tag) { + $body = str_replace("***pRe_sTrInG$i***", $code_tag, $body); } + // Implement [notag] + $body = preg_replace_callback('#\[notag(?::\w+)?\](.*?)\[/notag(?::\w+)?\]#si', + function ($matches) { return _bbcode_notag_tag($matches[1]); }, $body); + // Add closing tags to prevent users from disruping your site's HTML // (required for nestable tags only: [list] and [quote]) preg_match_all('/\[quote/i', $body, $matches); @@ -86,8 +89,8 @@ function _bbcode_filter_process(&$body, $settings) { if (stristr($body, '[size=') !== FALSE) { // prevent useless processing $arr = array( 'tag' => 'size', - 'pattern' => '#\[\x07=([\d]+)(?::\w+)?\]([^\x07]*)\[/\x07(?::\w+)?\]#esi', - 'replacement' => '"". str_replace(\'\"\', \'"\', \'$2\') .""', + 'pattern' => '#\[\x07=([\w-]+)(?::\w+)?\]([^\x07]*)\[/\x07(?::\w+)?\]#si', + 'call' => function ($matches) { return ''. str_replace('\"', '"', $matches[2]) .''; }, 'text' => $body, ); $body = _bbcode_replace_nest_tag($arr); @@ -104,6 +107,17 @@ function _bbcode_filter_process(&$body, $settings) { $body = _bbcode_replace_nest_tag($arr); } // end processing for [color] + // begin processing for [highlight] + if (stristr($body, '[highlight=') !== FALSE) { // prevent useless processing + $arr = array( + 'tag' => 'highlight', + 'pattern' => '#\[\x07=([\#\w]+)(?::\w+)?\]([^\x07]*)\[/\x07(?::\w+)?\]#si', + 'replacement' => '$2', + 'text' => $body, + ); + $body = _bbcode_replace_nest_tag($arr); + } // end processing for [highlight] + // begin processing for [font] if (stristr($body, '[font=') !== FALSE) { // prevent useless processing $arr = array( @@ -169,35 +183,36 @@ function _bbcode_filter_process(&$body, $settings) { // replace to
    /
/ tags // It will be better to use &count and do-while, if php 5 or higher. while (preg_match("#\[\x07[=]*((?-i)[cds1aAiI])*(?::\w+)?\]([^\x07]*)\[/\x07(?::\w+)?\]#si", $body)) { - $body = preg_replace("#\[\x07[=]*((?-i)[cds1aAiI])*(?::\w+)?\]([^\x07]*)\[/\x07(?::\w+)?\]#esi", '"<". $l_type[\'$1\']["tag"] ." class=\"bb-list\" style=\"list-style-type:". $l_type[\'$1\']["style"] .";\">". str_replace(\'\"\', \'"\', \'$2\') .""', $body); + $body = preg_replace_callback("#\[\x07[=]*((?-i)[cds1aAiI])*(?::\w+)?\]([^\x07]*)\[/\x07(?::\w+)?\]#si", + function ($matches) use($l_type) { return '<'. $l_type[$matches[1]]["tag"] .' class="bb-list" style="list-style-type:'. $l_type[$matches[1]]["style"] .';">'. str_replace('\"', '"', $matches[2]) .''; }, + $body); } // remove
tags $body = preg_replace('#(<[/]*([uo]l|li).*>.*)
#i', '$1', $body); } // end processing for [list] and [*] - // Implement [notag] - $body = preg_replace_callback('#\[notag(?::\w+)?\](.*?)\[/notag(?::\w+)?\]#si', - function ($matches) { return _bbcode_notag_tag($matches[1]); }, $body); - - // PHP code blocks (syntax highlighted) - $body = preg_replace_callback('#\[php(?::\w+)?\](?:[\r\n])*(.*?)\[/php(?::\w+)?\]#si', - function ($matches) { return _bbcode_php_tag($matches[1]); }, $body); + // PHP and HTML code blocks (syntax highlighted) + $body = preg_replace_callback('#\[(php|html)(?::\w+)?\](?:[\r\n])*(.*?)\[/(php|html)(?::\w+)?\]#si', + function ($matches) { return _bbcode_php_tag($matches[2]); }, $body); // Headings and indexes - articles will almost always need them + $body = preg_replace_callback('#\[index style=(ol|ul)\]#si', + function ($matches) { return _bbcode_generate_index($body, $matches[1]); }, $body); + $body = preg_replace_callback('#\[index\s*/?\]#si', + function ($matches) use ($body) { return _bbcode_generate_index($body); }, $body); $body = preg_replace_callback('#\[h([1-6])(?::\w+)?\](.*?)\[/h[1-6](?::\w+)?\]#si', - function ($matches) { return _bbcode_generate_heading($matches[1], $matches[2]); }, $body); - $body = preg_replace_callback('#\[index\s*/?\]#si', - function ($matches) { return _bbcode_generate_index($body); }, $body); - $body = preg_replace_callback('#\[index style=(ol|ul)\]#si', - function ($matches) { return _bbcode_generate_index($bosy, $matches[1]); }, $body); + function ($matches) { return _bbcode_generate_heading($matches[1], $matches[2]); }, $body); // Define BBCode tags $preg = array( // Font, text and alignment + '#\[p\](.*?)\[/p\]#si' => '

\\1

', '#\[align=(\w+)(?::\w+)?\](.*?)\[/align(?::\w+)?\]#si' => '\\2', '#\[float=(left|right)(?::\w+)?\](.*?)\[/float(?::\w+)?\]#si' => '\\2', '#\[justify(?::\w+)?\](.*?)\[/justify(?::\w+)?\]#si' => '
\\1
', + '#\[indent(?::\w+)?\](.*?)\[/indent(?::\w+)?\]#si' => '\\1', + '#\[tab\](\d*)\[/tab\]#si' => '', '#\[(b|strong)(?::\w+)?\](.*?)\[/(b|strong)(?::\w+)?\]#si' => '\\2', '#\[(i|em)(?::\w+)?\](.*?)\[/(i|em)(?::\w+)?\]#si' => '\\2', '#\[u(?::\w+)?\](.*?)\[/u(?::\w+)?\]#si' => '\\1', @@ -386,19 +401,29 @@ function _bbcode_php_tag($text = NULL) { } function _bbcode_size_val($size) { - if ($size < 6) - return '6px'; - elseif ($size <= 48) - return $size . 'px'; - else - return $size . '%'; + if (!is_numeric($size)) // Return values like 10px or xx-small. + return $size; + + if ($size < 6) // Normalize too small size values. + return '6px'; + elseif ($size <= 48) // Less than 49 is px, more is % values. + return $size . 'px'; + else + return $size . '%'; } function _bbcode_replace_nest_tag($arr = NULL) { $text = preg_replace('#(\[[/]*)' . $arr['tag'] . '(.*?\])#si', "$1\x07$2", $arr['text']); // It will be better to use &count and do-while, if php 5 or higher. - while (preg_match($arr['pattern'], $text)) { - $text = preg_replace($arr['pattern'], $arr['replacement'], $text); + + if (array_key_exists('call', $arr)) { + while (preg_match($arr['pattern'], $text)) { + $text = preg_replace_callback($arr['pattern'], $arr['call'], $text); + } + } else { + while (preg_match($arr['pattern'], $text)) { + $text = preg_replace($arr['pattern'], $arr['replacement'], $text); + } } return $text; } diff --git a/bbcode-test.css b/bbcode-test.css index 747629d46a468108469de815b39102079604dd5f..871d1d8ede9703be0a1f73d64f5d92cc67be1c1e 100644 --- a/bbcode-test.css +++ b/bbcode-test.css @@ -4,12 +4,11 @@ * need to copy the required properties to your site's CSS file. */ -.bb-code { +.bb-code, .bb-code-block { width: 100%; border: 1px solid #bfd0d9; - border-left: 4px solid #bfd0d9; 666699; + border-left: 4px solid #bfd0d9; } -.bb-code-block {} .bb-list {} .bb-url {} .bb-email {} @@ -18,6 +17,7 @@ width: expression(this.width > 500 ? "500px" : this.width); } .bb-quote {} +.bb-quote-body {} .bb-table { border: 1px solid #660000; } diff --git a/bbcode-test.txt b/bbcode-test.txt index a56a2a700041583a18cbecae0b8c33add78f1dd8..1e319515054b63e94063e6d6d2b2a63c17bea2ba 100644 --- a/bbcode-test.txt +++ b/bbcode-test.txt @@ -4,6 +4,7 @@ This document uses (almost) all BBCode tags supported by Drupal's BBCode module. [hr] [h3]Normal text formatting[/h3] + Test [b]bold[/b] / [strong]strong[/strong] text Test [i]italic[/i] / [em]emphasised[/em] text Test [u]underlined[/u] text @@ -11,20 +12,39 @@ Test [s]strikeout[/s] text Test subscript text - H[sub]2[/sub]O Test superscript text - X[sup]3[/sup] -[h3]Font colors[/h3] +[h3]Font colours[/h3] + Test [color=blue]blue[/color] text Test [color=red]red[/color] text Test [color=green]green[/color] text Test [color=#eeff00]#eeff00[/color] text +Some [highlight=yellow]highlighted[/highlight] [highlight=green]text[/highlight] [h3]Font sizes[/h3] + +It [size=14]g[/size][size=18]r[/size][size=22]o[/size][size=26]o[/size][size=30]w[/size][size=34]s[/size][size=36]![/size] + +[i]Sizes smaller than 50 are treated as px:[/i] Test [size=1]1px[/size] - too small, normalized to 6px Test [size=12]12px[/size] text Test [size=24]24px[/size] text -Test [size=100]100px[/size] - too big, normalized to 48px -[size=10] $_SERVER[PHP_SELF] "quoted" \\e\s\c\aped\" [/size] - watch out for eval +Test [size=48]24px[/size] text + +[i]Sizes 50 and bigger are treated as percentages:[/i] +Test [size=50]50[/size] - 50% +Test [size=100]100[/size] - 100% +Test [size=150]150[/size] - 150% + +[i]With CSS attributes:[/i] +Test [size=xx-small]xx-small[/size] - xx-small +Test [size=x-small]x-small[/size] - x-small +Test [size=small]small[/size] - small +Test [size=large]large[/size] - large +Test [size=x-large]x-large[/size] - x-large +Test [size=xx-large]xx-large[/size] - xx-large [h3]Font faces[/h3] + Test [font=arial]Arial typeface[/font] text Test [font=Arial Black]Arial typeface[/font] text Test [font=Courier]Courier typeface[/font] text @@ -35,10 +55,14 @@ Test [font=Times New Roman]Times New Roman typeface[/font] text Test [font=verdana]Verdana typeface[/font] text [h3]Text alignment[/h3] + [left]Left hand side of the screen[/left] [right]Right hand side of the screen[/right] -[center]Centered[/center] +[center]Centred text[/center] [justify]This paragraph is justified on both sided on the page. By default most browsers render text with a jagged right edge. If you want all text rendered like in a book with an even right edge - use the justify tag.[/justify] +[indent]Indented text[/indent] +[tab]20[/tab]Tabbed 20px +[tab]30[/tab]Tabbed 30px [h3]Images[/h3] @@ -55,6 +79,7 @@ Re-sized image: [img=100x50]http://upload.wikimedia.org/wikipedia/commons/7/7c/Drupal.ru-Logo.png[/img] [h3]URL's[/h3] + www.test-url.com ftp.test-url.com http://test-url.com/~user/,part,of,url @@ -72,18 +97,21 @@ Wikipedia link: [wikipedia]BBCode[/wikipedia] Youtube video: [youtube]0Q2aPi9ZEgs[/youtube] [h3]E-mail addresses[/h3] + Test@Mail.com drupal.user@server1.drupal.org [email]joe@example.com[/email] [email=joe@smith.co.za]Joe Smith[/email] [h3]Headings[/h3] + [h1]Level 1 Heading[/h1] [h2]Level 2 Heading[/h2] [h3]Level 3 Heading[/h3] [h4]Level 4 Heading[/h4] [h3]Acronyms and abbreviations[/h3] + Abbreviations: [abbr=Application Programming Interface]API[/abbr] [abbr=Content Management System]CMS[/abbr] @@ -98,12 +126,12 @@ Acronyms: [h3]Code blocks[/h3] Normal code block: -[code]x := y + z; -y := a - b;[/code] +[code] x := y + z; + y := a - b;[/code] An [code]inline code[/code] block -Color highlighted PHP code block: +Colour highlighted PHP code block: [php] alert(document.cookie); will be encoded. Some other exploits: @@ -287,6 +318,7 @@ Some other exploits: http://host.com/?act=SR&f='> [h3]Broken tags[/h3] + We need to ensure that bad formatting will not disrupt your site's HTML. Broken [b]bold text... @@ -295,4 +327,3 @@ Broken [b]bold text... [*]A broken list... [quote]A broken quote... -