Example #1
0
 /**
  * @param array $attr
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return array
  */
 public function transform($attr, $config, $context)
 {
     $src = true;
     if (!isset($attr['src'])) {
         if ($config->get('Core.RemoveInvalidImg')) {
             return $attr;
         }
         $attr['src'] = $config->get('Attr.DefaultInvalidImage');
         $src = false;
     }
     if (!isset($attr['alt'])) {
         if ($src) {
             $alt = $config->get('Attr.DefaultImageAlt');
             if ($alt === null) {
                 // truncate if the alt is too long
                 $attr['alt'] = substr(basename($attr['src']), 0, 40);
             } else {
                 $attr['alt'] = $alt;
             }
         } else {
             $attr['alt'] = $config->get('Attr.DefaultInvalidImageAlt');
         }
     }
     return $attr;
 }
 /**
  * Factory method that creates a cache object based on configuration
  * @param string $type Name of definitions handled by cache
  * @param HTMLPurifier_Config $config Config instance
  * @return mixed
  */
 public function create($type, $config)
 {
     $method = $config->get('Cache.DefinitionImpl');
     if ($method === null) {
         return new HTMLPurifier_DefinitionCache_Null($type);
     }
     if (!empty($this->caches[$method][$type])) {
         return $this->caches[$method][$type];
     }
     if (isset($this->implementations[$method]) && class_exists($class = $this->implementations[$method], false)) {
         $cache = new $class($type);
     } else {
         if ($method != 'Serializer') {
             trigger_error("Unrecognized DefinitionCache {$method}, using Serializer instead", E_USER_WARNING);
         }
         $cache = new HTMLPurifier_DefinitionCache_Serializer($type);
     }
     foreach ($this->decorators as $decorator) {
         $new_cache = $decorator->decorate($cache);
         // prevent infinite recursion in PHP 4
         unset($cache);
         $cache = $new_cache;
     }
     $this->caches[$method][$type] = $cache;
     return $this->caches[$method][$type];
 }
Example #3
0
 /**
  * @param string $string
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return bool|string
  */
 public function validate($string, $config, $context)
 {
     if ($this->valid_values === false) {
         $this->valid_values = $config->get('Attr.AllowedFrameTargets');
     }
     return parent::validate($string, $config, $context);
 }
 /**
  * @param HTMLPurifier_Config $config
  * @return void
  */
 public function prepare($config)
 {
     $our_host = $config->getDefinition('URI')->host;
     if ($our_host !== null) {
         $this->ourHostParts = array_reverse(explode('.', $our_host));
     }
 }
Example #5
0
 /**
  * @param HTMLPurifier_URI $uri
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return bool
  */
 public function filter(&$uri, $config, $context)
 {
     // check if filter not applicable
     if (!$config->get('HTML.SafeIframe')) {
         return true;
     }
     // check if the filter should actually trigger
     if (!$context->get('EmbeddedURI', true)) {
         return true;
     }
     $token = $context->get('CurrentToken', true);
     if (!($token && $token->name == 'iframe')) {
         return true;
     }
     // check if we actually have some whitelists enabled
     if ($this->regexp === null) {
         return false;
     }
     // actually check the whitelists
     if (!preg_match($this->regexp, $uri->toString())) {
         return false;
     }
     // Make sure that if we're an HTTPS site, the iframe is also HTTPS
     if (is_https() && $uri->scheme == 'http') {
         // Convert it to a protocol-relative URL
         $uri->scheme = null;
     }
     return $uri;
 }
Example #6
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function __construct($config)
 {
     $def = $config->getCSSDefinition();
     $this->info['border-width'] = $def->info['border-width'];
     $this->info['border-style'] = $def->info['border-style'];
     $this->info['border-top-color'] = $def->info['border-top-color'];
 }
Example #7
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function setup($config)
 {
     if ($config->get('HTML.SafeIframe')) {
         $this->safe = true;
     }
     $this->addElement('iframe', 'Inline', 'Flow', 'Common', array('src' => 'URI#embedded', 'width' => 'Length', 'height' => 'Length', 'name' => 'ID', 'scrolling' => 'Enum#yes,no,auto', 'frameborder' => 'Enum#0,1', 'longdesc' => 'URI', 'marginheight' => 'Pixels', 'marginwidth' => 'Pixels'));
 }
Example #8
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function __construct($config)
 {
     $def = $config->getCSSDefinition();
     $this->info['list-style-type'] = $def->info['list-style-type'];
     $this->info['list-style-position'] = $def->info['list-style-position'];
     $this->info['list-style-image'] = $def->info['list-style-image'];
 }
Example #9
0
 /**
  * @param string $string
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return bool|string
  */
 public function validate($string, $config, $context)
 {
     static $colors = null;
     if ($colors === null) {
         $colors = $config->get('Core.ColorKeywords');
     }
     $string = trim($string);
     if (empty($string)) {
         return false;
     }
     $lower = strtolower($string);
     if (isset($colors[$lower])) {
         return $colors[$lower];
     }
     if ($string[0] === '#') {
         $hex = substr($string, 1);
     } else {
         $hex = $string;
     }
     $length = strlen($hex);
     if ($length !== 3 && $length !== 6) {
         return false;
     }
     if (!ctype_xdigit($hex)) {
         return false;
     }
     if ($length === 3) {
         $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
     }
     return "#{$hex}";
 }
Example #10
0
 /**
  * Public interface for validating components of a URI.  Performs a
  * bunch of default actions. Don't overload this method.
  * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return bool success or failure
  */
 public function validate(&$uri, $config, $context)
 {
     if ($this->default_port == $uri->port) {
         $uri->port = null;
     }
     // kludge: browsers do funny things when the scheme but not the
     // authority is set
     if (!$this->may_omit_host && (!is_null($uri->scheme) && ($uri->host === '' || is_null($uri->host))) || is_null($uri->scheme) && $uri->host === '') {
         do {
             if (is_null($uri->scheme)) {
                 if (substr($uri->path, 0, 2) != '//') {
                     $uri->host = null;
                     break;
                 }
                 // URI is '////path', so we cannot nullify the
                 // host to preserve semantics.  Try expanding the
                 // hostname instead (fall through)
             }
             // first see if we can manually insert a hostname
             $host = $config->get('URI.Host');
             if (!is_null($host)) {
                 $uri->host = $host;
             } else {
                 // we can't do anything sensible, reject the URL.
                 return false;
             }
         } while (false);
     }
     return $this->doValidate($uri, $config, $context);
 }
Example #11
0
 /**
  * @param array $attr
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return array
  */
 public function transform($attr, $config, $context)
 {
     if (isset($attr['dir'])) {
         return $attr;
     }
     $attr['dir'] = $config->get('Attr.DefaultTextDir');
     return $attr;
 }
Example #12
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function setup($config)
 {
     // These definitions are not intrinsically safe: the attribute transforms
     // are a vital part of ensuring safety.
     $allowed = $config->get('HTML.SafeScripting');
     $script = $this->addElement('script', 'Inline', 'Empty', null, array('type' => 'Enum#application/javascript', 'src*' => new HTMLPurifier_AttrDef_Enum(array_keys($allowed))));
     $script->attr_transform_pre[] = $script->attr_transform_post[] = new HTMLPurifier_AttrTransform_ScriptRequired();
 }
Example #13
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function __construct($config)
 {
     $def = $config->getCSSDefinition();
     $this->info['background-color'] = $def->info['background-color'];
     $this->info['background-image'] = $def->info['background-image'];
     $this->info['background-repeat'] = $def->info['background-repeat'];
     $this->info['background-attachment'] = $def->info['background-attachment'];
     $this->info['background-position'] = $def->info['background-position'];
 }
Example #14
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function __construct($config)
 {
     $def = $config->getCSSDefinition();
     $this->info['font-style'] = $def->info['font-style'];
     $this->info['font-variant'] = $def->info['font-variant'];
     $this->info['font-weight'] = $def->info['font-weight'];
     $this->info['font-size'] = $def->info['font-size'];
     $this->info['line-height'] = $def->info['line-height'];
     $this->info['font-family'] = $def->info['font-family'];
 }
Example #15
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function setup($config)
 {
     $max = $config->get('HTML.MaxImgLength');
     $img = $this->addElement('img', 'Inline', 'Empty', 'Common', array('alt*' => 'Text', 'height' => 'Pixels#' . $max, 'width' => 'Pixels#' . $max, 'longdesc' => 'URI', 'src*' => new HTMLPurifier_AttrDef_URI(true)));
     if ($max === null || $config->get('HTML.Trusted')) {
         $img->attr['height'] = $img->attr['width'] = 'Length';
     }
     // kind of strange, but splitting things up would be inefficient
     $img->attr_transform_pre[] = $img->attr_transform_post[] = new HTMLPurifier_AttrTransform_ImgRequired();
 }
Example #16
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function setup($config)
 {
     // These definitions are not intrinsically safe: the attribute transforms
     // are a vital part of ensuring safety.
     $max = $config->get('HTML.MaxImgLength');
     $object = $this->addElement('object', 'Inline', 'Optional: param | Flow | #PCDATA', 'Common', array('type' => 'Enum#application/x-shockwave-flash', 'width' => 'Pixels#' . $max, 'height' => 'Pixels#' . $max, 'data' => 'URI#embedded', 'codebase' => new HTMLPurifier_AttrDef_Enum(array('http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0'))));
     $object->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeObject();
     $param = $this->addElement('param', false, 'Empty', false, array('id' => 'ID', 'name*' => 'Text', 'value' => 'Text'));
     $param->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeParam();
     $this->info_injector[] = 'SafeObject';
 }
Example #17
0
 /**
  * @param HTMLPurifier_Config $config
  */
 public function setup($config)
 {
     $elements = array('a', 'applet', 'form', 'frame', 'iframe', 'img', 'map');
     foreach ($elements as $name) {
         $element = $this->addBlankElement($name);
         $element->attr['name'] = 'CDATA';
         if (!$config->get('HTML.Attr.Name.UseCDATA')) {
             $element->attr_transform_post[] = new HTMLPurifier_AttrTransform_NameSync();
         }
     }
 }
Example #18
0
 /**
  * @return \HTMLPurifier_Config
  */
 protected function get_config()
 {
     if (is_null($this->config)) {
         $this->config = \HTMLPurifier_Config::createDefault();
         $this->config->set('HTML.Doctype', 'HTML 4.01 Transitional');
         $this->config->set('HTML.AllowedAttributes', array('a.href', 'a.target', 'img.src', '*.class'));
         $this->config->set('Attr.AllowedFrameTargets', array('_blank'));
         $this->config->set('HTML.Allowed', 'a,abbr,acronym,b,blockquote,cite,code,dd,div,dl,dt,em,i,li,ol,p,pre,s,span,strike,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,tt,u,ul');
     }
     return $this->config;
 }
Example #19
0
 /**
  * @param HTMLPurifier_Config $config
  * @return bool
  */
 public function prepare($config)
 {
     $this->target = $config->get('URI.' . $this->name);
     $this->parser = new HTMLPurifier_URIParser();
     $this->doEmbed = $config->get('URI.MungeResources');
     $this->secretKey = $config->get('URI.MungeSecretKey');
     if ($this->secretKey && !function_exists('hash_hmac')) {
         throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support.");
     }
     return true;
 }
Example #20
0
 /**
  * @param array $children
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return array
  */
 public function validateChildren($children, $config, $context)
 {
     // Flag for subclasses
     $this->whitespace = false;
     // if there are no tokens, delete parent node
     if (empty($children)) {
         return false;
     }
     // if li is not allowed, delete parent node
     if (!isset($config->getHTMLDefinition()->info['li'])) {
         trigger_error("Cannot allow ul/ol without allowing li", E_USER_WARNING);
         return false;
     }
     // the new set of children
     $result = array();
     // a little sanity check to make sure it's not ALL whitespace
     $all_whitespace = true;
     $current_li = false;
     foreach ($children as $node) {
         if (!empty($node->is_whitespace)) {
             $result[] = $node;
             continue;
         }
         $all_whitespace = false;
         // phew, we're not talking about whitespace
         if ($node->name === 'li') {
             // good
             $current_li = $node;
             $result[] = $node;
         } else {
             // we want to tuck this into the previous li
             // Invariant: we expect the node to be ol/ul
             // ToDo: Make this more robust in the case of not ol/ul
             // by distinguishing between existing li and li created
             // to handle non-list elements; non-list elements should
             // not be appended to an existing li; only li created
             // for non-list. This distinction is not currently made.
             if ($current_li === false) {
                 $current_li = new HTMLPurifier_Node_Element('li');
                 $result[] = $current_li;
             }
             $current_li->children[] = $node;
             $current_li->empty = false;
             // XXX fascinating! Check for this error elsewhere ToDo
         }
     }
     if (empty($result)) {
         return false;
     }
     if ($all_whitespace) {
         return false;
     }
     return $result;
 }
Example #21
0
 /**
  * @param array $tokens
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return array
  */
 protected function filter($tokens, $config, $context)
 {
     $allowed = $config->get('Attr.AllowedClasses');
     $forbidden = $config->get('Attr.ForbiddenClasses');
     $ret = array();
     foreach ($tokens as $token) {
         if (($allowed === null || isset($allowed[$token])) && !isset($forbidden[$token]) && !in_array($token, $ret, true)) {
             $ret[] = $token;
         }
     }
     return $ret;
 }
Example #22
0
 /**
  * @param string $uri
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return bool|string
  */
 public function validate($uri, $config, $context)
 {
     if ($config->get('URI.Disable')) {
         return false;
     }
     $uri = $this->parseCDATA($uri);
     // parse the URI
     $uri = $this->parser->parse($uri);
     if ($uri === false) {
         return false;
     }
     // add embedded flag to context for validators
     $context->register('EmbeddedURI', $this->embedsResource);
     $ok = false;
     do {
         // generic validation
         $result = $uri->validate($config, $context);
         if (!$result) {
             break;
         }
         // chained filtering
         $uri_def = $config->getDefinition('URI');
         $result = $uri_def->filter($uri, $config, $context);
         if (!$result) {
             break;
         }
         // scheme-specific validation
         $scheme_obj = $uri->getSchemeObj($config, $context);
         if (!$scheme_obj) {
             break;
         }
         if ($this->embedsResource && !$scheme_obj->browsable) {
             break;
         }
         $result = $scheme_obj->validate($uri, $config, $context);
         if (!$result) {
             break;
         }
         // Post chained filtering
         $result = $uri_def->postFilter($uri, $config, $context);
         if (!$result) {
             break;
         }
         // survived gauntlet
         $ok = true;
     } while (false);
     $context->destroy('EmbeddedURI');
     if (!$ok) {
         return false;
     }
     // back to string
     return $uri->toString();
 }
Example #23
0
 /**
  * @param array $attr
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return array
  */
 public function transform($attr, $config, $context)
 {
     $attr['allowscriptaccess'] = 'never';
     $attr['allownetworking'] = 'internal';
     $attr['type'] = 'application/x-shockwave-flash';
     // Added by Ivan Tcholakov, 24-DEC-2013.
     if (!$config->get('HTML.FlashAllowFullScreen') || !$attr['allowfullscreen'] == 'true') {
         unset($attr['allowfullscreen']);
         // if omitted, assume to be 'false'
     }
     //
     return $attr;
 }
Example #24
0
 /**
  * @param HTMLPurifier_Config $config
  * @return string
  */
 public function render($config)
 {
     $ret = '';
     $this->config =& $config;
     $this->def = $config->getHTMLDefinition();
     $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer'));
     $ret .= $this->renderDoctype();
     $ret .= $this->renderEnvironment();
     $ret .= $this->renderContentSets();
     $ret .= $this->renderInfo();
     $ret .= $this->end('div');
     return $ret;
 }
Example #25
0
 /**
  * @param array $attr
  * @param HTMLPurifier_Config $config
  * @param HTMLPurifier_Context $context
  * @return array
  */
 public function transform($attr, $config, $context)
 {
     // If we add support for other objects, we'll need to alter the
     // transforms.
     switch ($attr['name']) {
         // application/x-shockwave-flash
         // Keep this synchronized with Injector/SafeObject.php
         case 'allowScriptAccess':
             // Added by Ivan Tcholakov, 24-DEC-2013.
         // Added by Ivan Tcholakov, 24-DEC-2013.
         case 'allowscriptaccess':
             //
             $attr['value'] = 'never';
             break;
         case 'allowNetworking':
             // Added by Ivan Tcholakov, 24-DEC-2013.
         // Added by Ivan Tcholakov, 24-DEC-2013.
         case 'allownetworking':
             //
             $attr['value'] = 'internal';
             break;
         case 'allowFullScreen':
             // Added by Ivan Tcholakov, 24-DEC-2013.
         // Added by Ivan Tcholakov, 24-DEC-2013.
         case 'allowfullscreen':
             //
             if ($config->get('HTML.FlashAllowFullScreen')) {
                 $attr['value'] = $attr['value'] == 'true' ? 'true' : 'false';
             } else {
                 $attr['value'] = 'false';
             }
             break;
         case 'wmode':
             $attr['value'] = $this->wmode->validate($attr['value'], $config, $context);
             break;
         case 'movie':
         case 'src':
             $attr['name'] = "movie";
             $attr['value'] = $this->uri->validate($attr['value'], $config, $context);
             break;
         case 'flashvars':
             // we're going to allow arbitrary inputs to the SWF, on
             // the reasoning that it could only hack the SWF, not us.
             break;
             // add other cases to support other param name/value pairs
         // add other cases to support other param name/value pairs
         default:
             $attr['name'] = $attr['value'] = null;
     }
     return $attr;
 }
 public function setUp()
 {
     $config = \HTMLPurifier_Config::createDefault();
     $this->config = $this->getMockBuilder('\\HTMLPurifier_Config')->disableOriginalConstructor()->getMock();
     $this->config->expects($this->atLeastOnce())->method('set')->with('Cache.SerializerPath', '/tmp');
     $this->config->expects($this->any())->method('getHTMLDefinition')->will($this->returnValue($config->getHTMLDefinition()));
     $this->config->expects($this->any())->method('get')->will($this->returnCallback(function ($argument) {
         $config = \HTMLPurifier_Config::createDefault();
         return $config->get($argument);
     }));
     $this->config->expects($this->any())->method('getBatch')->will($this->returnCallback(function ($argument) {
         $config = \HTMLPurifier_Config::createDefault();
         return $config->getBatch($argument);
     }));
 }
Example #27
0
 /**
  * Build new instance
  * @param type $config 
  * @return
  */
 public static function setInstance($config = null)
 {
     if (is_null($config)) {
         $config = HTMLPurifier_Config::createDefault();
     }
     self::$_instance = new HTMLPurifier($config);
 }
 /**
  * clean the comment text field from html, in order to use it as submitted text
  * uses the htmlpurifier library, or a simple strip_tags call, based on the app.yml config file
  *
  * @return String
  * @param  String - the text to be cleaned
  *
  * @author Guglielmo Celata
  * @see    http://htmlpurifier.org/
  **/
 public static function clean($text)
 {
     $allowed_html_tags = sfConfig::get('app_deppPropelActAsCommentableBehaviorPlugin_allowed_tags', array());
     $use_htmlpurifier = sfConfig::get('app_deppPropelActAsCommentableBehaviorPlugin_use_htmlpurifier', false);
     if ($use_htmlpurifier) {
         $htmlpurifier_path = sfConfig::get('app_deppPropelActAsCommentableBehaviorPlugin_htmlpurifier_path', SF_ROOT_DIR . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'htmlpurifier' . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR);
         require_once $htmlpurifier_path . 'HTMLPurifier.auto.php';
         $config = HTMLPurifier_Config::createDefault();
         $config->set('HTML', 'Doctype', 'XHTML 1.0 Strict');
         $config->set('HTML', 'Allowed', implode(',', array_keys($allowed_html_tags)));
         if (isset($allowed_html_tags['a'])) {
             $config->set('HTML', 'AllowedAttributes', 'a.href');
             $config->set('AutoFormat', 'Linkify', true);
         }
         if (isset($allowed_html_tags['p'])) {
             $config->set('AutoFormat', 'AutoParagraph', true);
         }
         $purifier = new HTMLPurifier($config);
         $clean_text = $purifier->purify($text);
     } else {
         $allowed_html_tags_as_string = "";
         foreach ($allowed_html_tags as $tag) {
             $allowed_html_tags_as_string .= "{$tag}";
         }
         $clean_text = strip_tags($text, $allowed_html_tags_as_string);
     }
     return $clean_text;
 }
 function execute()
 {
     // HTMLPurifier runs with PHP5 only
     if (version_compare(PHP_VERSION, '5.0.0') < 0) {
         die('Turn postcommon_post_htmlpurify4everyone.php off because this filter cannot run with PHP4');
     }
     /*
             if ( file_exists( XOOPS_ROOT_PATH.'/class/icms.htmlpurifier.php' ) ) {
     // use HTMLPurifier inside ImpressCMS
     if ( ! class_exists( 'icms_HTMLPurifier' ) ) {
         require_once ICMS_ROOT_PATH.'/class/icms.htmlpurifier.php' ;
     }
     //			$pure =& icms_HTMLPurifier::getPurifierInstance() ;
     //			$_POST = $pure->icms_html_purifier( $_POST , 'protector' ) ;
     $this->purifier =& icms_HTMLPurifier::getPurifierInstance() ;
     $this->method = 'icms_html_purifier' ;
     
             } else {
     */
     // use HTMLPurifier inside Protector
     require_once dirname(dirname(__FILE__)) . '/library/HTMLPurifier.auto.php';
     $config = HTMLPurifier_Config::createDefault();
     $config->set('Cache', 'SerializerPath', XOOPS_TRUST_PATH . '/modules/protector/configs');
     $config->set('Core', 'Encoding', _CHARSET);
     //$config->set('HTML', 'Doctype', 'HTML 4.01 Transitional');
     $this->purifier = new HTMLPurifier($config);
     $this->method = 'purify';
     //        }
     $_POST = $this->purify_recursive($_POST);
 }
 function test()
 {
     generate_mock_once('HTMLPurifier_URIScheme');
     $config = HTMLPurifier_Config::create(array('URI.AllowedSchemes' => 'http, telnet', 'URI.OverrideAllowedSchemes' => true));
     $context = new HTMLPurifier_Context();
     $registry = new HTMLPurifier_URISchemeRegistry();
     $this->assertIsA($registry->getScheme('http', $config, $context), 'HTMLPurifier_URIScheme_http');
     $scheme_http = new HTMLPurifier_URISchemeMock();
     $scheme_telnet = new HTMLPurifier_URISchemeMock();
     $scheme_foobar = new HTMLPurifier_URISchemeMock();
     // register a new scheme
     $registry->register('telnet', $scheme_telnet);
     $this->assertIdentical($registry->getScheme('telnet', $config, $context), $scheme_telnet);
     // overload a scheme, this is FINAL (forget about defaults)
     $registry->register('http', $scheme_http);
     $this->assertIdentical($registry->getScheme('http', $config, $context), $scheme_http);
     // when we register a scheme, it's automatically allowed
     $registry->register('foobar', $scheme_foobar);
     $this->assertIdentical($registry->getScheme('foobar', $config, $context), $scheme_foobar);
     // now, test when overriding is not allowed
     $config = HTMLPurifier_Config::create(array('URI.AllowedSchemes' => 'http, telnet', 'URI.OverrideAllowedSchemes' => false));
     $this->assertNull($registry->getScheme('foobar', $config, $context));
     // scheme not allowed and never registered
     $this->assertNull($registry->getScheme('ftp', $config, $context));
 }