HomeHelpTrac

Changeset 15813 for tags


Ignore:
Timestamp:
12/29/11 20:32:05 (5 months ago)
Author:
Alexander Trofimov
Message:

Ticket #2720

Location:
tags/7.0
Files:
6 added
5 edited

Legend:

Unmodified
Added
Removed
  • tags/7.0/inc/utils.inc.php

    r15495 r15813  
    584584 
    585585        $oConfig->set('Filter.Custom', array (new HTMLPurifier_Filter_LocalMovie())); 
    586  
    587         $oConfig->set('HTML.DefinitionID', '1'); 
     586        $oConfig->set('Filter.Custom', array (new HTMLPurifier_Filter_YouTube())); 
     587 
    588588        $oDef = $oConfig->getHTMLDefinition(true); 
    589589        $oDef->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top'); 
  • tags/7.0/plugins/htmlpurifier/HTMLPurifier.standalone.php

    r15200 r15813  
    88 * FILE, changes will be overwritten the next time the script is run. 
    99 * 
    10  * @version 4.2.0 
     10 * @version 4.3.0 
    1111 * 
    1212 * @warning 
     
    4040 
    4141/* 
    42     HTML Purifier 4.2.0 - Standards Compliant HTML Filtering 
     42    HTML Purifier 4.3.0 - Standards Compliant HTML Filtering 
    4343    Copyright (C) 2006-2008 Edward Z. Yang 
    4444 
     
    7676 
    7777    /** Version of HTML Purifier */ 
    78     public $version = '4.2.0'; 
     78    public $version = '4.3.0'; 
    7979 
    8080    /** Constant with version of HTML Purifier */ 
    81     const VERSION = '4.2.0'; 
     81    const VERSION = '4.3.0'; 
    8282 
    8383    /** Global configuration object */ 
     
    848848        $file = HTMLPurifier_Bootstrap::getPath($class); 
    849849        if (!$file) return false; 
    850         require HTMLPURIFIER_PREFIX . '/' . $file; 
     850        // Technically speaking, it should be ok and more efficient to 
     851        // just do 'require', but Antonio Parraga reports that with 
     852        // Zend extensions such as Zend debugger and APC, this invariant 
     853        // may be broken.  Since we have efficient alternatives, pay 
     854        // the cost here and avoid the bug. 
     855        require_once HTMLPURIFIER_PREFIX . '/' . $file; 
    851856        return true; 
    852857    } 
     
    876881            spl_autoload_register($autoload); 
    877882        } elseif (function_exists('spl_autoload_unregister')) { 
     883            $buggy  = version_compare(PHP_VERSION, '5.2.11', '<'); 
    878884            $compat = version_compare(PHP_VERSION, '5.1.2', '<=') && 
    879885                      version_compare(PHP_VERSION, '5.1.0', '>='); 
    880886            foreach ($funcs as $func) { 
    881                 if (is_array($func)) { 
     887                if ($buggy && is_array($func)) { 
    882888                    // :TRICKY: There are some compatibility issues and some 
    883889                    // places where we need to error out 
     
    923929 
    924930    /** 
     931     * If true, write out the final definition object to the cache after 
     932     * setup.  This will be true only if all invocations to get a raw 
     933     * definition object are also optimized.  This does not cause file 
     934     * system thrashing because on subsequent calls the cached object 
     935     * is used and any writes to the raw definition object are short 
     936     * circuited.  See enduser-customize.html for the high-level 
     937     * picture. 
     938     */ 
     939    public $optimized = null; 
     940 
     941    /** 
    925942     * What type of definition is it? 
    926943     */ 
     
    11691186        } 
    11701187 
     1188        if ($config->get('CSS.Trusted')) { 
     1189            $this->doSetupTrusted($config); 
     1190        } 
     1191 
    11711192        $allow_important = $config->get('CSS.AllowImportant'); 
    11721193        // wrap all attr-defs with decorator that handles !important 
     
    12101231    } 
    12111232 
     1233    protected function doSetupTrusted($config) { 
     1234        $this->info['position'] = new HTMLPurifier_AttrDef_Enum(array( 
     1235            'static', 'relative', 'absolute', 'fixed' 
     1236        )); 
     1237        $this->info['top'] = 
     1238        $this->info['left'] = 
     1239        $this->info['right'] = 
     1240        $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(array( 
     1241            new HTMLPurifier_AttrDef_CSS_Length(), 
     1242            new HTMLPurifier_AttrDef_CSS_Percentage(), 
     1243            new HTMLPurifier_AttrDef_Enum(array('auto')), 
     1244        )); 
     1245        $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(array( 
     1246            new HTMLPurifier_AttrDef_Integer(), 
     1247            new HTMLPurifier_AttrDef_Enum(array('auto')), 
     1248        )); 
     1249    } 
    12121250 
    12131251    /** 
     
    13211359     * HTML Purifier's version 
    13221360     */ 
    1323     public $version = '4.2.0'; 
     1361    public $version = '4.3.0'; 
    13241362 
    13251363    /** 
     
    13771415    /** 
    13781416     * Set to false if you do not want line and file numbers in errors 
    1379      * (useful when unit testing) 
     1417     * (useful when unit testing).  This will also compress some errors 
     1418     * and exceptions. 
    13801419     */ 
    13811420    public $chatty = true; 
     
    16191658     * @param $raw Return a copy that has not been setup yet. Must be 
    16201659     *             called before it's been setup, otherwise won't work. 
    1621      */ 
    1622     public function getHTMLDefinition($raw = false) { 
    1623         return $this->getDefinition('HTML', $raw); 
     1660     * @param $optimized If true, this method may return null, to 
     1661     *             indicate that a cached version of the modified 
     1662     *             definition object is available and no further edits 
     1663     *             are necessary.  Consider using 
     1664     *             maybeGetRawHTMLDefinition, which is more explicitly 
     1665     *             named, instead. 
     1666     */ 
     1667    public function getHTMLDefinition($raw = false, $optimized = false) { 
     1668        return $this->getDefinition('HTML', $raw, $optimized); 
    16241669    } 
    16251670 
     
    16281673     * @param $raw Return a copy that has not been setup yet. Must be 
    16291674     *             called before it's been setup, otherwise won't work. 
    1630      */ 
    1631     public function getCSSDefinition($raw = false) { 
    1632         return $this->getDefinition('CSS', $raw); 
     1675     * @param $optimized If true, this method may return null, to 
     1676     *             indicate that a cached version of the modified 
     1677     *             definition object is available and no further edits 
     1678     *             are necessary.  Consider using 
     1679     *             maybeGetRawCSSDefinition, which is more explicitly 
     1680     *             named, instead. 
     1681     */ 
     1682    public function getCSSDefinition($raw = false, $optimized = false) { 
     1683        return $this->getDefinition('CSS', $raw, $optimized); 
     1684    } 
     1685 
     1686    /** 
     1687     * Retrieves object reference to the URI definition 
     1688     * @param $raw Return a copy that has not been setup yet. Must be 
     1689     *             called before it's been setup, otherwise won't work. 
     1690     * @param $optimized If true, this method may return null, to 
     1691     *             indicate that a cached version of the modified 
     1692     *             definition object is available and no further edits 
     1693     *             are necessary.  Consider using 
     1694     *             maybeGetRawURIDefinition, which is more explicitly 
     1695     *             named, instead. 
     1696     */ 
     1697    public function getURIDefinition($raw = false, $optimized = false) { 
     1698        return $this->getDefinition('URI', $raw, $optimized); 
    16331699    } 
    16341700 
     
    16371703     * @param $type Type of definition: HTML, CSS, etc 
    16381704     * @param $raw  Whether or not definition should be returned raw 
    1639      */ 
    1640     public function getDefinition($type, $raw = false) { 
     1705     * @param $optimized Only has an effect when $raw is true.  Whether 
     1706     *        or not to return null if the result is already present in 
     1707     *        the cache.  This is off by default for backwards 
     1708     *        compatibility reasons, but you need to do things this 
     1709     *        way in order to ensure that caching is done properly. 
     1710     *        Check out enduser-customize.html for more details. 
     1711     *        We probably won't ever change this default, as much as the 
     1712     *        maybe semantics is the "right thing to do." 
     1713     */ 
     1714    public function getDefinition($type, $raw = false, $optimized = false) { 
     1715        if ($optimized && !$raw) { 
     1716            throw new HTMLPurifier_Exception("Cannot set optimized = true when raw = false"); 
     1717        } 
    16411718        if (!$this->finalized) $this->autoFinalize(); 
    16421719        // temporarily suspend locks, so we can handle recursive definition calls 
     
    16471724        $this->lock = $lock; 
    16481725        if (!$raw) { 
    1649             // see if we can quickly supply a definition 
     1726            // full definition 
     1727            // --------------- 
     1728            // check if definition is in memory 
    16501729            if (!empty($this->definitions[$type])) { 
    1651                 if (!$this->definitions[$type]->setup) { 
    1652                     $this->definitions[$type]->setup($this); 
    1653                     $cache->set($this->definitions[$type], $this); 
     1730                $def = $this->definitions[$type]; 
     1731                // check if the definition is setup 
     1732                if ($def->setup) { 
     1733                    return $def; 
     1734                } else { 
     1735                    $def->setup($this); 
     1736                    if ($def->optimized) $cache->add($def, $this); 
     1737                    return $def; 
    16541738                } 
    1655                 return $this->definitions[$type]; 
    1656             } 
    1657             // memory check missed, try cache 
    1658             $this->definitions[$type] = $cache->get($this); 
    1659             if ($this->definitions[$type]) { 
    1660                 // definition in cache, return it 
    1661                 return $this->definitions[$type]; 
    1662             } 
    1663         } elseif ( 
    1664             !empty($this->definitions[$type]) && 
    1665             !$this->definitions[$type]->setup 
    1666         ) { 
    1667             // raw requested, raw in memory, quick return 
    1668             return $this->definitions[$type]; 
    1669         } 
     1739            } 
     1740            // check if definition is in cache 
     1741            $def = $cache->get($this); 
     1742            if ($def) { 
     1743                // definition in cache, save to memory and return it 
     1744                $this->definitions[$type] = $def; 
     1745                return $def; 
     1746            } 
     1747            // initialize it 
     1748            $def = $this->initDefinition($type); 
     1749            // set it up 
     1750            $this->lock = $type; 
     1751            $def->setup($this); 
     1752            $this->lock = null; 
     1753            // save in cache 
     1754            $cache->add($def, $this); 
     1755            // return it 
     1756            return $def; 
     1757        } else { 
     1758            // raw definition 
     1759            // -------------- 
     1760            // check preconditions 
     1761            $def = null; 
     1762            if ($optimized) { 
     1763                if (is_null($this->get($type . '.DefinitionID'))) { 
     1764                    // fatally error out if definition ID not set 
     1765                    throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID"); 
     1766                } 
     1767            } 
     1768            if (!empty($this->definitions[$type])) { 
     1769                $def = $this->definitions[$type]; 
     1770                if ($def->setup && !$optimized) { 
     1771                    $extra = $this->chatty ? " (try moving this code block earlier in your initialization)" : ""; 
     1772                    throw new HTMLPurifier_Exception("Cannot retrieve raw definition after it has already been setup" . $extra); 
     1773                } 
     1774                if ($def->optimized === null) { 
     1775                    $extra = $this->chatty ? " (try flushing your cache)" : ""; 
     1776                    throw new HTMLPurifier_Exception("Optimization status of definition is unknown" . $extra); 
     1777                } 
     1778                if ($def->optimized !== $optimized) { 
     1779                    $msg = $optimized ? "optimized" : "unoptimized"; 
     1780                    $extra = $this->chatty ? " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" : ""; 
     1781                    throw new HTMLPurifier_Exception("Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra); 
     1782                } 
     1783            } 
     1784            // check if definition was in memory 
     1785            if ($def) { 
     1786                if ($def->setup) { 
     1787                    // invariant: $optimized === true (checked above) 
     1788                    return null; 
     1789                } else { 
     1790                    return $def; 
     1791                } 
     1792            } 
     1793            // if optimized, check if definition was in cache 
     1794            // (because we do the memory check first, this formulation 
     1795            // is prone to cache slamming, but I think 
     1796            // guaranteeing that either /all/ of the raw 
     1797            // setup code or /none/ of it is run is more important.) 
     1798            if ($optimized) { 
     1799                // This code path only gets run once; once we put 
     1800                // something in $definitions (which is guaranteed by the 
     1801                // trailing code), we always short-circuit above. 
     1802                $def = $cache->get($this); 
     1803                if ($def) { 
     1804                    // save the full definition for later, but don't 
     1805                    // return it yet 
     1806                    $this->definitions[$type] = $def; 
     1807                    return null; 
     1808                } 
     1809            } 
     1810            // check invariants for creation 
     1811            if (!$optimized) { 
     1812                if (!is_null($this->get($type . '.DefinitionID'))) { 
     1813                    if ($this->chatty) { 
     1814                        $this->triggerError("Due to a documentation error in previous version of HTML Purifier, your definitions are not being cached.  If this is OK, you can remove the %$type.DefinitionRev and %$type.DefinitionID declaration.  Otherwise, modify your code to use maybeGetRawDefinition, and test if the returned value is null before making any edits (if it is null, that means that a cached version is available, and no raw operations are necessary).  See <a href='http://htmlpurifier.org/docs/enduser-customize.html#optimized'>Customize</a> for more details", E_USER_WARNING); 
     1815                    } else { 
     1816                        $this->triggerError("Useless DefinitionID declaration", E_USER_WARNING); 
     1817                    } 
     1818                } 
     1819            } 
     1820            // initialize it 
     1821            $def = $this->initDefinition($type); 
     1822            $def->optimized = $optimized; 
     1823            return $def; 
     1824        } 
     1825        throw new HTMLPurifier_Exception("The impossible happened!"); 
     1826    } 
     1827 
     1828    private function initDefinition($type) { 
    16701829        // quick checks failed, let's create the object 
    16711830        if ($type == 'HTML') { 
    1672             $this->definitions[$type] = new HTMLPurifier_HTMLDefinition(); 
     1831            $def = new HTMLPurifier_HTMLDefinition(); 
    16731832        } elseif ($type == 'CSS') { 
    1674             $this->definitions[$type] = new HTMLPurifier_CSSDefinition(); 
     1833            $def = new HTMLPurifier_CSSDefinition(); 
    16751834        } elseif ($type == 'URI') { 
    1676             $this->definitions[$type] = new HTMLPurifier_URIDefinition(); 
     1835            $def = new HTMLPurifier_URIDefinition(); 
    16771836        } else { 
    16781837            throw new HTMLPurifier_Exception("Definition of $type type not supported"); 
    16791838        } 
    1680         // quick abort if raw 
    1681         if ($raw) { 
    1682             if (is_null($this->get($type . '.DefinitionID'))) { 
    1683                 // fatally error out if definition ID not set 
    1684                 throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID"); 
    1685             } 
    1686             return $this->definitions[$type]; 
    1687         } 
    1688         // set it up 
    1689         $this->lock = $type; 
    1690         $this->definitions[$type]->setup($this); 
    1691         $this->lock = null; 
    1692         // save in cache 
    1693         $cache->set($this->definitions[$type], $this); 
    1694         return $this->definitions[$type]; 
     1839        $this->definitions[$type] = $def; 
     1840        return $def; 
     1841    } 
     1842 
     1843    public function maybeGetRawDefinition($name) { 
     1844        return $this->getDefinition($name, true, true); 
     1845    } 
     1846 
     1847    public function maybeGetRawHTMLDefinition() { 
     1848        return $this->getDefinition('HTML', true, true); 
     1849    } 
     1850 
     1851    public function maybeGetRawCSSDefinition() { 
     1852        return $this->getDefinition('CSS', true, true); 
     1853    } 
     1854 
     1855    public function maybeGetRawURIDefinition() { 
     1856        return $this->getDefinition('URI', true, true); 
    16951857    } 
    16961858 
     
    18502012    /** 
    18512013     * Produces a nicely formatted error message by supplying the 
    1852      * stack frame information from two levels up and OUTSIDE of 
    1853      * HTMLPurifier_Config. 
     2014     * stack frame information OUTSIDE of HTMLPurifier_Config. 
    18542015     */ 
    18552016    protected function triggerError($msg, $no) { 
    18562017        // determine previous stack frame 
    1857         $backtrace = debug_backtrace(); 
    1858         if ($this->chatty && isset($backtrace[1])) { 
    1859             $frame = $backtrace[1]; 
    1860             $extra = " on line {$frame['line']} in file {$frame['file']}"; 
    1861         } else { 
    1862             $extra = ''; 
     2018        $extra = ''; 
     2019        if ($this->chatty) { 
     2020            $trace = debug_backtrace(); 
     2021            // zip(tail(trace), trace) -- but PHP is not Haskell har har 
     2022            for ($i = 0, $c = count($trace); $i < $c - 1; $i++) { 
     2023                if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') { 
     2024                    continue; 
     2025                } 
     2026                $frame = $trace[$i]; 
     2027                $extra = " invoked on line {$frame['line']} in file {$frame['file']}"; 
     2028                break; 
     2029            } 
    18632030        } 
    18642031        trigger_error($msg . $extra, $no); 
     
    19422109     */ 
    19432110    public static function makeFromSerial() { 
    1944         return unserialize(file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser')); 
     2111        $contents = file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'); 
     2112        $r = unserialize($contents); 
     2113        if (!$r) { 
     2114            $hash = sha1($contents); 
     2115            trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR); 
     2116        } 
     2117        return $r; 
    19452118    } 
    19462119 
     
    38153988 
    38163989    /** 
     3990     * Cache of %Output.FixInnerHTML 
     3991     */ 
     3992    private $_innerHTMLFix; 
     3993 
     3994    /** 
    38173995     * Stack for keeping track of object information when outputting IE 
    38183996     * compatibility code. 
     
    38324010        $this->config = $config; 
    38334011        $this->_scriptFix = $config->get('Output.CommentScriptContents'); 
     4012        $this->_innerHTMLFix = $config->get('Output.FixInnerHTML'); 
    38344013        $this->_sortAttr = $config->get('Output.SortAttr'); 
    38354014        $this->_flashCompat = $config->get('Output.FlashCompat'); 
     
    39104089            if ($this->_flashCompat) { 
    39114090                if ($token->name == "object" && !empty($this->_flashStack)) { 
    3912                     $flash = array_pop($this->_flashStack); 
    3913                     $compat_token = new HTMLPurifier_Token_Empty("embed"); 
    3914                     foreach ($flash->attr as $name => $val) { 
    3915                         if ($name == "classid") continue; 
    3916                         if ($name == "type") continue; 
    3917                         if ($name == "data") $name = "src"; 
    3918                         $compat_token->attr[$name] = $val; 
    3919                     } 
    3920                     foreach ($flash->param as $name => $val) { 
    3921                         if ($name == "movie") $name = "src"; 
    3922                         $compat_token->attr[$name] = $val; 
    3923                     } 
    3924                     $_extra = "<!--[if IE]>".$this->generateFromToken($compat_token)."<![endif]-->"; 
     4091                    // doesn't do anything for now 
    39254092                } 
    39264093            } 
     
    39784145                    $html .= $key . ' '; 
    39794146                    continue; 
     4147                } 
     4148            } 
     4149            // Workaround for Internet Explorer innerHTML bug. 
     4150            // Essentially, Internet Explorer, when calculating 
     4151            // innerHTML, omits quotes if there are no instances of 
     4152            // angled brackets, quotes or spaces.  However, when parsing 
     4153            // HTML (for example, when you assign to innerHTML), it 
     4154            // treats backticks as quotes.  Thus, 
     4155            //      <img alt="``" /> 
     4156            // becomes 
     4157            //      <img alt=`` /> 
     4158            // becomes 
     4159            //      <img alt='' /> 
     4160            // Fortunately, all we need to do is trigger an appropriate 
     4161            // quoting style, which we do by adding an extra space. 
     4162            // This also is consistent with the W3C spec, which states 
     4163            // that user agents may ignore leading or trailing 
     4164            // whitespace (in fact, most don't, at least for attributes 
     4165            // like alt, but an extra space at the end is barely 
     4166            // noticeable).  Still, we have a configuration knob for 
     4167            // this, since this transformation is not necesary if you 
     4168            // don't process user input with innerHTML or you don't plan 
     4169            // on supporting Internet Explorer. 
     4170            if ($this->_innerHTMLFix) { 
     4171                if (strpos($value, '`') !== false) { 
     4172                    // check if correct quoting style would not already be 
     4173                    // triggered 
     4174                    if (strcspn($value, '"\' <>') === strlen($value)) { 
     4175                        // protect! 
     4176                        $value .= ' '; 
     4177                    } 
    39804178                } 
    39814179            } 
     
    48955093        } 
    48965094 
    4897         // add proprietary module (this gets special treatment because 
    4898         // it is completely removed from doctypes, etc.) 
     5095        // custom modules 
    48995096        if ($config->get('HTML.Proprietary')) { 
    49005097            $modules[] = 'Proprietary'; 
    49015098        } 
    4902  
    4903         // add SafeObject/Safeembed modules 
    49045099        if ($config->get('HTML.SafeObject')) { 
    49055100            $modules[] = 'SafeObject'; 
     
    49075102        if ($config->get('HTML.SafeEmbed')) { 
    49085103            $modules[] = 'SafeEmbed'; 
     5104        } 
     5105        if ($config->get('HTML.Nofollow')) { 
     5106            $modules[] = 'Nofollow'; 
    49095107        } 
    49105108 
     
    60916289    protected static function removeIEConditional($string) { 
    60926290        return preg_replace( 
    6093             '#<!--\[if [^>]+\]>.*<!\[endif\]-->#si', // probably should generalize for all strings 
     6291            '#<!--\[if [^>]+\]>.*?<!\[endif\]-->#si', // probably should generalize for all strings 
    60946292            '', 
    60956293            $string 
     
    61296327        } 
    61306328 
    6131         $html = $this->removeIEConditional($html); 
    6132  
    61336329        // escape CDATA 
    61346330        $html = $this->escapeCDATA($html); 
     6331 
     6332        $html = $this->removeIEConditional($html); 
    61356333 
    61366334        // extract body from document if applicable 
     
    68377035        $chars_pchar = $chars_sub_delims . ':@'; 
    68387036 
    6839         // validate scheme (MUST BE FIRST!) 
    6840         if (!is_null($this->scheme) && is_null($this->host)) { 
    6841             $def = $config->getDefinition('URI'); 
    6842             if ($def->defaultScheme === $this->scheme) { 
    6843                 $this->scheme = null; 
    6844             } 
    6845         } 
    6846  
    68477037        // validate host 
    68487038        if (!is_null($this->host)) { 
     
    68527042        } 
    68537043 
     7044        // validate scheme 
     7045        // NOTE: It's not appropriate to check whether or not this 
     7046        // scheme is in our registry, since a URIFilter may convert a 
     7047        // URI that we don't allow into one we do.  So instead, we just 
     7048        // check if the scheme can be dropped because there is no host 
     7049        // and it is our default scheme. 
     7050        if (!is_null($this->scheme) && is_null($this->host) || $this->host === '') { 
     7051            // support for relative paths is pretty abysmal when the 
     7052            // scheme is present, so axe it when possible 
     7053            $def = $config->getDefinition('URI'); 
     7054            if ($def->defaultScheme === $this->scheme) { 
     7055                $this->scheme = null; 
     7056            } 
     7057        } 
     7058 
    68547059        // validate username 
    68557060        if (!is_null($this->userinfo)) { 
     
    68667071        $path_parts = array(); 
    68677072        $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/'); 
    6868         if (!is_null($this->host)) { 
     7073        if (!is_null($this->host)) { // this catches $this->host === '' 
    68697074            // path-abempty (hier and relative) 
     7075            // http://www.example.com/my/path 
     7076            // //www.example.com/my/path (looks odd, but works, and 
     7077            //                            recognized by most browsers) 
     7078            // (this set is valid or invalid on a scheme by scheme 
     7079            // basis, so we'll deal with it later) 
     7080            // file:///my/path 
     7081            // ///my/path 
    68707082            $this->path = $segments_encoder->encode($this->path); 
    6871         } elseif ($this->path !== '' && $this->path[0] === '/') { 
    6872             // path-absolute (hier and relative) 
    6873             if (strlen($this->path) >= 2 && $this->path[1] === '/') { 
    6874                 // This shouldn't ever happen! 
    6875                 $this->path = ''; 
     7083        } elseif ($this->path !== '') { 
     7084            if ($this->path[0] === '/') { 
     7085                // path-absolute (hier and relative) 
     7086                // http:/my/path 
     7087                // /my/path 
     7088                if (strlen($this->path) >= 2 && $this->path[1] === '/') { 
     7089                    // This could happen if both the host gets stripped 
     7090                    // out 
     7091                    // http://my/path 
     7092                    // //my/path 
     7093                    $this->path = ''; 
     7094                } else { 
     7095                    $this->path = $segments_encoder->encode($this->path); 
     7096                } 
     7097            } elseif (!is_null($this->scheme)) { 
     7098                // path-rootless (hier) 
     7099                // http:my/path 
     7100                // Short circuit evaluation means we don't need to check nz 
     7101                $this->path = $segments_encoder->encode($this->path); 
    68767102            } else { 
    6877                 $this->path = $segments_encoder->encode($this->path); 
    6878             } 
    6879         } elseif (!is_null($this->scheme) && $this->path !== '') { 
    6880             // path-rootless (hier) 
    6881             // Short circuit evaluation means we don't need to check nz 
    6882             $this->path = $segments_encoder->encode($this->path); 
    6883         } elseif (is_null($this->scheme) && $this->path !== '') { 
    6884             // path-noscheme (relative) 
    6885             // (once again, not checking nz) 
    6886             $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@'); 
    6887             $c = strpos($this->path, '/'); 
    6888             if ($c !== false) { 
    6889                 $this->path = 
    6890                     $segment_nc_encoder->encode(substr($this->path, 0, $c)) . 
    6891                     $segments_encoder->encode(substr($this->path, $c)); 
    6892             } else { 
    6893                 $this->path = $segment_nc_encoder->encode($this->path); 
     7103                // path-noscheme (relative) 
     7104                // my/path 
     7105                // (once again, not checking nz) 
     7106                $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@'); 
     7107                $c = strpos($this->path, '/'); 
     7108                if ($c !== false) { 
     7109                    $this->path = 
     7110                        $segment_nc_encoder->encode(substr($this->path, 0, $c)) . 
     7111                        $segments_encoder->encode(substr($this->path, $c)); 
     7112                } else { 
     7113                    $this->path = $segment_nc_encoder->encode($this->path); 
     7114                } 
    68947115            } 
    68957116        } else { 
     
    69207141        // reconstruct authority 
    69217142        $authority = null; 
     7143        // there is a rendering difference between a null authority 
     7144        // (http:foo-bar) and an empty string authority 
     7145        // (http:///foo-bar). 
    69227146        if (!is_null($this->host)) { 
    69237147            $authority = ''; 
     
    69277151        } 
    69287152 
    6929         // reconstruct the result 
     7153        // Reconstruct the result 
     7154        // One might wonder about parsing quirks from browsers after 
     7155        // this reconstruction.  Unfortunately, parsing behavior depends 
     7156        // on what *scheme* was employed (file:///foo is handled *very* 
     7157        // differently than http:///foo), so unfortunately we have to 
     7158        // defer to the schemes to do the right thing. 
    69307159        $result = ''; 
    69317160        if (!is_null($this->scheme))    $result .= $this->scheme . ':'; 
     
    71587387 * Validator for the components of a URI for a specific scheme 
    71597388 */ 
    7160 class HTMLPurifier_URIScheme 
    7161 { 
    7162  
    7163     /** 
    7164      * Scheme's default port (integer) 
     7389abstract class HTMLPurifier_URIScheme 
     7390{ 
     7391 
     7392    /** 
     7393     * Scheme's default port (integer).  If an explicit port number is 
     7394     * specified that coincides with the default port, it will be 
     7395     * elided. 
    71657396     */ 
    71667397    public $default_port = null; 
     
    71797410 
    71807411    /** 
    7181      * Validates the components of a URI 
    7182      * @note This implementation should be called by children if they define 
    7183      *       a default port, as it does port processing. 
    7184      * @param $uri Instance of HTMLPurifier_URI 
     7412     * Whether or not the URI may omit a hostname when the scheme is 
     7413     * explicitly specified, ala file:///path/to/file. As of writing, 
     7414     * 'file' is the only scheme that browsers support his properly. 
     7415     */ 
     7416    public $may_omit_host = false; 
     7417 
     7418    /** 
     7419     * Validates the components of a URI for a specific scheme. 
     7420     * @param $uri Reference to a HTMLPurifier_URI object 
    71857421     * @param $config HTMLPurifier_Config object 
    71867422     * @param $context HTMLPurifier_Context object 
    71877423     * @return Bool success or failure 
    71887424     */ 
     7425    public abstract function doValidate(&$uri, $config, $context); 
     7426 
     7427    /** 
     7428     * Public interface for validating components of a URI.  Performs a 
     7429     * bunch of default actions. Don't overload this method. 
     7430     * @param $uri Reference to a HTMLPurifier_URI object 
     7431     * @param $config HTMLPurifier_Config object 
     7432     * @param $context HTMLPurifier_Context object 
     7433     * @return Bool success or failure 
     7434     */ 
    71897435    public function validate(&$uri, $config, $context) { 
    71907436        if ($this->default_port == $uri->port) $uri->port = null; 
    7191         return true; 
     7437        // kludge: browsers do funny things when the scheme but not the 
     7438        // authority is set 
     7439        if (!$this->may_omit_host && 
     7440            // if the scheme is present, a missing host is always in error 
     7441            (!is_null($uri->scheme) && ($uri->host === '' || is_null($uri->host))) || 
     7442            // if the scheme is not present, a *blank* host is in error, 
     7443            // since this translates into '///path' which most browsers 
     7444            // interpret as being 'http://path'. 
     7445             (is_null($uri->scheme) && $uri->host === '') 
     7446        ) { 
     7447            do { 
     7448                if (is_null($uri->scheme)) { 
     7449                    if (substr($uri->path, 0, 2) != '//') { 
     7450                        $uri->host = null; 
     7451                        break; 
     7452                    } 
     7453                    // URI is '////path', so we cannot nullify the 
     7454                    // host to preserve semantics.  Try expanding the 
     7455                    // hostname instead (fall through) 
     7456                } 
     7457                // first see if we can manually insert a hostname 
     7458                $host = $config->get('URI.Host'); 
     7459                if (!is_null($host)) { 
     7460                    $uri->host = $host; 
     7461                } else { 
     7462                    // we can't do anything sensible, reject the URL. 
     7463                    return false; 
     7464                } 
     7465            } while (false); 
     7466        } 
     7467        return $this->doValidate($uri, $config, $context); 
    71927468    } 
    71937469 
     
    88329108/** 
    88339109 * Validates a font family list according to CSS spec 
    8834  * @todo whitelisting allowed fonts would be nice 
    88359110 */ 
    88369111class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef 
    88379112{ 
     9113 
     9114    protected $mask = null; 
     9115 
     9116    public function __construct() { 
     9117        $this->mask = '- '; 
     9118        for ($c = 'a'; $c <= 'z'; $c++) $this->mask .= $c; 
     9119        for ($c = 'A'; $c <= 'Z'; $c++) $this->mask .= $c; 
     9120        for ($c = '0'; $c <= '9'; $c++) $this->mask .= $c; // cast-y, but should be fine 
     9121        // special bytes used by UTF-8 
     9122        for ($i = 0x80; $i <= 0xFF; $i++) { 
     9123            // We don't bother excluding invalid bytes in this range, 
     9124            // because the our restriction of well-formed UTF-8 will 
     9125            // prevent these from ever occurring. 
     9126            $this->mask .= chr($i); 
     9127        } 
     9128 
     9129        /* 
     9130            PHP's internal strcspn implementation is 
     9131            O(length of string * length of mask), making it inefficient 
     9132            for large masks.  However, it's still faster than 
     9133            preg_match 8) 
     9134          for (p = s1;;) { 
     9135            spanp = s2; 
     9136            do { 
     9137              if (*spanp == c || p == s1_end) { 
     9138                return p - s1; 
     9139              } 
     9140            } while (spanp++ < (s2_end - 1)); 
     9141            c = *++p; 
     9142          } 
     9143         */ 
     9144        // possible optimization: invert the mask. 
     9145    } 
    88389146 
    88399147    public function validate($string, $config, $context) { 
     
    88459153            'cursive' => true 
    88469154        ); 
     9155        $allowed_fonts = $config->get('CSS.AllowedFonts'); 
    88479156 
    88489157        // assume that no font names contain commas in them 
     
    88549163            // match a generic name 
    88559164            if (isset($generic_names[$font])) { 
    8856                 $final .= $font . ', '; 
     9165                if ($allowed_fonts === null || isset($allowed_fonts[$font])) { 
     9166                    $final .= $font . ', '; 
     9167                } 
    88579168                continue; 
    88589169            } 
     
    88709181            // $font is a pure representation of the font name 
    88719182 
     9183            if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) { 
     9184                continue; 
     9185            } 
     9186 
    88729187            if (ctype_alnum($font) && $font !== '') { 
    88739188                // very simple font, allow it in unharmed 
     
    88809195            $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font); 
    88819196 
    8882             // These ugly transforms don't pose a security 
    8883             // risk (as \\ and \" might).  We could try to be clever and 
    8884             // use single-quote wrapping when there is a double quote 
    8885             // present, but I have choosen not to implement that. 
    8886             // (warning: this code relies on the selection of quotation 
    8887             // mark below) 
    8888             $font = str_replace('\\', '\\5C ', $font); 
    8889             $font = str_replace('"',  '\\22 ', $font); 
    8890  
    8891             // complicated font, requires quoting 
    8892             $final .= "\"$font\", "; // note that this will later get turned into &quot; 
     9197            // Here, there are various classes of characters which need 
     9198            // to be treated differently: 
     9199            //  - Alphanumeric characters are essentially safe.  We 
     9200            //    handled these above. 
     9201            //  - Spaces require quoting, though most parsers will do 
     9202            //    the right thing if there aren't any characters that 
     9203            //    can be misinterpreted 
     9204            //  - Dashes rarely occur, but they fairly unproblematic 
     9205            //    for parsing/rendering purposes. 
     9206            //  The above characters cover the majority of Western font 
     9207            //  names. 
     9208            //  - Arbitrary Unicode characters not in ASCII.  Because 
     9209            //    most parsers give little thought to Unicode, treatment 
     9210            //    of these codepoints is basically uniform, even for 
     9211            //    punctuation-like codepoints.  These characters can 
     9212            //    show up in non-Western pages and are supported by most 
     9213            //    major browsers, for example: "MS 明朝" is a 
     9214            //    legitimate font-name 
     9215            //    <http://ja.wikipedia.org/wiki/MS_明朝>.  See 
     9216            //    the CSS3 spec for more examples: 
     9217            //    <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png> 
     9218            //    You can see live samples of these on the Internet: 
     9219            //    <http://www.google.co.jp/search?q=font-family+MS+明朝|ゴシック> 
     9220            //    However, most of these fonts have ASCII equivalents: 
     9221            //    for example, 'MS Mincho', and it's considered 
     9222            //    professional to use ASCII font names instead of 
     9223            //    Unicode font names.  Thanks Takeshi Terada for 
     9224            //    providing this information. 
     9225            //  The following characters, to my knowledge, have not been 
     9226            //  used to name font names. 
     9227            //  - Single quote.  While theoretically you might find a 
     9228            //    font name that has a single quote in its name (serving 
     9229            //    as an apostrophe, e.g. Dave's Scribble), I haven't 
     9230            //    been able to find any actual examples of this. 
     9231            //    Internet Explorer's cssText translation (which I 
     9232            //    believe is invoked by innerHTML) normalizes any 
     9233            //    quoting to single quotes, and fails to escape single 
     9234            //    quotes.  (Note that this is not IE's behavior for all 
     9235            //    CSS properties, just some sort of special casing for 
     9236            //    font-family).  So a single quote *cannot* be used 
     9237            //    safely in the font-family context if there will be an 
     9238            //    innerHTML/cssText translation.  Note that Firefox 3.x 
     9239            //    does this too. 
     9240            //  - Double quote.  In IE, these get normalized to 
     9241            //    single-quotes, no matter what the encoding.  (Fun 
     9242            //    fact, in IE8, the 'content' CSS property gained 
     9243            //    support, where they special cased to preserve encoded 
     9244            //    double quotes, but still translate unadorned double 
     9245            //    quotes into single quotes.)  So, because their 
     9246            //    fixpoint behavior is identical to single quotes, they 
     9247            //    cannot be allowed either.  Firefox 3.x displays 
     9248            //    single-quote style behavior. 
     9249            //  - Backslashes are reduced by one (so \\ -> \) every 
     9250            //    iteration, so they cannot be used safely.  This shows 
     9251            //    up in IE7, IE8 and FF3 
     9252            //  - Semicolons, commas and backticks are handled properly. 
     9253            //  - The rest of the ASCII punctuation is handled properly. 
     9254            // We haven't checked what browsers do to unadorned 
     9255            // versions, but this is not important as long as the 
     9256            // browser doesn't /remove/ surrounding quotes (as IE does 
     9257            // for HTML). 
     9258            // 
     9259            // With these results in hand, we conclude that there are 
     9260            // various levels of safety: 
     9261            //  - Paranoid: alphanumeric, spaces and dashes(?) 
     9262            //  - International: Paranoid + non-ASCII Unicode 
     9263            //  - Edgy: Everything except quotes, backslashes 
     9264            //  - NoJS: Standards compliance, e.g. sod IE. Note that 
     9265            //    with some judicious character escaping (since certain 
     9266            //    types of escaping doesn't work) this is theoretically 
     9267            //    OK as long as innerHTML/cssText is not called. 
     9268            // We believe that international is a reasonable default 
     9269            // (that we will implement now), and once we do more 
     9270            // extensive research, we may feel comfortable with dropping 
     9271            // it down to edgy. 
     9272 
     9273            // Edgy: alphanumeric, spaces, dashes and Unicode.  Use of 
     9274            // str(c)spn assumes that the string was already well formed 
     9275            // Unicode (which of course it is). 
     9276            if (strspn($font, $this->mask) !== strlen($font)) { 
     9277                continue; 
     9278            } 
     9279 
     9280            // Historical: 
     9281            // In the absence of innerHTML/cssText, these ugly 
     9282            // transforms don't pose a security risk (as \\ and \" 
     9283            // might--these escapes are not supported by most browsers). 
     9284            // We could try to be clever and use single-quote wrapping 
     9285            // when there is a double quote present, but I have choosen 
     9286            // not to implement that.  (NOTE: you can reduce the amount 
     9287            // of escapes by one depending on what quoting style you use) 
     9288            // $font = str_replace('\\', '\\5C ', $font); 
     9289            // $font = str_replace('"',  '\\22 ', $font); 
     9290            // $font = str_replace("'",  '\\27 ', $font); 
     9291 
     9292            // font possibly with spaces, requires quoting 
     9293            $final .= "'$font', "; 
    88939294        } 
    88949295        $final = rtrim($final, ', '); 
     
    92539654        $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); 
    92549655 
     9656        // suspicious characters are ()'; we're going to percent encode 
     9657        // them for safety. 
     9658        $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result); 
     9659 
     9660        // there's an extra bug where ampersands lose their escaping on 
     9661        // an innerHTML cycle, so a very unlucky query parameter could 
     9662        // then change the meaning of the URL.  Unfortunately, there's 
     9663        // not much we can do about that... 
     9664 
    92559665        return "url(\"$result\")"; 
    92569666 
     
    973410144    public function validate($string, $config, $context) { 
    973510145        $length = strlen($string); 
     10146        // empty hostname is OK; it's usually semantically equivalent: 
     10147        // the default host as defined by a URI scheme is used: 
     10148        // 
     10149        //      If the URI scheme defines a default for host, then that 
     10150        //      default applies when the host subcomponent is undefined 
     10151        //      or when the registered name is empty (zero length). 
    973610152        if ($string === '') return ''; 
    973710153        if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') { 
     
    1035610772 
    1035710773 
     10774// must be called POST validation 
     10775 
     10776/** 
     10777 * Adds rel="nofollow" to all outbound links.  This transform is 
     10778 * only attached if Attr.Nofollow is TRUE. 
     10779 */ 
     10780class HTMLPurifier_AttrTransform_Nofollow extends HTMLPurifier_AttrTransform 
     10781{ 
     10782    private $parser; 
     10783 
     10784    public function __construct() { 
     10785        $this->parser = new HTMLPurifier_URIParser(); 
     10786    } 
     10787 
     10788    public function transform($attr, $config, $context) { 
     10789 
     10790        if (!isset($attr['href'])) { 
     10791            return $attr; 
     10792        } 
     10793 
     10794        // XXX Kind of inefficient 
     10795        $url = $this->parser->parse($attr['href']); 
     10796        $scheme = $url->getSchemeObj($config, $context); 
     10797 
     10798        if (!is_null($url->host) && $scheme !== false && $scheme->browsable) { 
     10799            if (isset($attr['rel'])) { 
     10800                $attr['rel'] .= ' nofollow'; 
     10801            } else { 
     10802                $attr['rel'] = 'nofollow'; 
     10803            } 
     10804        } 
     10805 
     10806        return $attr; 
     10807 
     10808    } 
     10809 
     10810} 
     10811 
     10812 
     10813 
     10814 
     10815 
    1035810816class HTMLPurifier_AttrTransform_SafeEmbed extends HTMLPurifier_AttrTransform 
    1035910817{ 
     
    1040810866    public function __construct() { 
    1040910867        $this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded 
     10868        $this->wmode = new HTMLPurifier_AttrDef_Enum(array('window', 'opaque', 'transparent')); 
    1041010869    } 
    1041110870 
     
    1043010889                break; 
    1043110890            case 'wmode': 
    10432                 $attr['value'] = 'window'; 
     10891                $attr['value'] = $this->wmode->validate($attr['value'], $config, $context); 
    1043310892                break; 
    1043410893            case 'movie': 
     
    1113911598        if (file_exists($file)) return false; 
    1114011599        if (!$this->_prepareDir($config)) return false; 
    11141         return $this->_write($file, serialize($def)); 
     11600        return $this->_write($file, serialize($def), $config); 
    1114211601    } 
    1114311602 
     
    1114611605        $file = $this->generateFilePath($config); 
    1114711606        if (!$this->_prepareDir($config)) return false; 
    11148         return $this->_write($file, serialize($def)); 
     11607        return $this->_write($file, serialize($def), $config); 
    1114911608    } 
    1115011609 
     
    1115411613        if (!file_exists($file)) return false; 
    1115511614        if (!$this->_prepareDir($config)) return false; 
    11156         return $this->_write($file, serialize($def)); 
     11615        return $this->_write($file, serialize($def), $config); 
    1115711616    } 
    1115811617 
     
    1122711686     * @param $file File name to write to 
    1122811687     * @param $data Data to write into file 
     11688     * @param $config Config object 
    1122911689     * @return Number of bytes written if success, or false if failure. 
    1123011690     */ 
    11231     private function _write($file, $data) { 
    11232         return file_put_contents($file, $data); 
     11691    private function _write($file, $data, $config) { 
     11692        $result = file_put_contents($file, $data); 
     11693        if ($result !== false) { 
     11694            // set permissions of the new file (no execute) 
     11695            $chmod = $config->get('Cache.SerializerPermissions'); 
     11696            if (!$chmod) { 
     11697                $chmod = 0644; // invalid config or simpletest 
     11698            } 
     11699            $chmod = $chmod & 0666; 
     11700            chmod($file, $chmod); 
     11701        } 
     11702        return $result; 
    1123311703    } 
    1123411704 
    1123511705    /** 
    1123611706     * Prepares the directory that this type stores the serials in 
     11707     * @param $config Config object 
    1123711708     * @return True if successful 
    1123811709     */ 
    1123911710    private function _prepareDir($config) { 
    1124011711        $directory = $this->generateDirectoryPath($config); 
     11712        $chmod = $config->get('Cache.SerializerPermissions'); 
     11713        if (!$chmod) { 
     11714            $chmod = 0755; // invalid config or simpletest 
     11715        } 
    1124111716        if (!is_dir($directory)) { 
    1124211717            $base = $this->generateBaseDirectoryPath($config); 
     
    1124611721                    E_USER_WARNING); 
    1124711722                return false; 
    11248             } elseif (!$this->_testPermissions($base)) { 
     11723            } elseif (!$this->_testPermissions($base, $chmod)) { 
    1124911724                return false; 
    1125011725            } 
    11251             $old = umask(0022); // disable group and world writes 
    11252             mkdir($directory); 
     11726            $old = umask(0000); 
     11727            mkdir($directory, $chmod); 
    1125311728            umask($old); 
    11254         } elseif (!$this->_testPermissions($directory)) { 
     11729        } elseif (!$this->_testPermissions($directory, $chmod)) { 
    1125511730            return false; 
    1125611731        } 
     
    1126111736     * Tests permissions on a directory and throws out friendly 
    1126211737     * error messages and attempts to chmod it itself if possible 
    11263      */ 
    11264     private function _testPermissions($dir) { 
     11738     * @param $dir Directory path 
     11739     * @param $chmod Permissions 
     11740     * @return True if directory writable 
     11741     */ 
     11742    private function _testPermissions($dir, $chmod) { 
    1126511743        // early abort, if it is writable, everything is hunky-dory 
    1126611744        if (is_writable($dir)) return true; 
     
    1127611754            if (fileowner($dir) === posix_getuid()) { 
    1127711755                // we can chmod it ourselves 
    11278                 chmod($dir, 0755); 
    11279                 return true; 
     11756                $chmod = $chmod | 0700; 
     11757                if (chmod($dir, $chmod)) return true; 
    1128011758            } elseif (filegroup($dir) === posix_getgid()) { 
    11281                 $chmod = '775'; 
     11759                $chmod = $chmod | 0070; 
    1128211760            } else { 
    1128311761                // PHP's probably running as nobody, so we'll 
    1128411762                // need to give global permissions 
    11285                 $chmod = '777'; 
     11763                $chmod = $chmod | 0777; 
    1128611764            } 
    1128711765            trigger_error('Directory '.$dir.' not writable, '. 
    11288                 'please chmod to ' . $chmod, 
     11766                'please chmod to ' . decoct($chmod), 
    1128911767                E_USER_WARNING); 
    1129011768        } else { 
     
    1188812366 
    1188912367 
     12368/** 
     12369 * Module adds the nofollow attribute transformation to a tags.  It 
     12370 * is enabled by HTML.Nofollow 
     12371 */ 
     12372class HTMLPurifier_HTMLModule_Nofollow extends HTMLPurifier_HTMLModule 
     12373{ 
     12374 
     12375    public $name = 'Nofollow'; 
     12376 
     12377    public function setup($config) { 
     12378        $a = $this->addBlankElement('a'); 
     12379        $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_Nofollow(); 
     12380    } 
     12381 
     12382} 
     12383 
     12384 
     12385 
     12386 
     12387 
    1189012388class HTMLPurifier_HTMLModule_NonXMLCommonAttributes extends HTMLPurifier_HTMLModule 
    1189112389{ 
     
    1207112569                'allownetworking' => 'Enum#internal', 
    1207212570                'flashvars' => 'Text', 
    12073                 'wmode' => 'Enum#window', 
     12571                'wmode' => 'Enum#window,transparent,opaque', 
    1207412572                'name' => 'ID', 
    1207512573            ) 
     
    1211412612                'height' => 'Pixels#' . $max, 
    1211512613                'data'   => 'URI#embedded', 
    12116                 'classid' => 'Enum#clsid:d27cdb6e-ae6d-11cf-96b8-444553540000', 
    1211712614                'codebase' => new HTMLPurifier_AttrDef_Enum(array( 
    1211812615                    'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0')), 
     
    1361014107 
    1361114108    /** 
    13612      * Recursive function that tokenizes a node, putting it into an accumulator. 
    13613      * 
     14109     * Iterative function that tokenizes a node, putting it into an accumulator. 
     14110     * To iterate is human, to recurse divine - L. Peter Deutsch 
    1361414111     * @param $node     DOMNode to be tokenized. 
    1361514112     * @param $tokens   Array-list of already tokenized tokens. 
     14113     * @returns Tokens of node appended to previously passed tokens. 
     14114     */ 
     14115    protected function tokenizeDOM($node, &$tokens) { 
     14116 
     14117        $level = 0; 
     14118        $nodes = array($level => array($node)); 
     14119        $closingNodes = array(); 
     14120        do { 
     14121            while (!empty($nodes[$level])) { 
     14122                $node = array_shift($nodes[$level]); // FIFO 
     14123                $collect = $level > 0 ? true : false; 
     14124                $needEndingTag = $this->createStartNode($node, $tokens, $collect); 
     14125                if ($needEndingTag) { 
     14126                    $closingNodes[$level][] = $node; 
     14127                } 
     14128                if ($node->childNodes && $node->childNodes->length) { 
     14129                    $level++; 
     14130                    $nodes[$level] = array(); 
     14131                    foreach ($node->childNodes as $childNode) { 
     14132                        array_push($nodes[$level], $childNode); 
     14133                    } 
     14134                } 
     14135            } 
     14136            $level--; 
     14137            if ($level && isset($closingNodes[$level])) { 
     14138                while($node = array_pop($closingNodes[$level])) { 
     14139                    $this->createEndNode($node, $tokens); 
     14140                } 
     14141            } 
     14142        } while ($level > 0); 
     14143    } 
     14144 
     14145    /** 
     14146     * @param $node  DOMNode to be tokenized. 
     14147     * @param $tokens   Array-list of already tokenized tokens. 
    1361614148     * @param $collect  Says whether or start and close are collected, set to 
    13617      *                  false at first recursion because it's the implicit DIV 
    13618      *                  tag you're dealing with. 
    13619      * @returns Tokens of node appended to previously passed tokens. 
    13620      */ 
    13621     protected function tokenizeDOM($node, &$tokens, $collect = false) { 
    13622  
     14149     *                    false at first recursion because it's the implicit DIV 
     14150     *                    tag you're dealing with. 
     14151     * @returns bool if the token needs an endtoken 
     14152     */ 
     14153    protected function createStartNode($node, &$tokens, $collect) { 
    1362314154        // intercept non element nodes. WE MUST catch all of them, 
    1362414155        // but we're not getting the character reference nodes because 
     
    1362614157        if ($node->nodeType === XML_TEXT_NODE) { 
    1362714158            $tokens[] = $this->factory->createText($node->data); 
    13628             return; 
     14159            return false; 
    1362914160        } elseif ($node->nodeType === XML_CDATA_SECTION_NODE) { 
    1363014161            // undo libxml's special treatment of <script> and <style> tags 
     
    1364414175            } 
    1364514176            $tokens[] = $this->factory->createText($this->parseData($data)); 
    13646             return; 
     14177            return false; 
    1364714178        } elseif ($node->nodeType === XML_COMMENT_NODE) { 
    1364814179            // this is code is only invoked for comments in script/style in versions 
     
    1365014181            // handled regularly) 
    1365114182            $tokens[] = $this->factory->createComment($node->data); 
    13652             return; 
     14183            return false; 
    1365314184        } elseif ( 
    1365414185            // not-well tested: there may be other nodes we have to grab 
    1365514186            $node->nodeType !== XML_ELEMENT_NODE 
    1365614187        ) { 
    13657             return; 
    13658         } 
    13659  
    13660         $attr = $node->hasAttributes() ? 
    13661             $this->transformAttrToAssoc($node->attributes) : 
    13662             array(); 
     14188            return false; 
     14189        } 
     14190 
     14191        $attr = $node->hasAttributes() ? $this->transformAttrToAssoc($node->attributes) : array(); 
    1366314192 
    1366414193        // We still have to make sure that the element actually IS empty 
     
    1366714196                $tokens[] = $this->factory->createEmpty($node->tagName, $attr); 
    1366814197            } 
     14198            return false; 
    1366914199        } else { 
    13670             if ($collect) { // don't wrap on first iteration 
     14200            if ($collect) { 
    1367114201                $tokens[] = $this->factory->createStart( 
    1367214202                    $tag_name = $node->tagName, // somehow, it get's dropped 
     
    1367414204                ); 
    1367514205            } 
    13676             foreach ($node->childNodes as $node) { 
    13677                 // remember, it's an accumulator. Otherwise, we'd have 
    13678                 // to use array_merge 
    13679                 $this->tokenizeDOM($node, $tokens, true); 
    13680             } 
    13681             if ($collect) { 
    13682                 $tokens[] = $this->factory->createEnd($tag_name); 
    13683             } 
    13684         } 
    13685  
    13686     } 
     14206            return true; 
     14207        } 
     14208    } 
     14209 
     14210    protected function createEndNode($node, &$tokens) { 
     14211        $tokens[] = $this->factory->createEnd($node->tagName); 
     14212    } 
     14213 
    1368714214 
    1368814215    /** 
     
    1461915146/** 
    1462015147 * Takes tokens makes them well-formed (balance end tags, etc.) 
     15148 * 
     15149 * Specification of the armor attributes this strategy uses: 
     15150 * 
     15151 *      - MakeWellFormed_TagClosedError: This armor field is used to 
     15152 *        suppress tag closed errors for certain tokens [TagClosedSuppress], 
     15153 *        in particular, if a tag was generated automatically by HTML 
     15154 *        Purifier, we may rely on our infrastructure to close it for us 
     15155 *        and shouldn't report an error to the user [TagClosedAuto]. 
    1462115156 */ 
    1462215157class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy 
     
    1466015195        $generator = new HTMLPurifier_Generator($config, $context); 
    1466115196        $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); 
     15197        // used for autoclose early abortion 
     15198        $global_parent_allowed_elements = array(); 
     15199        if (isset($definition->info[$definition->info_parent])) { 
     15200            // may be unset under testing circumstances 
     15201            $global_parent_allowed_elements = $definition->info[$definition->info_parent]->child->getAllowedElements($config); 
     15202        } 
    1466215203        $e = $context->get('ErrorCollector', true); 
    1466315204        $t = false; // token index 
     
    1471915260        // -- end INJECTOR -- 
    1472015261 
    14721         // a note on punting: 
     15262        // a note on reprocessing: 
    1472215263        //      In order to reduce code duplication, whenever some code needs 
    1472315264        //      to make HTML changes in order to make things "correct", the 
     
    1476615307                $this->stack[] = $top_nesting; 
    1476715308 
    14768                 // send error 
     15309                // send error [TagClosedSuppress] 
    1476915310                if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) { 
    1477015311                    $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting); 
     
    1481015351            if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) { 
    1481115352                // claims to be a start tag but is empty 
    14812                 $token = new HTMLPurifier_Token_Empty($token->name, $token->attr); 
     15353                $token = new HTMLPurifier_Token_Empty($token->name, $token->attr, $token->line, $token->col, $token->armor); 
    1481315354                $ok = true; 
    1481415355            } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) { 
    1481515356                // claims to be empty but really is a start tag 
    1481615357                $this->swap(new HTMLPurifier_Token_End($token->name)); 
    14817                 $this->insertBefore(new HTMLPurifier_Token_Start($token->name, $token->attr)); 
     15358                $this->insertBefore(new HTMLPurifier_Token_Start($token->name, $token->attr, $token->line, $token->col, $token->armor)); 
    1481815359                // punt (since we had to modify the input stream in a non-trivial way) 
    1481915360                $reprocess = true; 
     
    1482715368                // ...unless they also have to close their parent 
    1482815369                if (!empty($this->stack)) { 
     15370 
     15371                    // Performance note: you might think that it's rather 
     15372                    // inefficient, recalculating the autoclose information 
     15373                    // for every tag that a token closes (since when we 
     15374                    // do an autoclose, we push a new token into the 
     15375                    // stream and then /process/ that, before 
     15376                    // re-processing this token.)  But this is 
     15377                    // necessary, because an injector can make an 
     15378                    // arbitrary transformations to the autoclosing 
     15379                    // tokens we introduce, so things may have changed 
     15380                    // in the meantime.  Also, doing the inefficient thing is 
     15381                    // "easy" to reason about (for certain perverse definitions 
     15382                    // of "easy") 
    1482915383 
    1483015384                    $parent = array_pop($this->stack); 
     
    1486015414 
    1486115415                    if ($autoclose) { 
    14862                         // errors need to be updated 
    14863                         $new_token = new HTMLPurifier_Token_End($parent->name); 
    14864                         $new_token->start = $parent; 
    14865                         if ($carryover) { 
    14866                             $element = clone $parent; 
    14867                             $element->armor['MakeWellFormed_TagClosedError'] = true; 
    14868                             $element->carryover = true; 
    14869                             $this->processToken(array($new_token, $token, $element)); 
     15416                        // check if this autoclose is doomed to fail 
     15417                        // (this rechecks $parent, which his harmless) 
     15418                        $autoclose_ok = isset($global_parent_allowed_elements[$token->name]); 
     15419                        if (!$autoclose_ok) { 
     15420                            foreach ($this->stack as $ancestor) { 
     15421                                $elements = $definition->info[$ancestor->name]->child->getAllowedElements($config); 
     15422                                if (isset($elements[$token->name])) { 
     15423                                    $autoclose_ok = true; 
     15424                                    break; 
     15425                                } 
     15426                                if ($definition->info[$token->name]->wrap) { 
     15427                                    $wrapname = $definition->info[$token->name]->wrap; 
     15428                                    $wrapdef = $definition->info[$wrapname]; 
     15429                                    $wrap_elements = $wrapdef->child->getAllowedElements($config); 
     15430                                    if (isset($wrap_elements[$token->name]) && isset($elements[$wrapname])) { 
     15431                                        $autoclose_ok = true; 
     15432                                        break; 
     15433                                    } 
     15434                                } 
     15435                            } 
     15436                        } 
     15437                        if ($autoclose_ok) { 
     15438                            // errors need to be updated 
     15439                            $new_token = new HTMLPurifier_Token_End($parent->name); 
     15440                            $new_token->start = $parent; 
     15441                            if ($carryover) { 
     15442                                $element = clone $parent; 
     15443                                // [TagClosedAuto] 
     15444                                $element->armor['MakeWellFormed_TagClosedError'] = true; 
     15445                                $element->carryover = true; 
     15446                                $this->processToken(array($new_token, $token, $element)); 
     15447                            } else { 
     15448                                $this->insertBefore($new_token); 
     15449                            } 
     15450                            // [TagClosedSuppress] 
     15451                            if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) { 
     15452                                if (!$carryover) { 
     15453                                    $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent); 
     15454                                } else { 
     15455                                    $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent); 
     15456                                } 
     15457                            } 
    1487015458                        } else { 
    14871                             $this->insertBefore($new_token); 
    14872                         } 
    14873                         if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) { 
    14874                             if (!$carryover) { 
    14875                                 $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent); 
    14876                             } else { 
    14877                                 $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent); 
    14878                             } 
     15459                            $this->remove(); 
    1487915460                        } 
    1488015461                        $reprocess = true; 
     
    1498315564                for ($j = $c - 1; $j > 0; $j--) { 
    1498415565                    // notice we exclude $j == 0, i.e. the current ending tag, from 
    14985                     // the errors... 
     15566                    // the errors... [TagClosedSuppress] 
    1498615567                    if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) { 
    1498715568                        $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]); 
     
    1499815579                array_unshift($replace, $new_token); 
    1499915580                if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) { 
     15581                    // [TagClosedAuto] 
    1500015582                    $element = clone $skipped_tags[$j]; 
    1500115583                    $element->carryover = true; 
     
    1506615648 
    1506715649    /** 
    15068      * Inserts a token before the current token. Cursor now points to this token 
     15650     * Inserts a token before the current token. Cursor now points to 
     15651     * this token.  You must reprocess after this. 
    1506915652     */ 
    1507015653    private function insertBefore($token) { 
     
    1507415657    /** 
    1507515658     * Removes current token. Cursor now points to new token occupying previously 
    15076      * occupied space. 
     15659     * occupied space.  You must reprocess after this. 
    1507715660     */ 
    1507815661    private function remove() { 
     
    1508115664 
    1508215665    /** 
    15083      * Swap current token with new token. Cursor points to new token (no change). 
     15666     * Swap current token with new token. Cursor points to new token (no 
     15667     * change).  You must reprocess after this. 
    1508415668     */ 
    1508515669    private function swap($token) { 
     
    1536815952        if (isset($attr['size'])) { 
    1536915953            // normalize large numbers 
    15370             if ($attr['size']{0} == '+' || $attr['size']{0} == '-') { 
    15371                 $size = (int) $attr['size']; 
    15372                 if ($size < -2) $attr['size'] = '-2'; 
    15373                 if ($size > 4)  $attr['size'] = '+4'; 
    15374             } else { 
    15375                 $size = (int) $attr['size']; 
    15376                 if ($size > 7) $attr['size'] = '7'; 
     15954            if ($attr['size'] !== '') { 
     15955                if ($attr['size']{0} == '+' || $attr['size']{0} == '-') { 
     15956                    $size = (int) $attr['size']; 
     15957                    if ($size < -2) $attr['size'] = '-2'; 
     15958                    if ($size > 4)  $attr['size'] = '+4'; 
     15959                } else { 
     15960                    $size = (int) $attr['size']; 
     15961                    if ($size > 7) $attr['size'] = '7'; 
     15962                } 
    1537715963            } 
    1537815964            if (isset($this->_size_lookup[$attr['size']])) { 
     
    1549416080     * @param $attr Associative array of attributes. 
    1549516081     */ 
    15496     public function __construct($name, $attr = array(), $line = null, $col = null) { 
     16082    public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) { 
    1549716083        $this->name = ctype_lower($name) ? $name : strtolower($name); 
    1549816084        foreach ($attr as $key => $value) { 
     
    1551116097        $this->line = $line; 
    1551216098        $this->col  = $col; 
     16099        $this->armor = $armor; 
    1551316100    } 
    1551416101} 
     
    1585416441        'image/png' => true, 
    1585516442        ); 
    15856  
    15857     public function validate(&$uri, $config, $context) { 
     16443    // this is actually irrelevant since we only write out the path 
     16444    // component 
     16445    public $may_omit_host = true; 
     16446 
     16447    public function doValidate(&$uri, $config, $context) { 
    1585816448        $result = explode(',', $uri->path, 2); 
    1585916449        $is_base64 = false; 
     
    1594416534    public $browsable = false; 
    1594516535 
    15946     public function validate(&$uri, $config, $context) { 
    15947         parent::validate($uri, $config, $context); 
     16536    // Basically the *only* URI scheme for which this is true, since 
     16537    // accessing files on the local machine is very common.  In fact, 
     16538    // browsers on some operating systems don't understand the 
     16539    // authority, though I hear it is used on Windows to refer to 
     16540    // network shares. 
     16541    public $may_omit_host = true; 
     16542 
     16543    public function doValidate(&$uri, $config, $context) { 
    1594816544        // Authentication method is not supported 
    1594916545        $uri->userinfo = null; 
     
    1597116567    public $hierarchical = true; 
    1597216568 
    15973     public function validate(&$uri, $config, $context) { 
    15974         parent::validate($uri, $config, $context); 
     16569    public function doValidate(&$uri, $config, $context) { 
    1597516570        $uri->query    = null; 
    1597616571 
     
    1601516610    public $hierarchical = true; 
    1601616611 
    16017     public function validate(&$uri, $config, $context) { 
    16018         parent::validate($uri, $config, $context); 
     16612    public function doValidate(&$uri, $config, $context) { 
    1601916613        $uri->userinfo = null; 
    1602016614        return true; 
     
    1605216646 
    1605316647    public $browsable = false; 
    16054  
    16055     public function validate(&$uri, $config, $context) { 
    16056         parent::validate($uri, $config, $context); 
     16648    public $may_omit_host = true; 
     16649 
     16650    public function doValidate(&$uri, $config, $context) { 
    1605716651        $uri->userinfo = null; 
    1605816652        $uri->host     = null; 
     
    1607416668 
    1607516669    public $browsable = false; 
    16076  
    16077     public function validate(&$uri, $config, $context) { 
    16078         parent::validate($uri, $config, $context); 
     16670    public $may_omit_host = true; 
     16671 
     16672    public function doValidate(&$uri, $config, $context) { 
    1607916673        $uri->userinfo = null; 
    1608016674        $uri->host     = null; 
     
    1609916693    public $browsable = false; 
    1610016694 
    16101     public function validate(&$uri, $config, $context) { 
    16102         parent::validate($uri, $config, $context); 
     16695    public function doValidate(&$uri, $config, $context) { 
    1610316696        $uri->userinfo = null; 
    1610416697        $uri->query    = null; 
  • tags/7.0/plugins/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema.ser

    r15200 r15813  
    1 O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:104:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:22:"Core.AggressivelyFixLt";b:1;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:17:{s:6:"maroon";s:7:"#800000";s:3:"red";s:7:"#FF0000";s:6:"orange";s:7:"#FFA500";s:6:"yellow";s:7:"#FFFF00";s:5:"olive";s:7:"#808000";s:6:"purple";s:7:"#800080";s:7:"fuchsia";s:7:"#FF00FF";s:5:"white";s:7:"#FFFFFF";s:4:"lime";s:7:"#00FF00";s:5:"green";s:7:"#008000";s:4:"navy";s:7:"#000080";s:4:"blue";s:7:"#0000FF";s:4:"aqua";s:7:"#00FFFF";s:4:"teal";s:7:"#008080";s:5:"black";s:7:"#000000";s:6:"silver";s:7:"#C0C0C0";s:4:"gray";s:7:"#808080";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeObject";b:0;s:11:"HTML.Strict";b:0;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:6:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:104:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:22:"Core.AggressivelyFixLt";b:1;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:17:{s:6:"maroon";s:7:"#800000";s:3:"red";s:7:"#FF0000";s:6:"orange";s:7:"#FFA500";s:6:"yellow";s:7:"#FFFF00";s:5:"olive";s:7:"#808000";s:6:"purple";s:7:"#800080";s:7:"fuchsia";s:7:"#FF00FF";s:5:"white";s:7:"#FFFFFF";s:4:"lime";s:7:"#00FF00";s:5:"green";s:7:"#008000";s:4:"navy";s:7:"#000080";s:4:"blue";s:7:"#0000FF";s:4:"aqua";s:7:"#00FFFF";s:4:"teal";s:7:"#008080";s:5:"black";s:7:"#000000";s:6:"silver";s:7:"#C0C0C0";s:4:"gray";s:7:"#808080";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeObject";b:0;s:11:"HTML.Strict";b:0;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:6:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:117:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:22:"Core.AggressivelyFixLt";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:17:"HTML.MaxImgLength";i:-5;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeObject";i:7;s:11:"HTML.Strict";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;}} 
     1O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:109:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:17:{s:6:"maroon";s:7:"#800000";s:3:"red";s:7:"#FF0000";s:6:"orange";s:7:"#FFA500";s:6:"yellow";s:7:"#FFFF00";s:5:"olive";s:7:"#808000";s:6:"purple";s:7:"#800080";s:7:"fuchsia";s:7:"#FF00FF";s:5:"white";s:7:"#FFFFFF";s:4:"lime";s:7:"#00FF00";s:5:"green";s:7:"#008000";s:4:"navy";s:7:"#000080";s:4:"blue";s:7:"#0000FF";s:4:"aqua";s:7:"#00FFFF";s:4:"teal";s:7:"#008080";s:5:"black";s:7:"#000000";s:6:"silver";s:7:"#C0C0C0";s:4:"gray";s:7:"#808080";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeObject";b:0;s:11:"HTML.Strict";b:0;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:6:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:109:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:17:{s:6:"maroon";s:7:"#800000";s:3:"red";s:7:"#FF0000";s:6:"orange";s:7:"#FFA500";s:6:"yellow";s:7:"#FFFF00";s:5:"olive";s:7:"#808000";s:6:"purple";s:7:"#800080";s:7:"fuchsia";s:7:"#FF00FF";s:5:"white";s:7:"#FFFFFF";s:4:"lime";s:7:"#00FF00";s:5:"green";s:7:"#008000";s:4:"navy";s:7:"#000080";s:4:"blue";s:7:"#0000FF";s:4:"aqua";s:7:"#00FFFF";s:4:"teal";s:7:"#008080";s:5:"black";s:7:"#000000";s:6:"silver";s:7:"#C0C0C0";s:4:"gray";s:7:"#808080";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeObject";b:0;s:11:"HTML.Strict";b:0;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:6:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:122:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:5;s:22:"Core.AggressivelyFixLt";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeObject";i:7;s:11:"HTML.Strict";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;}} 
  • tags/7.0/plugins/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt

    r15200 r15813  
    66Indicates whether or not the user input is trusted or not. If the input is 
    77trusted, a more expansive set of allowed tags and attributes will be used. 
     8See also %CSS.Trusted. 
    89--# vim: et sw=4 sts=4 
  • tags/7.0/plugins/htmlpurifier/standalone/HTMLPurifier/EntityLookup/entities.ser

    r15200 r15813  
    1 a:246:{s:4:"nbsp";s:2:" ";s:5:"iexcl";s:2:"¡";s:4:"cent";s:2:"¢";s:5:"pound";s:2:"£";s:6:"curren";s:2:"¤";s:3:"yen";s:2:"¥";s:6:"brvbar";s:2:"¦";s:4:"sect";s:2:"§";s:3:"uml";s:2:"¨";s:4:"copy";s:2:"©";s:4:"ordf";s:2:"ª";s:5:"laquo";s:2:"«";s:3:"not";s:2:"¬";s:3:"shy";s:2:"­";s:3:"reg";s:2:"®";s:4:"macr";s:2:"¯";s:3:"deg";s:2:"°";s:6:"plusmn";s:2:"±";s:5:"acute";s:2:"´";s:5:"micro";s:2:"µ";s:4:"para";s:2:"¶";s:6:"middot";s:2:"·";s:5:"cedil";s:2:"¸";s:4:"ordm";s:2:"º";s:5:"raquo";s:2:"»";s:6:"iquest";s:2:"¿";s:6:"Agrave";s:2:"À";s:6:"Aacute";s:2:"Á";s:5:"Acirc";s:2:"Â";s:6:"Atilde";s:2:"Ã";s:4:"Auml";s:2:"Ä";s:5:"Aring";s:2:"Å";s:5:"AElig";s:2:"Æ";s:6:"Ccedil";s:2:"Ç";s:6:"Egrave";s:2:"È";s:6:"Eacute";s:2:"É";s:5:"Ecirc";s:2:"Ê";s:4:"Euml";s:2:"Ë";s:6:"Igrave";s:2:"Ì";s:6:"Iacute";s:2:"Í";s:5:"Icirc";s:2:"Î";s:4:"Iuml";s:2:"Ï";s:3:"ETH";s:2:"Ð";s:6:"Ntilde";s:2:"Ñ";s:6:"Ograve";s:2:"Ò";s:6:"Oacute";s:2:"Ó";s:5:"Ocirc";s:2:"Ô";s:6:"Otilde";s:2:"Õ";s:4:"Ouml";s:2:"Ö";s:5:"times";s:2:"×";s:6:"Oslash";s:2:"Ø";s:6:"Ugrave";s:2:"Ù";s:6:"Uacute";s:2:"Ú";s:5:"Ucirc";s:2:"Û";s:4:"Uuml";s:2:"Ü";s:6:"Yacute";s:2:"Ý";s:5:"THORN";s:2:"Þ";s:5:"szlig";s:2:"ß";s:6:"agrave";s:2:"à";s:6:"aacute";s:2:"á";s:5:"acirc";s:2:"â";s:6:"atilde";s:2:"ã";s:4:"auml";s:2:"ä";s:5:"aring";s:2:"å";s:5:"aelig";s:2:"æ";s:6:"ccedil";s:2:"ç";s:6:"egrave";s:2:"è";s:6:"eacute";s:2:"é";s:5:"ecirc";s:2:"ê";s:4:"euml";s:2:"ë";s:6:"igrave";s:2:"ì";s:6:"iacute";s:2:"í";s:5:"icirc";s:2:"î";s:4:"iuml";s:2:"ï";s:3:"eth";s:2:"ð";s:6:"ntilde";s:2:"ñ";s:6:"ograve";s:2:"ò";s:6:"oacute";s:2:"ó";s:5:"ocirc";s:2:"ô";s:6:"otilde";s:2:"õ";s:4:"ouml";s:2:"ö";s:6:"divide";s:2:"÷";s:6:"oslash";s:2:"ø";s:6:"ugrave";s:2:"ù";s:6:"uacute";s:2:"ú";s:5:"ucirc";s:2:"û";s:4:"uuml";s:2:"ü";s:6:"yacute";s:2:"ý";s:5:"thorn";s:2:"þ";s:4:"yuml";s:2:"ÿ";s:4:"quot";s:1:""";s:3:"amp";s:1:"&";s:2:"lt";s:1:"<";s:2:"gt";s:1:">";s:4:"apos";s:1:"'";s:5:"OElig";s:2:"Œ";s:5:"oelig";s:2:"œ";s:6:"Scaron";s:2:"Š";s:6:"scaron";s:2:"š";s:4:"Yuml";s:2:"Ÿ";s:4:"circ";s:2:"ˆ";s:5:"tilde";s:2:"˜";s:4:"ensp";s:3:" ";s:4:"emsp";s:3:" ";s:6:"thinsp";s:3:" ";s:4:"zwnj";s:3:"‌";s:3:"zwj";s:3:"‍";s:3:"lrm";s:3:"‎";s:3:"rlm";s:3:"‏";s:5:"ndash";s:3:"–";s:5:"mdash";s:3:"—";s:5:"lsquo";s:3:"‘";s:5:"rsquo";s:3:"’";s:5:"sbquo";s:3:"‚";s:5:"ldquo";s:3:"“";s:5:"rdquo";s:3:"”";s:5:"bdquo";s:3:"„";s:6:"dagger";s:3:"†";s:6:"Dagger";s:3:"‡";s:6:"permil";s:3:"‰";s:6:"lsaquo";s:3:"‹";s:6:"rsaquo";s:3:"›";s:4:"euro";s:3:"€";s:4:"fnof";s:2:"ƒ";s:5:"Alpha";s:2:"Α";s:4:"Beta";s:2:"Β";s:5:"Gamma";s:2:"Γ";s:5:"Delta";s:2:"Δ";s:7:"Epsilon";s:2:"Ε";s:4:"Zeta";s:2:"Ζ";s:3:"Eta";s:2:"Η";s:5:"Theta";s:2:"Θ";s:4:"Iota";s:2:"Ι";s:5:"Kappa";s:2:"Κ";s:6:"Lambda";s:2:"Λ";s:2:"Mu";s:2:"Μ";s:2:"Nu";s:2:"Ν";s:2:"Xi";s:2:"Ξ";s:7:"Omicron";s:2:"Ο";s:2:"Pi";s:2:"Π";s:3:"Rho";s:2:"Ρ";s:5:"Sigma";s:2:"Σ";s:3:"Tau";s:2:"Τ";s:7:"Upsilon";s:2:"Υ";s:3:"Phi";s:2:"Φ";s:3:"Chi";s:2:"Χ";s:3:"Psi";s:2:"Ψ";s:5:"Omega";s:2:"Ω";s:5:"alpha";s:2:"α";s:4:"beta";s:2:"β";s:5:"gamma";s:2:"γ";s:5:"delta";s:2:"δ";s:7:"epsilon";s:2:"ε";s:4:"zeta";s:2:"ζ";s:3:"eta";s:2:"η";s:5:"theta";s:2:"θ";s:4:"iota";s:2:"ι";s:5:"kappa";s:2:"κ";s:6:"lambda";s:2:"λ";s:2:"mu";s:2:"μ";s:2:"nu";s:2:"ν";s:2:"xi";s:2:"ξ";s:7:"omicron";s:2:"ο";s:2:"pi";s:2:"π";s:3:"rho";s:2:"ρ";s:6:"sigmaf";s:2:"ς";s:5:"sigma";s:2:"σ";s:3:"tau";s:2:"τ";s:7:"upsilon";s:2:"υ";s:3:"phi";s:2:"φ";s:3:"chi";s:2:"χ";s:3:"psi";s:2:"ψ";s:5:"omega";s:2:"ω";s:8:"thetasym";s:2:"ϑ";s:5:"upsih";s:2:"ϒ";s:3:"piv";s:2:"ϖ";s:4:"bull";s:3:"•";s:6:"hellip";s:3:"…";s:5:"prime";s:3:"′";s:5:"Prime";s:3:"″";s:5:"oline";s:3:"‾";s:5:"frasl";s:3:"⁄";s:6:"weierp";s:3:"℘";s:5:"image";s:3:"ℑ";s:4:"real";s:3:"ℜ";s:5:"trade";s:3:"™";s:7:"alefsym";s:3:"ℵ";s:4:"larr";s:3:"←";s:4:"uarr";s:3:"↑";s:4:"rarr";s:3:"→";s:4:"darr";s:3:"↓";s:4:"harr";s:3:"↔";s:5:"crarr";s:3:"↵";s:4:"lArr";s:3:"⇐";s:4:"uArr";s:3:"⇑";s:4:"rArr";s:3:"⇒";s:4:"dArr";s:3:"⇓";s:4:"hArr";s:3:"⇔";s:6:"forall";s:3:"∀";s:4:"part";s:3:"∂";s:5:"exist";s:3:"∃";s:5:"empty";s:3:"∅";s:5:"nabla";s:3:"∇";s:4:"isin";s:3:"∈";s:5:"notin";s:3:"∉";s:2:"ni";s:3:"∋";s:4:"prod";s:3:"∏";s:3:"sum";s:3:"∑";s:5:"minus";s:3:"−";s:6:"lowast";s:3:"∗";s:5:"radic";s:3:"√";s:4:"prop";s:3:"∝";s:5:"infin";s:3:"∞";s:3:"ang";s:3:"∠";s:3:"and";s:3:"∧";s:2:"or";s:3:"∨";s:3:"cap";s:3:"∩";s:3:"cup";s:3:"∪";s:3:"int";s:3:"∫";s:3:"sim";s:3:"∼";s:4:"cong";s:3:"≅";s:5:"asymp";s:3:"≈";s:2:"ne";s:3:"≠";s:5:"equiv";s:3:"≡";s:2:"le";s:3:"≤";s:2:"ge";s:3:"≥";s:3:"sub";s:3:"⊂";s:3:"sup";s:3:"⊃";s:4:"nsub";s:3:"⊄";s:4:"sube";s:3:"⊆";s:4:"supe";s:3:"⊇";s:5:"oplus";s:3:"⊕";s:6:"otimes";s:3:"⊗";s:4:"perp";s:3:"⊥";s:4:"sdot";s:3:"⋅";s:5:"lceil";s:3:"⌈";s:5:"rceil";s:3:"⌉";s:6:"lfloor";s:3:"⌊";s:6:"rfloor";s:3:"⌋";s:4:"lang";s:3:"〈";s:4:"rang";s:3:"〉";s:3:"loz";s:3:"◊";s:6:"spades";s:3:"♠";s:5:"clubs";s:3:"♣";s:6:"hearts";s:3:"♥";s:5:"diams";s:3:"♦";} 
     1a:253:{s:4:"fnof";s:2:"ƒ";s:5:"Alpha";s:2:"Α";s:4:"Beta";s:2:"Β";s:5:"Gamma";s:2:"Γ";s:5:"Delta";s:2:"Δ";s:7:"Epsilon";s:2:"Ε";s:4:"Zeta";s:2:"Ζ";s:3:"Eta";s:2:"Η";s:5:"Theta";s:2:"Θ";s:4:"Iota";s:2:"Ι";s:5:"Kappa";s:2:"Κ";s:6:"Lambda";s:2:"Λ";s:2:"Mu";s:2:"Μ";s:2:"Nu";s:2:"Ν";s:2:"Xi";s:2:"Ξ";s:7:"Omicron";s:2:"Ο";s:2:"Pi";s:2:"Π";s:3:"Rho";s:2:"Ρ";s:5:"Sigma";s:2:"Σ";s:3:"Tau";s:2:"Τ";s:7:"Upsilon";s:2:"Υ";s:3:"Phi";s:2:"Φ";s:3:"Chi";s:2:"Χ";s:3:"Psi";s:2:"Ψ";s:5:"Omega";s:2:"Ω";s:5:"alpha";s:2:"α";s:4:"beta";s:2:"β";s:5:"gamma";s:2:"γ";s:5:"delta";s:2:"δ";s:7:"epsilon";s:2:"ε";s:4:"zeta";s:2:"ζ";s:3:"eta";s:2:"η";s:5:"theta";s:2:"θ";s:4:"iota";s:2:"ι";s:5:"kappa";s:2:"κ";s:6:"lambda";s:2:"λ";s:2:"mu";s:2:"μ";s:2:"nu";s:2:"ν";s:2:"xi";s:2:"ξ";s:7:"omicron";s:2:"ο";s:2:"pi";s:2:"π";s:3:"rho";s:2:"ρ";s:6:"sigmaf";s:2:"ς";s:5:"sigma";s:2:"σ";s:3:"tau";s:2:"τ";s:7:"upsilon";s:2:"υ";s:3:"phi";s:2:"φ";s:3:"chi";s:2:"χ";s:3:"psi";s:2:"ψ";s:5:"omega";s:2:"ω";s:8:"thetasym";s:2:"ϑ";s:5:"upsih";s:2:"ϒ";s:3:"piv";s:2:"ϖ";s:4:"bull";s:3:"•";s:6:"hellip";s:3:"…";s:5:"prime";s:3:"′";s:5:"Prime";s:3:"″";s:5:"oline";s:3:"‾";s:5:"frasl";s:3:"⁄";s:6:"weierp";s:3:"℘";s:5:"image";s:3:"ℑ";s:4:"real";s:3:"ℜ";s:5:"trade";s:3:"™";s:7:"alefsym";s:3:"ℵ";s:4:"larr";s:3:"←";s:4:"uarr";s:3:"↑";s:4:"rarr";s:3:"→";s:4:"darr";s:3:"↓";s:4:"harr";s:3:"↔";s:5:"crarr";s:3:"↵";s:4:"lArr";s:3:"⇐";s:4:"uArr";s:3:"⇑";s:4:"rArr";s:3:"⇒";s:4:"dArr";s:3:"⇓";s:4:"hArr";s:3:"⇔";s:6:"forall";s:3:"∀";s:4:"part";s:3:"∂";s:5:"exist";s:3:"∃";s:5:"empty";s:3:"∅";s:5:"nabla";s:3:"∇";s:4:"isin";s:3:"∈";s:5:"notin";s:3:"∉";s:2:"ni";s:3:"∋";s:4:"prod";s:3:"∏";s:3:"sum";s:3:"∑";s:5:"minus";s:3:"−";s:6:"lowast";s:3:"∗";s:5:"radic";s:3:"√";s:4:"prop";s:3:"∝";s:5:"infin";s:3:"∞";s:3:"ang";s:3:"∠";s:3:"and";s:3:"∧";s:2:"or";s:3:"∨";s:3:"cap";s:3:"∩";s:3:"cup";s:3:"∪";s:3:"int";s:3:"∫";s:6:"there4";s:3:"∴";s:3:"sim";s:3:"∼";s:4:"cong";s:3:"≅";s:5:"asymp";s:3:"≈";s:2:"ne";s:3:"≠";s:5:"equiv";s:3:"≡";s:2:"le";s:3:"≤";s:2:"ge";s:3:"≥";s:3:"sub";s:3:"⊂";s:3:"sup";s:3:"⊃";s:4:"nsub";s:3:"⊄";s:4:"sube";s:3:"⊆";s:4:"supe";s:3:"⊇";s:5:"oplus";s:3:"⊕";s:6:"otimes";s:3:"⊗";s:4:"perp";s:3:"⊥";s:4:"sdot";s:3:"⋅";s:5:"lceil";s:3:"⌈";s:5:"rceil";s:3:"⌉";s:6:"lfloor";s:3:"⌊";s:6:"rfloor";s:3:"⌋";s:4:"lang";s:3:"〈";s:4:"rang";s:3:"〉";s:3:"loz";s:3:"◊";s:6:"spades";s:3:"♠";s:5:"clubs";s:3:"♣";s:6:"hearts";s:3:"♥";s:5:"diams";s:3:"♦";s:4:"quot";s:1:""";s:3:"amp";s:1:"&";s:2:"lt";s:1:"<";s:2:"gt";s:1:">";s:4:"apos";s:1:"'";s:5:"OElig";s:2:"Œ";s:5:"oelig";s:2:"œ";s:6:"Scaron";s:2:"Š";s:6:"scaron";s:2:"š";s:4:"Yuml";s:2:"Ÿ";s:4:"circ";s:2:"ˆ";s:5:"tilde";s:2:"˜";s:4:"ensp";s:3:" ";s:4:"emsp";s:3:" ";s:6:"thinsp";s:3:" ";s:4:"zwnj";s:3:"‌";s:3:"zwj";s:3:"‍";s:3:"lrm";s:3:"‎";s:3:"rlm";s:3:"‏";s:5:"ndash";s:3:"–";s:5:"mdash";s:3:"—";s:5:"lsquo";s:3:"‘";s:5:"rsquo";s:3:"’";s:5:"sbquo";s:3:"‚";s:5:"ldquo";s:3:"“";s:5:"rdquo";s:3:"”";s:5:"bdquo";s:3:"„";s:6:"dagger";s:3:"†";s:6:"Dagger";s:3:"‡";s:6:"permil";s:3:"‰";s:6:"lsaquo";s:3:"‹";s:6:"rsaquo";s:3:"›";s:4:"euro";s:3:"€";s:4:"nbsp";s:2:" ";s:5:"iexcl";s:2:"¡";s:4:"cent";s:2:"¢";s:5:"pound";s:2:"£";s:6:"curren";s:2:"¤";s:3:"yen";s:2:"¥";s:6:"brvbar";s:2:"¦";s:4:"sect";s:2:"§";s:3:"uml";s:2:"¨";s:4:"copy";s:2:"©";s:4:"ordf";s:2:"ª";s:5:"laquo";s:2:"«";s:3:"not";s:2:"¬";s:3:"shy";s:2:"­";s:3:"reg";s:2:"®";s:4:"macr";s:2:"¯";s:3:"deg";s:2:"°";s:6:"plusmn";s:2:"±";s:4:"sup2";s:2:"²";s:4:"sup3";s:2:"³";s:5:"acute";s:2:"´";s:5:"micro";s:2:"µ";s:4:"para";s:2:"¶";s:6:"middot";s:2:"·";s:5:"cedil";s:2:"¸";s:4:"sup1";s:2:"¹";s:4:"ordm";s:2:"º";s:5:"raquo";s:2:"»";s:6:"frac14";s:2:"¼";s:6:"frac12";s:2:"½";s:6:"frac34";s:2:"¾";s:6:"iquest";s:2:"¿";s:6:"Agrave";s:2:"À";s:6:"Aacute";s:2:"Á";s:5:"Acirc";s:2:"Â";s:6:"Atilde";s:2:"Ã";s:4:"Auml";s:2:"Ä";s:5:"Aring";s:2:"Å";s:5:"AElig";s:2:"Æ";s:6:"Ccedil";s:2:"Ç";s:6:"Egrave";s:2:"È";s:6:"Eacute";s:2:"É";s:5:"Ecirc";s:2:"Ê";s:4:"Euml";s:2:"Ë";s:6:"Igrave";s:2:"Ì";s:6:"Iacute";s:2:"Í";s:5:"Icirc";s:2:"Î";s:4:"Iuml";s:2:"Ï";s:3:"ETH";s:2:"Ð";s:6:"Ntilde";s:2:"Ñ";s:6:"Ograve";s:2:"Ò";s:6:"Oacute";s:2:"Ó";s:5:"Ocirc";s:2:"Ô";s:6:"Otilde";s:2:"Õ";s:4:"Ouml";s:2:"Ö";s:5:"times";s:2:"×";s:6:"Oslash";s:2:"Ø";s:6:"Ugrave";s:2:"Ù";s:6:"Uacute";s:2:"Ú";s:5:"Ucirc";s:2:"Û";s:4:"Uuml";s:2:"Ü";s:6:"Yacute";s:2:"Ý";s:5:"THORN";s:2:"Þ";s:5:"szlig";s:2:"ß";s:6:"agrave";s:2:"à";s:6:"aacute";s:2:"á";s:5:"acirc";s:2:"â";s:6:"atilde";s:2:"ã";s:4:"auml";s:2:"ä";s:5:"aring";s:2:"å";s:5:"aelig";s:2:"æ";s:6:"ccedil";s:2:"ç";s:6:"egrave";s:2:"è";s:6:"eacute";s:2:"é";s:5:"ecirc";s:2:"ê";s:4:"euml";s:2:"ë";s:6:"igrave";s:2:"ì";s:6:"iacute";s:2:"í";s:5:"icirc";s:2:"î";s:4:"iuml";s:2:"ï";s:3:"eth";s:2:"ð";s:6:"ntilde";s:2:"ñ";s:6:"ograve";s:2:"ò";s:6:"oacute";s:2:"ó";s:5:"ocirc";s:2:"ô";s:6:"otilde";s:2:"õ";s:4:"ouml";s:2:"ö";s:6:"divide";s:2:"÷";s:6:"oslash";s:2:"ø";s:6:"ugrave";s:2:"ù";s:6:"uacute";s:2:"ú";s:5:"ucirc";s:2:"û";s:4:"uuml";s:2:"ü";s:6:"yacute";s:2:"ý";s:5:"thorn";s:2:"þ";s:4:"yuml";s:2:"ÿ";} 
Note: See TracChangeset for help on using the changeset viewer.