3 * Old & buggy PCRE-based message parser
5 * @author Ant P. <xmpp:ant@specialops.ath.cx>
7 * @license http://specialops.ath.cx/repos/so2/trunk/COPYING
9 require_once 'lib/iface.Message3.php';
11 class Message_PCRE
implements Message3
13 const CHARSET
= 'UTF-8'; // Don't change unless you know what you're doing
14 const URL_DISPLAY_LENGTH
= 80;
17 private $output = null;
19 public static $allowed_html = array(
20 /* These are the order the HTML 5 spec defines them.
21 Yes I know HTML 5 is still a draft. Stop fucking whining. */
25 'ol', 'ul', 'li', 'dl', 'dt', 'dd',
26 'em', 'strong', 'small', 'abbr', 'dfn', 'code', 'var', 'samp', 'kbd', 'sup', 'sub', 'q', 'cite',
30 function __construct($input, $formatting = null)
32 // &-Encode everything by default
33 $temp = htmlspecialchars($input);
35 // Not allowed full HTML
36 foreach ( self
::$allowed_html as $tag ) {
37 $preg1[] = '#<('.$tag.')>(.+)</('.$tag.')>#Usie';
39 $temp = preg_replace($preg1, "'<'.strtolower('$1').'>$2</'.strtolower('$3').'>'", $temp);
42 $temp = preg_replace('#(?<!")(http|ftp|irc)://(([0-9a-zA-Z\-_.+?/%=;,~:]|&)+(\#[a-zA-Z][0-9a-zA-Z_]*)?)#ie',
43 "Message_PCRE::makeurl('$1://$2')", $temp);
45 // Add <br/>s if the no-autobr option isn't given
46 if ( ! ($formatting & self
::HTML_RAW
) ) {
49 // Trim <br/>s after block elements and other places they shouldn't be
50 $temp = preg_replace('#<(/?(table|tr|[uod]l)|/(t[dh]|d[dt]|li|p|h[1-6]))>(\s*<br />)+#si',
52 // Trim <br/>s within <pre>
53 $temp = preg_replace('#<pre>(.*)</pre>#Usie',
54 "'<pre>'.str_replace('<br />', '', '$1').'</pre>'", $temp);
57 if ( strpos($this->output
, '<script') !== false ) {
58 throw new Exception('No scripts allowed.');
61 $this->output
= str_replace("\r\n", "\n", $temp);
64 private static function makeurl($uri)
66 $uri = html_entity_decode($uri);
68 return '<a href="'.htmlspecialchars($uri).'" rel="external nofollow">'.( strlen($uri) > self
::URL_DISPLAY_LENGTH ?
69 htmlspecialchars(substr($uri, 0, self
::URL_DISPLAY_LENGTH
)).'...' : htmlspecialchars($uri) ).'</a>';
74 // Check for malformed XML, doesn't really do much else
75 $parser = xml_parser_create(self
::CHARSET
);
77 if ( !xml_parse($parser, '<div>'.$this->output
.'</div>', true) ) {
78 throw new InvalidInputException(xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser));