Static Public Member Functions | Static Private Member Functions

Sanitizer Class Reference

Static Public Member Functions

static validateTagAttributes ($attribs, $element)
 Take an array of attribute names and values and normalize or discard illegal values for the given element type.
static checkCss ($value)
 Pick apart some CSS and check it for forbidden or unsafe structures.
static fixTagAttributes ($text, $element)
 Take a tag soup fragment listing an HTML element's attributes and normalize it to well-formed XML, discarding unwanted attributes.
static encodeAttribute ($text)
 Encode an attribute value for HTML output.
static safeEncodeAttribute ($text)
 Encode an attribute value for HTML tags, with extra armoring against further wiki processing.
static escapeId ($id)
 Given a value escape it so that it can be used in an id attribute and return it, this does not validate the value however (see first link).
static escapeClass ($class)
 Given a value, escape it so that it can be used as a CSS class and return it.
static decodeTagAttributes ($text)
 Return an associative array of attribute names and values from a partial tag string.
static normalizeCharReferencesCallback ($matches)
static normalizeEntity ($name)
 If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD, return the named entity reference as is.
static decCharReference ($codepoint)
static hexCharReference ($codepoint)
static decodeCharReferences ($text)
 Decode any character references, numeric or named entities, in the text and return a UTF-8 string.
static decodeCharReferencesCallback ($matches)
static decodeEntity ($name)
 If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD, return the UTF-8 encoding of that character.
static attributeWhitelist ($element)
 Fetch the whitelist of acceptable attributes for a given element name.
static setupAttributeWhitelist ()
static stripAllTags ($text)
 Take a fragment of (potentially invalid) HTML and return a version with any tags removed, encoded as plain text.
static hackDocType ()
 Hack up a private DOCTYPE with HTML's standard entity declarations.
static cleanUrl ($url, $hostname=true)

Static Private Member Functions

static removeHTMLtags ($text, $processCallback=null, $args=array())
 Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments.
static removeHTMLcomments ($text)
 Remove '', and everything between.
static armorLinksCallback ($matches)
 Regex replace callback for armoring links against further processing.
static getTagAttributeCallback ($set)
 Pick the appropriate attribute value from a match set from the MW_ATTRIBS_REGEX matches.
static normalizeAttributeValue ($text)
 Normalize whitespace and character references in an XML source- encoded text for an attribute value.
static normalizeWhitespace ($text)
static normalizeCharReferences ($text)
 Ensure that any entities and character references are legal for XML and XHTML specifically.
static validateCodepoint ($codepoint)
 Returns true if a given Unicode codepoint is a valid character in XML.
static decodeChar ($codepoint)
 Return UTF-8 string for a codepoint if that is a valid character reference, otherwise U+FFFD REPLACEMENT CHARACTER.

Detailed Description

Definition at line 330 of file Sanitizer.php.


Member Function Documentation

static Sanitizer::armorLinksCallback ( matches  )  [static, private]

Regex replace callback for armoring links against further processing.

Parameters:
array $matches
Returns:
string

Definition at line 772 of file Sanitizer.php.

                                                               {

static Sanitizer::attributeWhitelist ( element  )  [static]

Fetch the whitelist of acceptable attributes for a given element name.

Parameters:
string $element
Returns:
array

Definition at line 1041 of file Sanitizer.php.

                                                       {
                static $list;
                if( !isset( $list ) ) {
                        $list = Sanitizer::setupAttributeWhitelist();
                }
                return isset( $list[$element] )
                        ? $list[$element]

static Sanitizer::checkCss ( value  )  [static]

Pick apart some CSS and check it for forbidden or unsafe structures.

Returns a sanitized string, or false if it was just too evil.

Currently URL references, 'expression', 'tps' are forbidden.

Parameters:
string $value
Returns:
mixed

Definition at line 611 of file Sanitizer.php.

                                           {
                $stripped = Sanitizer::decodeCharReferences( $value );

                // Remove any comments; IE gets token splitting wrong
                $stripped = StringUtils::delimiterReplace( '/*', '*/', ' ', $stripped );
                
                $value = $stripped;

                // ... and continue checks
                $stripped = preg_replace( '!\\\\([0-9A-Fa-f]{1,6})[ \\n\\r\\t\\f]?!e',
                        'codepointToUtf8(hexdec("$1"))', $stripped );
                $stripped = str_replace( '\\', '', $stripped );
                if( preg_match( '/(?:expression|tps*:\/\/|url\\s*\().*/is',
                                $stripped ) ) {
                        # haxx0r
                        return false;
                }
                

static Sanitizer::cleanUrl ( url,
hostname = true 
) [static]

Definition at line 1232 of file Sanitizer.php.

                                                         {
                # Normalize any HTML entities in input. They will be
                # re-escaped by makeExternalLink().

                $url = Sanitizer::decodeCharReferences( $url );

                # Escape any control characters introduced by the above step
                $url = preg_replace( '/[\][<>"\\x00-\\x20\\x7F]/e', "urlencode('\\0')", $url );

                # Validate hostname portion
                $matches = array();
                if( preg_match( '!^([^:]+:)(//[^/]+)?(.*)$!iD', $url, $matches ) ) {
                        list( /* $whole */, $protocol, $host, $rest ) = $matches;

                        // Characters that will be ignored in IDNs.
                        // http://tools.ietf.org/html/3454#section-3.1
                        // Strip them before further processing so blacklists and such work.
                        $strip = "/
                                \\s|          # general whitespace
                                \xc2\xad|     # 00ad SOFT HYPHEN
                                \xe1\xa0\x86| # 1806 MONGOLIAN TODO SOFT HYPHEN
                                \xe2\x80\x8b| # 200b ZERO WIDTH SPACE
                                \xe2\x81\xa0| # 2060 WORD JOINER
                                \xef\xbb\xbf| # feff ZERO WIDTH NO-BREAK SPACE
                                \xcd\x8f|     # 034f COMBINING GRAPHEME JOINER
                                \xe1\xa0\x8b| # 180b MONGOLIAN FREE VARIATION SELECTOR ONE
                                \xe1\xa0\x8c| # 180c MONGOLIAN FREE VARIATION SELECTOR TWO
                                \xe1\xa0\x8d| # 180d MONGOLIAN FREE VARIATION SELECTOR THREE
                                \xe2\x80\x8c| # 200c ZERO WIDTH NON-JOINER
                                \xe2\x80\x8d| # 200d ZERO WIDTH JOINER
                                [\xef\xb8\x80-\xef\xb8\x8f] # fe00-fe00f VARIATION SELECTOR-1-16
                                /xuD";

                        $host = preg_replace( $strip, '', $host );

                        // @fixme: validate hostnames here

                        return $protocol . $host . $rest;
                } else {
                        return $url;

static Sanitizer::decCharReference ( codepoint  )  [static]

Definition at line 932 of file Sanitizer.php.

                                                       {
                $point = intval( $codepoint );
                if( Sanitizer::validateCodepoint( $point ) ) {
                        return sprintf( '&#%d;', $point );
                } else {
                        return null;

static Sanitizer::decodeChar ( codepoint  )  [static, private]

Return UTF-8 string for a codepoint if that is a valid character reference, otherwise U+FFFD REPLACEMENT CHARACTER.

Parameters:
int $codepoint
Returns:
string

Definition at line 1005 of file Sanitizer.php.

                                                 {
                if( Sanitizer::validateCodepoint( $codepoint ) ) {
                        return codepointToUtf8( $codepoint );
                } else {
                        return UTF8_REPLACEMENT;

static Sanitizer::decodeCharReferences ( text  )  [static]

Decode any character references, numeric or named entities, in the text and return a UTF-8 string.

Parameters:
string $text
Returns:
string

Definition at line 973 of file Sanitizer.php.

                                                             {
                return preg_replace_callback(
                        MW_CHAR_REFS_REGEX,
                        array( 'Sanitizer', 'decodeCharReferencesCallback' ),

static Sanitizer::decodeCharReferencesCallback ( matches  )  [static]
Parameters:
string $matches
Returns:
string

Definition at line 984 of file Sanitizer.php.

                                                                 {
                if( $matches[1] != '' ) {
                        return Sanitizer::decodeEntity( $matches[1] );
                } elseif( $matches[2] != '' ) {
                        return  Sanitizer::decodeChar( intval( $matches[2] ) );
                } elseif( $matches[3] != ''  ) {
                        return  Sanitizer::decodeChar( hexdec( $matches[3] ) );
                } elseif( $matches[4] != '' ) {
                        return  Sanitizer::decodeChar( hexdec( $matches[4] ) );
                }
                # Last case should be an ampersand by itself

static Sanitizer::decodeEntity ( name  )  [static]

If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD, return the UTF-8 encoding of that character.

Otherwise, returns pseudo-entity source (eg )

Parameters:
string $name
Returns:
string

Definition at line 1021 of file Sanitizer.php.

                                              {
                global $wgHtmlEntities, $wgHtmlEntityAliases;
                
                if ( isset( $wgHtmlEntityAliases[$name] ) ) {
                        $name = $wgHtmlEntityAliases[$name];
                }
                if( isset( $wgHtmlEntities[$name] ) ) {
                        return codepointToUtf8( $wgHtmlEntities[$name] );
                } else {
                        return "&$name;";

static Sanitizer::decodeTagAttributes ( text  )  [static]

Return an associative array of attribute names and values from a partial tag string.

Attribute names are forces to lowercase, character references are decoded to UTF-8 text.

Parameters:
string 
Returns:
array

Definition at line 784 of file Sanitizer.php.

                                                     {
                $attribs = array();

                if( trim( $text ) == '' ) {
                        return $attribs;
                }

                $pairs = array();
                if( !preg_match_all(
                        MW_ATTRIBS_REGEX,
                        $text,
                        $pairs,
                        PREG_SET_ORDER ) ) {
                        return $attribs;
                }

                foreach( $pairs as $set ) {
                        $attribute = strtolower( $set[1] );
                        $value = Sanitizer::getTagAttributeCallback( $set );

                        // Normalize whitespace
                        $value = preg_replace( '/[\t\r\n ]+/', ' ', $value );
                        $value = trim( $value );

                        // Decode character references
                        $attribs[$attribute] = Sanitizer::decodeCharReferences( $value );
                }

static Sanitizer::encodeAttribute ( text  )  [static]

Encode an attribute value for HTML output.

Parameters:
$text 
Returns:
HTML-encoded text fragment

Definition at line 674 of file Sanitizer.php.

                                                 {
                $encValue = htmlspecialchars( $text );

                // Whitespace is normalized during attribute decoding,
                // so if we've been passed non-spaces we must encode them
                // ahead of time or they won't be preserved.
                $encValue = strtr( $encValue, array(
                        "\n" => '&#10;',
                        "\r" => '&#13;',
                        "\t" => '&#9;',
                ) );

static Sanitizer::escapeClass ( class  )  [static]

Given a value, escape it so that it can be used as a CSS class and return it.

Todo:
For extra validity, input should be validated UTF-8.
See also:
http://www.w3.org/TR/CSS21/syndata.html Valid characters/format
Parameters:
string $class
Returns:
string

Definition at line 758 of file Sanitizer.php.

                                              {
                // Convert ugly stuff to underscores and kill underscores in ugly places
                return rtrim(preg_replace(
                        array('/(^[0-9\\-])|[\\x00-\\x20!"#$%&\'()*+,.\\/:;<=>?@[\\]^`{|}~]|\\xC2\\xA0/','/_+/'),
                        '_',

static Sanitizer::escapeId ( id  )  [static]

Given a value escape it so that it can be used in an id attribute and return it, this does not validate the value however (see first link).

See also:
http://www.w3.org/TR/html401/types.html#type-name Valid characters in the id and name attributes
http://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with the id attribute
Parameters:
string $id
Returns:
string

Definition at line 736 of file Sanitizer.php.

                                        {
                static $replace = array(
                        '%3A' => ':',
                        '%' => '.'
                );

                $id = urlencode( Sanitizer::decodeCharReferences( strtr( $id, ' ', '_' ) ) );

static Sanitizer::fixTagAttributes ( text,
element 
) [static]

Take a tag soup fragment listing an HTML element's attributes and normalize it to well-formed XML, discarding unwanted attributes.

Output is safe for further wikitext processing, with escaping of values that could trigger problems.

  • Normalizes attribute names to lowercase
  • Discards attributes not on a whitelist for the given element
  • Turns broken or invalid entities into plaintext
  • Double-quotes all attribute values
  • Attributes without values are given the name as attribute
  • Double attributes are discarded
  • Unsafe style attributes are discarded
  • Prepends space if there are attributes.
Parameters:
string $text
string $element
Returns:
string

Definition at line 651 of file Sanitizer.php.

                                                            {
                if( trim( $text ) == '' ) {
                        return '';
                }

                $stripped = Sanitizer::validateTagAttributes(
                        Sanitizer::decodeTagAttributes( $text ), $element );

                $attribs = array();
                foreach( $stripped as $attribute => $value ) {
                        $encAttribute = htmlspecialchars( $attribute );
                        $encValue = Sanitizer::safeEncodeAttribute( $value );

                        $attribs[] = "$encAttribute=\"$encValue\"";
                }

static Sanitizer::getTagAttributeCallback ( set  )  [static, private]

Pick the appropriate attribute value from a match set from the MW_ATTRIBS_REGEX matches.

Parameters:
array $set
Returns:
string

Definition at line 822 of file Sanitizer.php.

                                                                {
                if( isset( $set[6] ) ) {
                        # Illegal #XXXXXX color with no quotes.
                        return $set[6];
                } elseif( isset( $set[5] ) ) {
                        # No quotes.
                        return $set[5];
                } elseif( isset( $set[4] ) ) {
                        # Single-quoted
                        return $set[4];
                } elseif( isset( $set[3] ) ) {
                        # Double-quoted
                        return $set[3];
                } elseif( !isset( $set[2] ) ) {
                        # In XHTML, attributes must have a value.
                        # For 'reduced' form, return explicitly the attribute name here.
                        return $set[1];
                } else {
                        throw new MWException( "Tag conditions not met. This should never happen and is a bug." );

static Sanitizer::hackDocType (  )  [static]

Hack up a private DOCTYPE with HTML's standard entity declarations.

PHP 4 seemed to know these if you gave it an HTML doctype, but PHP 5.1 doesn't.

Use for passing XHTML fragments to PHP's XML parsing functions

Returns:
string

Definition at line 1222 of file Sanitizer.php.

                                      {
                global $wgHtmlEntities;
                $out = "<!DOCTYPE html [\n";
                foreach( $wgHtmlEntities as $entity => $codepoint ) {
                        $out .= "<!ENTITY $entity \"&#$codepoint;\">";
                }
                $out .= "]>\n";

static Sanitizer::hexCharReference ( codepoint  )  [static]

Definition at line 941 of file Sanitizer.php.

                                                       {
                $point = hexdec( $codepoint );
                if( Sanitizer::validateCodepoint( $point ) ) {
                        return sprintf( '&#x%x;', $point );
                } else {
                        return null;

static Sanitizer::normalizeAttributeValue ( text  )  [static, private]

Normalize whitespace and character references in an XML source- encoded text for an attribute value.

See http://www.w3.org/TR/REC-xml/#AVNormalize for background, but note that we're not returning the value, but are returning XML source fragments that will be slapped into output.

Parameters:
string $text
Returns:
string

Definition at line 856 of file Sanitizer.php.

                                                                 {
                return str_replace( '"', '&quot;',
                        self::normalizeWhitespace(

static Sanitizer::normalizeCharReferences ( text  )  [static, private]

Ensure that any entities and character references are legal for XML and XHTML specifically.

Any stray bits will be &-escaped to result in a valid text fragment.

a. any named char refs must be known in XHTML b. any numeric char refs must be legal chars, not invalid or forbidden c. use &x, not &X d. fix or reject non-valid attributes

Parameters:
string $text
Returns:
string

Definition at line 883 of file Sanitizer.php.

                                                         {
                return preg_replace_callback(
                        MW_CHAR_REFS_REGEX,
                        array( 'Sanitizer', 'normalizeCharReferencesCallback' ),

static Sanitizer::normalizeCharReferencesCallback ( matches  )  [static]
Parameters:
string $matches
Returns:
string

Definition at line 893 of file Sanitizer.php.

                                                                    {
                $ret = null;
                if( $matches[1] != '' ) {
                        $ret = Sanitizer::normalizeEntity( $matches[1] );
                } elseif( $matches[2] != '' ) {
                        $ret = Sanitizer::decCharReference( $matches[2] );
                } elseif( $matches[3] != ''  ) {
                        $ret = Sanitizer::hexCharReference( $matches[3] );
                } elseif( $matches[4] != '' ) {
                        $ret = Sanitizer::hexCharReference( $matches[4] );
                }
                if( is_null( $ret ) ) {
                        return htmlspecialchars( $matches[0] );
                } else {
                        return $ret;

static Sanitizer::normalizeEntity ( name  )  [static]

If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD, return the named entity reference as is.

If the entity is a MediaWiki-specific alias, returns the HTML equivalent. Otherwise, returns HTML-escaped text of pseudo-entity source (eg &foo;)

Parameters:
string $name
Returns:
string

Definition at line 921 of file Sanitizer.php.

                                                 {
                global $wgHtmlEntities, $wgHtmlEntityAliases;
                if ( isset( $wgHtmlEntityAliases[$name] ) ) {
                        return "&{$wgHtmlEntityAliases[$name]};";
                } elseif( isset( $wgHtmlEntities[$name] ) ) {
                        return "&$name;";
                } else {
                        return "&amp;$name;";

static Sanitizer::normalizeWhitespace ( text  )  [static, private]

Definition at line 862 of file Sanitizer.php.

                                                             {
                return preg_replace(
                        '/\r\n|[\x20\x0d\x0a\x09]/',
                        ' ',

static Sanitizer::removeHTMLcomments ( text  )  [static, private]

Remove '', and everything between.

To avoid leaving blank lines, when a comment is both preceded and followed by a newline (ignoring spaces), trim leading and trailing spaces and one of the newlines.

Parameters:
string $text
Returns:
string

Definition at line 526 of file Sanitizer.php.

                                                    {
                wfProfileIn( __METHOD__ );
                while (($start = strpos($text, '<!--')) !== false) {
                        $end = strpos($text, '-->', $start + 4);
                        if ($end === false) {
                                # Unterminated comment; bail out
                                break;
                        }

                        $end += 3;

                        # Trim space and newline if the comment is both
                        # preceded and followed by a newline
                        $spaceStart = max($start - 1, 0);
                        $spaceLen = $end - $spaceStart;
                        while (substr($text, $spaceStart, 1) === ' ' && $spaceStart > 0) {
                                $spaceStart--;
                                $spaceLen++;
                        }
                        while (substr($text, $spaceStart + $spaceLen, 1) === ' ')
                                $spaceLen++;
                        if (substr($text, $spaceStart, 1) === "\n" and substr($text, $spaceStart + $spaceLen, 1) === "\n") {
                                # Remove the comment, leading and trailing
                                # spaces, and leave only one newline.
                                $text = substr_replace($text, "\n", $spaceStart, $spaceLen + 1);
                        }
                        else {
                                # Remove just the comment.
                                $text = substr_replace($text, '', $start, $end - $start);
                        }
                }
                wfProfileOut( __METHOD__ );

static Sanitizer::removeHTMLtags ( text,
processCallback = null,
args = array() 
) [static, private]

Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments.

Parameters:
string $text
callback $processCallback to do any variable or parameter replacements in HTML attribute values
array $args for the processing callback
Returns:
string

Definition at line 340 of file Sanitizer.php.

                                                                                          {
                global $wgUseTidy;

                static $htmlpairs, $htmlsingle, $htmlsingleonly, $htmlnest, $tabletags,
                        $htmllist, $listtags, $htmlsingleallowed, $htmlelements, $staticInitialised;

                wfProfileIn( __METHOD__ );

                if ( !$staticInitialised ) {

                        $htmlpairs = array( # Tags that must be closed
                                'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1',
                                'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
                                'strike', 'strong', 'tt', 'var', 'div', 'center',
                                'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
                                'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'u'
                        );
                        $htmlsingle = array(
                                'br', 'hr', 'li', 'dt', 'dd'
                        );
                        $htmlsingleonly = array( # Elements that cannot have close tags
                                'br', 'hr'
                        );
                        $htmlnest = array( # Tags that can be nested--??
                                'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul',
                                'dl', 'font', 'big', 'small', 'sub', 'sup', 'span'
                        );
                        $tabletags = array( # Can only appear inside table, we will close them
                                'td', 'th', 'tr',
                        );
                        $htmllist = array( # Tags used by list
                                'ul','ol',
                        );
                        $listtags = array( # Tags that can appear in a list
                                'li',
                        );

                        $htmlsingleallowed = array_merge( $htmlsingle, $tabletags );
                        $htmlelements = array_merge( $htmlsingle, $htmlpairs, $htmlnest );

                        # Convert them all to hashtables for faster lookup
                        $vars = array( 'htmlpairs', 'htmlsingle', 'htmlsingleonly', 'htmlnest', 'tabletags', 
                                'htmllist', 'listtags', 'htmlsingleallowed', 'htmlelements' );
                        foreach ( $vars as $var ) {
                                $$var = array_flip( $$var );
                        }
                        $staticInitialised = true;
                }

                # Remove HTML comments
                $text = Sanitizer::removeHTMLcomments( $text );
                $bits = explode( '<', $text );
                $text = str_replace( '>', '&gt;', array_shift( $bits ) );
                if(!$wgUseTidy) {
                        $tagstack = $tablestack = array();
                        foreach ( $bits as $x ) {
                                $regs = array();
                                if( preg_match( '!^(/?)(\\w+)([^>]*?)(/{0,1}>)([^<]*)$!', $x, $regs ) ) {
                                        list( /* $qbar */, $slash, $t, $params, $brace, $rest ) = $regs;
                                } else {
                                        $slash = $t = $params = $brace = $rest = null;
                                }

                                $badtag = 0 ;
                                if ( isset( $htmlelements[$t = strtolower( $t )] ) ) {
                                        # Check our stack
                                        if ( $slash ) {
                                                # Closing a tag...
                                                if( isset( $htmlsingleonly[$t] ) ) {
                                                        $badtag = 1;
                                                } elseif ( ( $ot = @array_pop( $tagstack ) ) != $t ) {
                                                        if ( isset( $htmlsingleallowed[$ot] ) ) {
                                                                # Pop all elements with an optional close tag
                                                                # and see if we find a match below them
                                                                $optstack = array();
                                                                array_push ($optstack, $ot);
                                                                while ( ( ( $ot = @array_pop( $tagstack ) ) != $t ) &&
                                                                                isset( $htmlsingleallowed[$ot] ) ) 
                                                                {
                                                                        array_push ($optstack, $ot);
                                                                }
                                                                if ( $t != $ot ) {
                                                                        # No match. Push the optinal elements back again
                                                                        $badtag = 1;
                                                                        while ( $ot = @array_pop( $optstack ) ) {
                                                                                array_push( $tagstack, $ot );
                                                                        }
                                                                }
                                                        } else {
                                                                @array_push( $tagstack, $ot );
                                                                # <li> can be nested in <ul> or <ol>, skip those cases:
                                                                if(!(isset( $htmllist[$ot] ) && isset( $listtags[$t] ) )) {
                                                                        $badtag = 1;
                                                                }
                                                        }
                                                } else {
                                                        if ( $t == 'table' ) {
                                                                $tagstack = array_pop( $tablestack );
                                                        }
                                                }
                                                $newparams = '';
                                        } else {
                                                # Keep track for later
                                                if ( isset( $tabletags[$t] ) &&
                                                ! in_array( 'table', $tagstack ) ) {
                                                        $badtag = 1;
                                                } else if ( in_array( $t, $tagstack ) &&
                                                ! isset( $htmlnest [$t ] ) ) {
                                                        $badtag = 1 ;
                                                # Is it a self closed htmlpair ? (bug 5487)
                                                } else if( $brace == '/>' &&
                                                isset( $htmlpairs[$t] ) ) {
                                                        $badtag = 1;
                                                } elseif( isset( $htmlsingleonly[$t] ) ) {
                                                        # Hack to force empty tag for uncloseable elements
                                                        $brace = '/>';
                                                } else if( isset( $htmlsingle[$t] ) ) {
                                                        # Hack to not close $htmlsingle tags
                                                        $brace = NULL;
                                                } else if( isset( $tabletags[$t] )
                                                &&  in_array($t ,$tagstack) ) {
                                                        // New table tag but forgot to close the previous one
                                                        $text .= "</$t>";
                                                } else {
                                                        if ( $t == 'table' ) {
                                                                array_push( $tablestack, $tagstack );
                                                                $tagstack = array();
                                                        }
                                                        array_push( $tagstack, $t );
                                                }

                                                # Replace any variables or template parameters with
                                                # plaintext results.
                                                if( is_callable( $processCallback ) ) {
                                                        call_user_func_array( $processCallback, array( &$params, $args ) );
                                                }

                                                # Strip non-approved attributes from the tag
                                                $newparams = Sanitizer::fixTagAttributes( $params, $t );
                                        }
                                        if ( ! $badtag ) {
                                                $rest = str_replace( '>', '&gt;', $rest );
                                                $close = ( $brace == '/>' && !$slash ) ? ' /' : '';
                                                $text .= "<$slash$t$newparams$close>$rest";
                                                continue;
                                        }
                                }
                                $text .= '&lt;' . str_replace( '>', '&gt;', $x);
                        }
                        # Close off any remaining tags
                        while ( is_array( $tagstack ) && ($t = array_pop( $tagstack )) ) {
                                $text .= "</$t>\n";
                                if ( $t == 'table' ) { $tagstack = array_pop( $tablestack ); }
                        }
                } else {
                        # this might be possible using tidy itself
                        foreach ( $bits as $x ) {
                                preg_match( '/^(\\/?)(\\w+)([^>]*?)(\\/{0,1}>)([^<]*)$/',
                                $x, $regs );
                                @list( /* $qbar */, $slash, $t, $params, $brace, $rest ) = $regs;
                                if ( isset( $htmlelements[$t = strtolower( $t )] ) ) {
                                        if( is_callable( $processCallback ) ) {
                                                call_user_func_array( $processCallback, array( &$params, $args ) );
                                        }
                                        $newparams = Sanitizer::fixTagAttributes( $params, $t );
                                        $rest = str_replace( '>', '&gt;', $rest );
                                        $text .= "<$slash$t$newparams$brace$rest";
                                } else {
                                        $text .= '&lt;' . str_replace( '>', '&gt;', $x);
                                }
                        }
                }
                wfProfileOut( __METHOD__ );

static Sanitizer::safeEncodeAttribute ( text  )  [static]

Encode an attribute value for HTML tags, with extra armoring against further wiki processing.

Parameters:
$text 
Returns:
HTML-encoded text fragment

Definition at line 695 of file Sanitizer.php.

                                                     {
                $encValue = Sanitizer::encodeAttribute( $text );

                # Templates and links may be expanded in later parsing,
                # creating invalid or dangerous output. Suppress this.
                $encValue = strtr( $encValue, array(
                        '<'    => '&lt;',   // This should never happen,
                        '>'    => '&gt;',   // we've received invalid input
                        '"'    => '&quot;', // which should have been escaped.
                        '{'    => '&#123;',
                        '['    => '&#91;',
                        "''"   => '&#39;&#39;',
                        'ISBN' => '&#73;SBN',
                        'RFC'  => '&#82;FC',
                        'PMID' => '&#80;MID',
                        '|'    => '&#124;',
                        '__'   => '&#95;_',
                ) );

                # Stupid hack
                $encValue = preg_replace_callback(
                        '/(' . wfUrlProtocols() . ')/',
                        array( 'Sanitizer', 'armorLinksCallback' ),
                        $encValue );

static Sanitizer::setupAttributeWhitelist (  )  [static]
Todo:
Document it a bit
Returns:
array

Definition at line 1055 of file Sanitizer.php.

                                                  {
                $common = array( 'id', 'class', 'lang', 'dir', 'title', 'style' );
                $block = array_merge( $common, array( 'align' ) );
                $tablealign = array( 'align', 'char', 'charoff', 'valign' );
                $tablecell = array( 'abbr',
                                    'axis',
                                    'headers',
                                    'scope',
                                    'rowspan',
                                    'colspan',
                                    'nowrap', # deprecated
                                    'width',  # deprecated
                                    'height', # deprecated
                                    'bgcolor' # deprecated
                                    );

                # Numbers refer to sections in HTML 4.01 standard describing the element.
                # See: http://www.w3.org/TR/html4/
                $whitelist = array (
                        # 7.5.4
                        'div'        => $block,
                        'center'     => $common, # deprecated
                        'span'       => $block, # ??

                        # 7.5.5
                        'h1'         => $block,
                        'h2'         => $block,
                        'h3'         => $block,
                        'h4'         => $block,
                        'h5'         => $block,
                        'h6'         => $block,

                        # 7.5.6
                        # address

                        # 8.2.4
                        # bdo

                        # 9.2.1
                        'em'         => $common,
                        'strong'     => $common,
                        'cite'       => $common,
                        # dfn
                        'code'       => $common,
                        # samp
                        # kbd
                        'var'        => $common,
                        # abbr
                        # acronym

                        # 9.2.2
                        'blockquote' => array_merge( $common, array( 'cite' ) ),
                        # q

                        # 9.2.3
                        'sub'        => $common,
                        'sup'        => $common,

                        # 9.3.1
                        'p'          => $block,

                        # 9.3.2
                        'br'         => array( 'id', 'class', 'title', 'style', 'clear' ),

                        # 9.3.4
                        'pre'        => array_merge( $common, array( 'width' ) ),

                        # 9.4
                        'ins'        => array_merge( $common, array( 'cite', 'datetime' ) ),
                        'del'        => array_merge( $common, array( 'cite', 'datetime' ) ),

                        # 10.2
                        'ul'         => array_merge( $common, array( 'type' ) ),
                        'ol'         => array_merge( $common, array( 'type', 'start' ) ),
                        'li'         => array_merge( $common, array( 'type', 'value' ) ),

                        # 10.3
                        'dl'         => $common,
                        'dd'         => $common,
                        'dt'         => $common,

                        # 11.2.1
                        'table'      => array_merge( $common,
                                                                array( 'summary', 'width', 'border', 'frame',
                                                                                'rules', 'cellspacing', 'cellpadding',
                                                                                'align', 'bgcolor',
                                                                ) ),

                        # 11.2.2
                        'caption'    => array_merge( $common, array( 'align' ) ),

                        # 11.2.3
                        'thead'      => array_merge( $common, $tablealign ),
                        'tfoot'      => array_merge( $common, $tablealign ),
                        'tbody'      => array_merge( $common, $tablealign ),

                        # 11.2.4
                        'colgroup'   => array_merge( $common, array( 'span', 'width' ), $tablealign ),
                        'col'        => array_merge( $common, array( 'span', 'width' ), $tablealign ),

                        # 11.2.5
                        'tr'         => array_merge( $common, array( 'bgcolor' ), $tablealign ),

                        # 11.2.6
                        'td'         => array_merge( $common, $tablecell, $tablealign ),
                        'th'         => array_merge( $common, $tablecell, $tablealign ),

                        # 15.2.1
                        'tt'         => $common,
                        'b'          => $common,
                        'i'          => $common,
                        'big'        => $common,
                        'small'      => $common,
                        'strike'     => $common,
                        's'          => $common,
                        'u'          => $common,

                        # 15.2.2
                        'font'       => array_merge( $common, array( 'size', 'color', 'face' ) ),
                        # basefont

                        # 15.3
                        'hr'         => array_merge( $common, array( 'noshade', 'size', 'width' ) ),

                        # XHTML Ruby annotation text module, simple ruby only.
                        # http://www.w3c.org/TR/ruby/
                        'ruby'       => $common,
                        # rbc
                        # rtc
                        'rb'         => $common,
                        'rt'         => $common, #array_merge( $common, array( 'rbspan' ) ),
                        'rp'         => $common,
                        );

static Sanitizer::stripAllTags ( text  )  [static]

Take a fragment of (potentially invalid) HTML and return a version with any tags removed, encoded as plain text.

Warning: this return value must be further escaped for literal inclusion in HTML output as of 1.10!

Parameters:
string $text HTML fragment
Returns:
string

Definition at line 1201 of file Sanitizer.php.

                                              {
                # Actual <tags>
                $text = StringUtils::delimiterReplace( '<', '>', '', $text );

                # Normalize &entities and whitespace
                $text = self::decodeCharReferences( $text );
                $text = self::normalizeWhitespace( $text );

static Sanitizer::validateCodepoint ( codepoint  )  [static, private]

Returns true if a given Unicode codepoint is a valid character in XML.

Parameters:
int $codepoint
Returns:
bool

Definition at line 955 of file Sanitizer.php.

                                                                {
                return ($codepoint ==    0x09)
                        || ($codepoint ==    0x0a)
                        || ($codepoint ==    0x0d)
                        || ($codepoint >=    0x20 && $codepoint <=   0xd7ff)
                        || ($codepoint >=  0xe000 && $codepoint <=   0xfffd)

static Sanitizer::validateTagAttributes ( attribs,
element 
) [static]

Take an array of attribute names and values and normalize or discard illegal values for the given element type.

  • Discards attributes not on a whitelist for the given element
  • Unsafe style attributes are discarded
Parameters:
array $attribs
string $element
Returns:
array
Todo:

Check for legal values where the DTD limits things.

Check for unique id attribute :P

Definition at line 575 of file Sanitizer.php.

                                               :P
         */
        static function validateTagAttributes( $attribs, $element ) {
                $whitelist = array_flip( Sanitizer::attributeWhitelist( $element ) );
                $out = array();
                foreach( $attribs as $attribute => $value ) {
                        if( !isset( $whitelist[$attribute] ) ) {
                                continue;
                        }
                        # Strip javascript "expression" from stylesheets.
                        # http://msdn.microsoft.com/workshop/author/dhtml/overview/recalc.asp
                        if( $attribute == 'style' ) {
                                $value = Sanitizer::checkCss( $value );
                                if( $value === false ) {
                                        # haxx0r
                                        continue;
                                }
                        }

                        if ( $attribute === 'id' )
                                $value = Sanitizer::escapeId( $value );

                        // If this attribute was previously set, override it.
                        // Output should only have one attribute of each name.
                        $out[$attribute] = $value;
                }


The documentation for this class was generated from the following file: