1171 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1171 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace Nextend\Framework;
 | |
| 
 | |
| use DOMDocument;
 | |
| use Nextend\Framework\Platform\Platform;
 | |
| 
 | |
| global $allowedentitynames;
 | |
| /**
 | |
|  * @var string[] $allowedentitynames Array of KSES allowed HTML entitity names.
 | |
|  * @since 1.0.0
 | |
|  */
 | |
| $allowedentitynames = is_array($allowedentitynames) ? $allowedentitynames : array(
 | |
|     'nbsp',
 | |
|     'iexcl',
 | |
|     'cent',
 | |
|     'pound',
 | |
|     'curren',
 | |
|     'yen',
 | |
|     'brvbar',
 | |
|     'sect',
 | |
|     'uml',
 | |
|     'copy',
 | |
|     'ordf',
 | |
|     'laquo',
 | |
|     'not',
 | |
|     'shy',
 | |
|     'reg',
 | |
|     'macr',
 | |
|     'deg',
 | |
|     'plusmn',
 | |
|     'acute',
 | |
|     'micro',
 | |
|     'para',
 | |
|     'middot',
 | |
|     'cedil',
 | |
|     'ordm',
 | |
|     'raquo',
 | |
|     'iquest',
 | |
|     'Agrave',
 | |
|     'Aacute',
 | |
|     'Acirc',
 | |
|     'Atilde',
 | |
|     'Auml',
 | |
|     'Aring',
 | |
|     'AElig',
 | |
|     'Ccedil',
 | |
|     'Egrave',
 | |
|     'Eacute',
 | |
|     'Ecirc',
 | |
|     'Euml',
 | |
|     'Igrave',
 | |
|     'Iacute',
 | |
|     'Icirc',
 | |
|     'Iuml',
 | |
|     'ETH',
 | |
|     'Ntilde',
 | |
|     'Ograve',
 | |
|     'Oacute',
 | |
|     'Ocirc',
 | |
|     'Otilde',
 | |
|     'Ouml',
 | |
|     'times',
 | |
|     'Oslash',
 | |
|     'Ugrave',
 | |
|     'Uacute',
 | |
|     'Ucirc',
 | |
|     'Uuml',
 | |
|     'Yacute',
 | |
|     'THORN',
 | |
|     'szlig',
 | |
|     'agrave',
 | |
|     'aacute',
 | |
|     'acirc',
 | |
|     'atilde',
 | |
|     'auml',
 | |
|     'aring',
 | |
|     'aelig',
 | |
|     'ccedil',
 | |
|     'egrave',
 | |
|     'eacute',
 | |
|     'ecirc',
 | |
|     'euml',
 | |
|     'igrave',
 | |
|     'iacute',
 | |
|     'icirc',
 | |
|     'iuml',
 | |
|     'eth',
 | |
|     'ntilde',
 | |
|     'ograve',
 | |
|     'oacute',
 | |
|     'ocirc',
 | |
|     'otilde',
 | |
|     'ouml',
 | |
|     'divide',
 | |
|     'oslash',
 | |
|     'ugrave',
 | |
|     'uacute',
 | |
|     'ucirc',
 | |
|     'uuml',
 | |
|     'yacute',
 | |
|     'thorn',
 | |
|     'yuml',
 | |
|     'quot',
 | |
|     'amp',
 | |
|     'lt',
 | |
|     'gt',
 | |
|     'apos',
 | |
|     'OElig',
 | |
|     'oelig',
 | |
|     'Scaron',
 | |
|     'scaron',
 | |
|     'Yuml',
 | |
|     'circ',
 | |
|     'tilde',
 | |
|     'ensp',
 | |
|     'emsp',
 | |
|     'thinsp',
 | |
|     'zwnj',
 | |
|     'zwj',
 | |
|     'lrm',
 | |
|     'rlm',
 | |
|     'ndash',
 | |
|     'mdash',
 | |
|     'lsquo',
 | |
|     'rsquo',
 | |
|     'sbquo',
 | |
|     'ldquo',
 | |
|     'rdquo',
 | |
|     'bdquo',
 | |
|     'dagger',
 | |
|     'Dagger',
 | |
|     'permil',
 | |
|     'lsaquo',
 | |
|     'rsaquo',
 | |
|     'euro',
 | |
|     'fnof',
 | |
|     'Alpha',
 | |
|     'Beta',
 | |
|     'Gamma',
 | |
|     'Delta',
 | |
|     'Epsilon',
 | |
|     'Zeta',
 | |
|     'Eta',
 | |
|     'Theta',
 | |
|     'Iota',
 | |
|     'Kappa',
 | |
|     'Lambda',
 | |
|     'Mu',
 | |
|     'Nu',
 | |
|     'Xi',
 | |
|     'Omicron',
 | |
|     'Pi',
 | |
|     'Rho',
 | |
|     'Sigma',
 | |
|     'Tau',
 | |
|     'Upsilon',
 | |
|     'Phi',
 | |
|     'Chi',
 | |
|     'Psi',
 | |
|     'Omega',
 | |
|     'alpha',
 | |
|     'beta',
 | |
|     'gamma',
 | |
|     'delta',
 | |
|     'epsilon',
 | |
|     'zeta',
 | |
|     'eta',
 | |
|     'theta',
 | |
|     'iota',
 | |
|     'kappa',
 | |
|     'lambda',
 | |
|     'mu',
 | |
|     'nu',
 | |
|     'xi',
 | |
|     'omicron',
 | |
|     'pi',
 | |
|     'rho',
 | |
|     'sigmaf',
 | |
|     'sigma',
 | |
|     'tau',
 | |
|     'upsilon',
 | |
|     'phi',
 | |
|     'chi',
 | |
|     'psi',
 | |
|     'omega',
 | |
|     'thetasym',
 | |
|     'upsih',
 | |
|     'piv',
 | |
|     'bull',
 | |
|     'hellip',
 | |
|     'prime',
 | |
|     'Prime',
 | |
|     'oline',
 | |
|     'frasl',
 | |
|     'weierp',
 | |
|     'image',
 | |
|     'real',
 | |
|     'trade',
 | |
|     'alefsym',
 | |
|     'larr',
 | |
|     'uarr',
 | |
|     'rarr',
 | |
|     'darr',
 | |
|     'harr',
 | |
|     'crarr',
 | |
|     'lArr',
 | |
|     'uArr',
 | |
|     'rArr',
 | |
|     'dArr',
 | |
|     'hArr',
 | |
|     'forall',
 | |
|     'part',
 | |
|     'exist',
 | |
|     'empty',
 | |
|     'nabla',
 | |
|     'isin',
 | |
|     'notin',
 | |
|     'ni',
 | |
|     'prod',
 | |
|     'sum',
 | |
|     'minus',
 | |
|     'lowast',
 | |
|     'radic',
 | |
|     'prop',
 | |
|     'infin',
 | |
|     'ang',
 | |
|     'and',
 | |
|     'or',
 | |
|     'cap',
 | |
|     'cup',
 | |
|     'int',
 | |
|     'sim',
 | |
|     'cong',
 | |
|     'asymp',
 | |
|     'ne',
 | |
|     'equiv',
 | |
|     'le',
 | |
|     'ge',
 | |
|     'sub',
 | |
|     'sup',
 | |
|     'nsub',
 | |
|     'sube',
 | |
|     'supe',
 | |
|     'oplus',
 | |
|     'otimes',
 | |
|     'perp',
 | |
|     'sdot',
 | |
|     'lceil',
 | |
|     'rceil',
 | |
|     'lfloor',
 | |
|     'rfloor',
 | |
|     'lang',
 | |
|     'rang',
 | |
|     'loz',
 | |
|     'spades',
 | |
|     'clubs',
 | |
|     'hearts',
 | |
|     'diams',
 | |
|     'sup1',
 | |
|     'sup2',
 | |
|     'sup3',
 | |
|     'frac14',
 | |
|     'frac12',
 | |
|     'frac34',
 | |
|     'there4',
 | |
| );
 | |
| 
 | |
| class Sanitize {
 | |
| 
 | |
|     public static $basicTags = array();
 | |
| 
 | |
|     // Tags for admin page forms with text fields, on-offs, selects, textareas, etc..
 | |
|     public static $adminFormTags = array();
 | |
| 
 | |
|     // Tags for the rest of the admin page layout.
 | |
|     public static $adminTemplateTags = array();
 | |
| 
 | |
|     // Tags for CSS and JS codes.
 | |
|     public static $assetTags = array();
 | |
| 
 | |
|     // Tags for html videos.
 | |
|     public static $videoTags = array();
 | |
| 
 | |
|     private static function getCharset() {
 | |
| 
 | |
|         return Platform::getCharset();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Checks for invalid UTF8 in a string.
 | |
|      *
 | |
|      * @param string $string The text which is to be checked.
 | |
|      * @param bool   $strip  Optional. Whether to attempt to strip out invalid UTF8. Default is false.
 | |
|      *
 | |
|      * @return string The checked text.
 | |
|      * @since     2.8.0
 | |
|      *
 | |
|      * @staticvar bool $is_utf8
 | |
|      * @staticvar bool $utf8_pcre
 | |
|      *
 | |
|      */
 | |
|     private static function check_invalid_utf8($string, $strip = false) {
 | |
|         $string = (string)$string;
 | |
| 
 | |
|         if (0 === strlen($string)) {
 | |
|             return '';
 | |
|         }
 | |
| 
 | |
|         // Store the site charset as a static to avoid multiple calls to get_option()
 | |
|         static $is_utf8 = null;
 | |
|         if (!isset($is_utf8)) {
 | |
|             $is_utf8 = in_array(self::getCharset(), array(
 | |
|                 'utf8',
 | |
|                 'utf-8',
 | |
|                 'UTF8',
 | |
|                 'UTF-8'
 | |
|             ));
 | |
|         }
 | |
|         if (!$is_utf8) {
 | |
|             return $string;
 | |
|         }
 | |
| 
 | |
|         // Check for support for utf8 in the installed PCRE library once and store the result in a static
 | |
|         static $utf8_pcre = null;
 | |
|         if (!isset($utf8_pcre)) {
 | |
|             $utf8_pcre = @preg_match('/^./u', 'a');
 | |
|         }
 | |
|         // We can't demand utf8 in the PCRE installation, so just return the string in those cases
 | |
|         if (!$utf8_pcre) {
 | |
|             return $string;
 | |
|         }
 | |
| 
 | |
|         // preg_match fails when it encounters invalid UTF8 in $string
 | |
|         if (1 === @preg_match('/^./us', $string)) {
 | |
|             return $string;
 | |
|         }
 | |
| 
 | |
|         // Attempt to strip the bad chars if requested (not recommended)
 | |
|         if ($strip && function_exists('iconv')) {
 | |
|             return iconv('utf-8', 'utf-8', $string);
 | |
|         }
 | |
| 
 | |
|         return '';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Converts a number of special characters into their HTML entities.
 | |
|      *
 | |
|      * Specifically deals with: &, <, >, ", and '.
 | |
|      *
 | |
|      * $quote_style can be set to ENT_COMPAT to encode " to
 | |
|      * ", or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded.
 | |
|      *
 | |
|      * @param string      $string        The text which is to be encoded.
 | |
|      * @param int|string  $quote_style   Optional. Converts double quotes if set to ENT_COMPAT,
 | |
|      *                                   both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES.
 | |
|      *                                   Also compatible with old values; converting single quotes if set to 'single',
 | |
|      *                                   double if set to 'double' or both if otherwise set.
 | |
|      *                                   Default is ENT_NOQUOTES.
 | |
|      * @param string|bool $charset       Optional. The character encoding of the string. Default is false.
 | |
|      * @param bool        $double_encode Optional. Whether to encode existing html entities. Default is false.
 | |
|      *
 | |
|      * @return string The encoded text with HTML entities.
 | |
|      * @since     1.2.2
 | |
|      * @access    private
 | |
|      *
 | |
|      * @staticvar string $_charset
 | |
|      *
 | |
|      */
 | |
|     private static function _specialchars($string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false) {
 | |
|         $string = (string)$string;
 | |
| 
 | |
|         if (0 === strlen($string)) return '';
 | |
| 
 | |
|         // Don't bother if there are no specialchars - saves some processing
 | |
|         if (!preg_match('/[&<>"\']/', $string)) return $string;
 | |
| 
 | |
|         // Account for the previous behaviour of the function when the $quote_style is not an accepted value
 | |
|         if (empty($quote_style)) $quote_style = ENT_NOQUOTES; else if (!in_array($quote_style, array(
 | |
|             0,
 | |
|             2,
 | |
|             3,
 | |
|             'single',
 | |
|             'double'
 | |
|         ), true)) $quote_style = ENT_QUOTES;
 | |
| 
 | |
|         // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
 | |
|         if (!$charset) {
 | |
|             static $_charset = null;
 | |
|             if (!isset($_charset)) {
 | |
|                 $_charset = self::getCharset();
 | |
|             }
 | |
|             $charset = $_charset;
 | |
|         }
 | |
| 
 | |
|         if (in_array($charset, array(
 | |
|             'utf8',
 | |
|             'utf-8',
 | |
|             'UTF8'
 | |
|         ))) $charset = 'UTF-8';
 | |
| 
 | |
|         $_quote_style = $quote_style;
 | |
| 
 | |
|         if ($quote_style === 'double') {
 | |
|             $quote_style  = ENT_COMPAT;
 | |
|             $_quote_style = ENT_COMPAT;
 | |
|         } else if ($quote_style === 'single') {
 | |
|             $quote_style = ENT_NOQUOTES;
 | |
|         }
 | |
| 
 | |
|         if (!$double_encode) {
 | |
|             // Guarantee every &entity; is valid, convert &garbage; into &garbage;
 | |
|             // This is required for PHP < 5.4.0 because ENT_HTML401 flag is unavailable.
 | |
|             $string = self::kses_normalize_entities($string);
 | |
|         }
 | |
| 
 | |
|         $string = @htmlspecialchars($string, $quote_style, $charset, $double_encode);
 | |
| 
 | |
|         // Back-compat.
 | |
|         if ('single' === $_quote_style) $string = str_replace("'", ''', $string);
 | |
| 
 | |
|         return $string;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Converts and fixes HTML entities.
 | |
|      *
 | |
|      * This function normalizes HTML entities. It will convert `AT&T` to the correct
 | |
|      * `AT&T`, `:` to `:`, `&#XYZZY;` to `&#XYZZY;` and so on.
 | |
|      *
 | |
|      * @param string $string Content to normalize entities
 | |
|      *
 | |
|      * @return string Content with normalized entities
 | |
|      * @since 1.0.0
 | |
|      *
 | |
|      */
 | |
|     private static function kses_normalize_entities($string) {
 | |
|         // Disarm all entities by converting & to &
 | |
|         $string = str_replace('&', '&', $string);
 | |
| 
 | |
|         // Change back the allowed entities in our entity whitelist
 | |
|         $string = preg_replace_callback('/&([A-Za-z]{2,8}[0-9]{0,2});/', array(
 | |
|             self::class,
 | |
|             'kses_named_entities'
 | |
|         ), $string);
 | |
|         $string = preg_replace_callback('/&#(0*[0-9]{1,7});/', array(
 | |
|             self::class,
 | |
|             'kses_normalize_entities2'
 | |
|         ), $string);
 | |
|         $string = preg_replace_callback('/&#[Xx](0*[0-9A-Fa-f]{1,6});/', array(
 | |
|             self::class,
 | |
|             'kses_normalize_entities3'
 | |
|         ), $string);
 | |
| 
 | |
|         return $string;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Callback for kses_normalize_entities() regular expression.
 | |
|      *
 | |
|      * This function only accepts valid named entity references, which are finite,
 | |
|      * case-sensitive, and highly scrutinized by HTML and XML validators.
 | |
|      *
 | |
|      * @param array  $matches preg_replace_callback() matches array
 | |
|      *
 | |
|      * @return string Correctly encoded entity
 | |
|      * @since 3.0.0
 | |
|      *
 | |
|      * @global array $allowedentitynames
 | |
|      *
 | |
|      */
 | |
|     public static function kses_named_entities($matches) {
 | |
|         global $allowedentitynames;
 | |
| 
 | |
|         if (empty($matches[1])) return '';
 | |
| 
 | |
|         $i = $matches[1];
 | |
| 
 | |
|         return (!in_array($i, $allowedentitynames)) ? "&$i;" : "&$i;";
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Callback for kses_normalize_entities() regular expression.
 | |
|      *
 | |
|      * This function helps kses_normalize_entities() to only accept 16-bit
 | |
|      * values and nothing more for `&#number;` entities.
 | |
|      *
 | |
|      * @access private
 | |
|      *
 | |
|      * @param array $matches preg_replace_callback() matches array
 | |
|      *
 | |
|      * @return string Correctly encoded entity
 | |
|      * @since  1.0.0
 | |
|      *
 | |
|      */
 | |
|     public static function kses_normalize_entities2($matches) {
 | |
|         if (empty($matches[1])) return '';
 | |
| 
 | |
|         $i = $matches[1];
 | |
|         if (self::valid_unicode($i)) {
 | |
|             $i = str_pad(ltrim($i, '0'), 3, '0', STR_PAD_LEFT);
 | |
|             $i = "&#$i;";
 | |
|         } else {
 | |
|             $i = "&#$i;";
 | |
|         }
 | |
| 
 | |
|         return $i;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Callback for kses_normalize_entities() for regular expression.
 | |
|      *
 | |
|      * This function helps kses_normalize_entities() to only accept valid Unicode
 | |
|      * numeric entities in hex form.
 | |
|      *
 | |
|      * @access private
 | |
|      *
 | |
|      * @param array $matches preg_replace_callback() matches array
 | |
|      *
 | |
|      * @return string Correctly encoded entity
 | |
|      */
 | |
|     public static function kses_normalize_entities3($matches) {
 | |
|         if (empty($matches[1])) return '';
 | |
| 
 | |
|         $hexchars = $matches[1];
 | |
| 
 | |
|         return (!self::valid_unicode(hexdec($hexchars))) ? "&#x$hexchars;" : '&#x' . ltrim($hexchars, '0') . ';';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Helper function to determine if a Unicode value is valid.
 | |
|      *
 | |
|      * @param int $i Unicode value
 | |
|      *
 | |
|      * @return bool True if the value was a valid Unicode number
 | |
|      */
 | |
|     private static function valid_unicode($i) {
 | |
|         return ($i == 0x9 || $i == 0xa || $i == 0xd || ($i >= 0x20 && $i <= 0xd7ff) || ($i >= 0xe000 && $i <= 0xfffd) || ($i >= 0x10000 && $i <= 0x10ffff));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Escape single quotes, htmlspecialchar " < > &, and fix line endings.
 | |
|      *
 | |
|      * Escapes text strings for echoing in JS. It is intended to be used for inline JS
 | |
|      * (in a tag attribute, for example onclick="..."). Note that the strings have to
 | |
|      * be in single quotes. The {@see 'js_escape'} filter is also applied here.
 | |
|      *
 | |
|      * @param string $text The text to be escaped.
 | |
|      *
 | |
|      * @return string Escaped text.
 | |
|      * @since 2.8.0
 | |
|      *
 | |
|      */
 | |
|     public static function esc_js($text) {
 | |
|         $safe_text = self::check_invalid_utf8($text);
 | |
|         $safe_text = self::_specialchars($safe_text, ENT_COMPAT);
 | |
|         $safe_text = preg_replace('/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes($safe_text));
 | |
|         $safe_text = str_replace("\r", '', $safe_text);
 | |
|         $safe_text = str_replace("\n", '\\n', addslashes($safe_text));
 | |
| 
 | |
|         return $safe_text;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Escaping for HTML blocks.
 | |
|      *
 | |
|      * @param string $text
 | |
|      *
 | |
|      * @return string
 | |
|      * @since 2.8.0
 | |
|      *
 | |
|      */
 | |
|     public static function esc_html($text) {
 | |
|         $safe_text = self::check_invalid_utf8($text);
 | |
|         $safe_text = self::_specialchars($safe_text, ENT_QUOTES);
 | |
| 
 | |
|         return $safe_text;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Escaping for HTML attributes.
 | |
|      *
 | |
|      * @param string $text
 | |
|      *
 | |
|      * @return string
 | |
|      * @since 2.8.0
 | |
|      *
 | |
|      */
 | |
|     public static function esc_attr($text) {
 | |
|         $safe_text = self::check_invalid_utf8($text);
 | |
|         $safe_text = self::_specialchars($safe_text, ENT_QUOTES);
 | |
| 
 | |
|         return $safe_text;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Escaping for textarea values.
 | |
|      *
 | |
|      * @param string $text
 | |
|      *
 | |
|      * @return string
 | |
|      * @since 3.1.0
 | |
|      *
 | |
|      */
 | |
|     public static function esc_textarea($text) {
 | |
|         $safe_text = htmlspecialchars($text, ENT_QUOTES, self::getCharset());
 | |
| 
 | |
|         return $safe_text;
 | |
|     }
 | |
| 
 | |
|     public static function remove_closing_style_tag($text) {
 | |
|         $safe_text = self::check_invalid_utf8($text);
 | |
| 
 | |
|         return preg_replace_callback('/<\/style.*?>/i', function () {
 | |
|             return '';
 | |
|         }, $safe_text);
 | |
|     }
 | |
| 
 | |
|     public static function esc_css_value($text) {
 | |
|         $safe_text = self::check_invalid_utf8($text);
 | |
| 
 | |
|         return preg_replace_callback('/[<>]/', function () {
 | |
|             return '';
 | |
|         }, $safe_text);
 | |
|     }
 | |
| 
 | |
|     public static function esc_css_string($cssString) {
 | |
| 
 | |
|         $output = '';
 | |
|         echo "\n\n";
 | |
| 
 | |
|         $pairs = explode(';', trim($cssString));
 | |
|         foreach ($pairs as $pair) {
 | |
|             if (!empty($pair)) {
 | |
|                 $keyValue = explode(':', trim($pair), 2);
 | |
|                 if (count($keyValue) != 2) {
 | |
|                     continue;
 | |
|                 }
 | |
|                 if (!preg_match('/^[a-zA-Z\-]+$/', $keyValue[0])) {
 | |
|                     continue;
 | |
|                 }
 | |
| 
 | |
|                 $output .= $keyValue[0] . ':' . self::esc_css_value(trim($keyValue[1])) . ';';
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $output;
 | |
|     }
 | |
| 
 | |
|     public static function filter_allowed_html($input, $extraTags = '') {
 | |
| 
 | |
|         return self::filter_attributes_on(strip_tags($input, '<a><span><sub><sup><em><i><var><cite><b><strong><small><bdo><br><img><picture><source><u><del><bdi><ins>' . $extraTags));
 | |
|     }
 | |
| 
 | |
|     public static function remove_all_html($input) {
 | |
| 
 | |
|         return strip_tags($input);
 | |
|     }
 | |
| 
 | |
|     public static function filter_attributes_on($input) {
 | |
| 
 | |
|         if (class_exists('DOMDocument')) {
 | |
|             if (function_exists('libxml_use_internal_errors')) {
 | |
|                 libxml_use_internal_errors(true);
 | |
|             }
 | |
| 
 | |
|             $dom = new DOMDocument();
 | |
|             $dom->loadHTML('<?xml encoding="utf-8" ?><!DOCTYPE html><html lang="en"><body>' . $input . '</body></html>');
 | |
| 
 | |
|             if (function_exists('libxml_use_internal_errors')) {
 | |
|                 libxml_use_internal_errors(false);
 | |
|             }
 | |
| 
 | |
|             for ($els = $dom->getElementsByTagname('*'), $i = $els->length - 1; $i >= 0; $i--) {
 | |
|                 for ($attrs = $els->item($i)->attributes, $ii = $attrs->length - 1; $ii >= 0; $ii--) {
 | |
|                     if (substr($attrs->item($ii)->name, 0, 2) === 'on') {
 | |
|                         $els->item($i)
 | |
|                             ->removeAttribute($attrs->item($ii)->name);
 | |
| 
 | |
|                         continue;
 | |
|                     }
 | |
| 
 | |
|                     if ($attrs->item($ii)->name === 'href' && strpos($attrs->item($ii)->value, 'javascript:') !== false) {
 | |
|                         $els->item($i)
 | |
|                             ->removeAttribute($attrs->item($ii)->name);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             $output = '';
 | |
|             $body   = $dom->getElementsByTagName('body');
 | |
|             if ($body && 0 < $body->length) {
 | |
|                 $body       = $body->item(0);
 | |
|                 $childNodes = $body->childNodes;
 | |
|                 if (!empty($childNodes)) {
 | |
|                     foreach ($childNodes as $childNode) {
 | |
|                         $output .= $dom->saveHTML($childNode);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return $output;
 | |
|         } else if (function_exists('wp_kses_post')) {
 | |
|             return wp_kses_post($input);
 | |
|         }
 | |
|         return '';
 | |
|     
 | |
|     }
 | |
| 
 | |
|     public static function set_allowed_tags() {
 | |
|         global $allowedposttags;
 | |
| 
 | |
|         $_allowedposttags = $allowedposttags;
 | |
|     
 | |
| 
 | |
|         if (N2JOOMLA || CUSTOM_TAGS) {
 | |
|             $_allowedposttags = array();
 | |
|         }
 | |
| 
 | |
|         $wpAllowedposttags = array(
 | |
|             'address'    => array(),
 | |
|             'a'          => array(
 | |
|                 'href'     => true,
 | |
|                 'rel'      => true,
 | |
|                 'rev'      => true,
 | |
|                 'name'     => true,
 | |
|                 'target'   => true,
 | |
|                 'download' => array(
 | |
|                     'valueless' => 'y',
 | |
|                 ),
 | |
|             ),
 | |
|             'abbr'       => array(),
 | |
|             'acronym'    => array(),
 | |
|             'area'       => array(
 | |
|                 'alt'    => true,
 | |
|                 'coords' => true,
 | |
|                 'href'   => true,
 | |
|                 'nohref' => true,
 | |
|                 'shape'  => true,
 | |
|                 'target' => true,
 | |
|             ),
 | |
|             'article'    => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'aside'      => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'audio'      => array(
 | |
|                 'autoplay' => true,
 | |
|                 'controls' => true,
 | |
|                 'loop'     => true,
 | |
|                 'muted'    => true,
 | |
|                 'preload'  => true,
 | |
|                 'src'      => true,
 | |
|             ),
 | |
|             'b'          => array(),
 | |
|             'bdi'        => array(),
 | |
|             'bdo'        => array(),
 | |
|             'big'        => array(),
 | |
|             'blockquote' => array(
 | |
|                 'cite' => true,
 | |
|             ),
 | |
|             'br'         => array(),
 | |
|             'button'     => array(
 | |
|                 'disabled' => true,
 | |
|                 'name'     => true,
 | |
|                 'type'     => true,
 | |
|                 'value'    => true,
 | |
|             ),
 | |
|             'caption'    => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'cite'       => array(),
 | |
|             'code'       => array(),
 | |
|             'col'        => array(
 | |
|                 'align'   => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'span'    => true,
 | |
|                 'valign'  => true,
 | |
|                 'width'   => true,
 | |
|             ),
 | |
|             'colgroup'   => array(
 | |
|                 'align'   => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'span'    => true,
 | |
|                 'valign'  => true,
 | |
|                 'width'   => true,
 | |
|             ),
 | |
|             'del'        => array(
 | |
|                 'datetime' => true,
 | |
|             ),
 | |
|             'dd'         => array(),
 | |
|             'dfn'        => array(),
 | |
|             'details'    => array(
 | |
|                 'align' => true,
 | |
|                 'open'  => true,
 | |
|             ),
 | |
|             'div'        => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'dl'         => array(),
 | |
|             'dt'         => array(),
 | |
|             'em'         => array(),
 | |
|             'fieldset'   => array(),
 | |
|             'figure'     => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'figcaption' => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'font'       => array(
 | |
|                 'color' => true,
 | |
|                 'face'  => true,
 | |
|                 'size'  => true,
 | |
|             ),
 | |
|             'footer'     => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'h1'         => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'h2'         => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'h3'         => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'h4'         => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'h5'         => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'h6'         => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'header'     => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'hgroup'     => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'hr'         => array(
 | |
|                 'align'   => true,
 | |
|                 'noshade' => true,
 | |
|                 'size'    => true,
 | |
|                 'width'   => true,
 | |
|             ),
 | |
|             'i'          => array(),
 | |
|             'img'        => array(
 | |
|                 'alt'      => true,
 | |
|                 'align'    => true,
 | |
|                 'border'   => true,
 | |
|                 'height'   => true,
 | |
|                 'hspace'   => true,
 | |
|                 'loading'  => true,
 | |
|                 'longdesc' => true,
 | |
|                 'vspace'   => true,
 | |
|                 'src'      => true,
 | |
|                 'usemap'   => true,
 | |
|                 'width'    => true,
 | |
|             ),
 | |
|             'ins'        => array(
 | |
|                 'datetime' => true,
 | |
|                 'cite'     => true,
 | |
|             ),
 | |
|             'kbd'        => array(),
 | |
|             'label'      => array(
 | |
|                 'for' => true,
 | |
|             ),
 | |
|             'legend'     => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'li'         => array(
 | |
|                 'align' => true,
 | |
|                 'value' => true,
 | |
|             ),
 | |
|             'main'       => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'map'        => array(
 | |
|                 'name' => true,
 | |
|             ),
 | |
|             'mark'       => array(),
 | |
|             'menu'       => array(
 | |
|                 'type' => true,
 | |
|             ),
 | |
|             'nav'        => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'object'     => array(
 | |
|                 'data' => array(
 | |
|                     'required'       => true,
 | |
|                     'value_callback' => '_wp_kses_allow_pdf_objects',
 | |
|                 ),
 | |
|                 'type' => array(
 | |
|                     'required' => true,
 | |
|                     'values'   => array('application/pdf'),
 | |
|                 ),
 | |
|             ),
 | |
|             'p'          => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'pre'        => array(
 | |
|                 'width' => true,
 | |
|             ),
 | |
|             'q'          => array(
 | |
|                 'cite' => true,
 | |
|             ),
 | |
|             'rb'         => array(),
 | |
|             'rp'         => array(),
 | |
|             'rt'         => array(),
 | |
|             'rtc'        => array(),
 | |
|             'ruby'       => array(),
 | |
|             's'          => array(),
 | |
|             'samp'       => array(),
 | |
|             'span'       => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'section'    => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'small'      => array(),
 | |
|             'strike'     => array(),
 | |
|             'strong'     => array(),
 | |
|             'sub'        => array(),
 | |
|             'summary'    => array(
 | |
|                 'align' => true,
 | |
|             ),
 | |
|             'sup'        => array(),
 | |
|             'table'      => array(
 | |
|                 'align'       => true,
 | |
|                 'bgcolor'     => true,
 | |
|                 'border'      => true,
 | |
|                 'cellpadding' => true,
 | |
|                 'cellspacing' => true,
 | |
|                 'rules'       => true,
 | |
|                 'summary'     => true,
 | |
|                 'width'       => true,
 | |
|             ),
 | |
|             'tbody'      => array(
 | |
|                 'align'   => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'valign'  => true,
 | |
|             ),
 | |
|             'td'         => array(
 | |
|                 'abbr'    => true,
 | |
|                 'align'   => true,
 | |
|                 'axis'    => true,
 | |
|                 'bgcolor' => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'colspan' => true,
 | |
|                 'headers' => true,
 | |
|                 'height'  => true,
 | |
|                 'nowrap'  => true,
 | |
|                 'rowspan' => true,
 | |
|                 'scope'   => true,
 | |
|                 'valign'  => true,
 | |
|                 'width'   => true,
 | |
|             ),
 | |
|             'textarea'   => array(
 | |
|                 'cols'     => true,
 | |
|                 'rows'     => true,
 | |
|                 'disabled' => true,
 | |
|                 'name'     => true,
 | |
|                 'readonly' => true,
 | |
|             ),
 | |
|             'tfoot'      => array(
 | |
|                 'align'   => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'valign'  => true,
 | |
|             ),
 | |
|             'th'         => array(
 | |
|                 'abbr'    => true,
 | |
|                 'align'   => true,
 | |
|                 'axis'    => true,
 | |
|                 'bgcolor' => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'colspan' => true,
 | |
|                 'headers' => true,
 | |
|                 'height'  => true,
 | |
|                 'nowrap'  => true,
 | |
|                 'rowspan' => true,
 | |
|                 'scope'   => true,
 | |
|                 'valign'  => true,
 | |
|                 'width'   => true,
 | |
|             ),
 | |
|             'thead'      => array(
 | |
|                 'align'   => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'valign'  => true,
 | |
|             ),
 | |
|             'title'      => array(),
 | |
|             'tr'         => array(
 | |
|                 'align'   => true,
 | |
|                 'bgcolor' => true,
 | |
|                 'char'    => true,
 | |
|                 'charoff' => true,
 | |
|                 'valign'  => true,
 | |
|             ),
 | |
|             'track'      => array(
 | |
|                 'default' => true,
 | |
|                 'kind'    => true,
 | |
|                 'label'   => true,
 | |
|                 'src'     => true,
 | |
|                 'srclang' => true,
 | |
|             ),
 | |
|             'tt'         => array(),
 | |
|             'u'          => array(),
 | |
|             'ul'         => array(
 | |
|                 'type' => true,
 | |
|             ),
 | |
|             'ol'         => array(
 | |
|                 'start'    => true,
 | |
|                 'type'     => true,
 | |
|                 'reversed' => true,
 | |
|             ),
 | |
|             'var'        => array(),
 | |
|             'video'      => array(
 | |
|                 'autoplay'    => true,
 | |
|                 'controls'    => true,
 | |
|                 'height'      => true,
 | |
|                 'loop'        => true,
 | |
|                 'muted'       => true,
 | |
|                 'playsinline' => true,
 | |
|                 'poster'      => true,
 | |
|                 'preload'     => true,
 | |
|                 'src'         => true,
 | |
|                 'width'       => true,
 | |
|             ),
 | |
|         );
 | |
| 
 | |
|         $wpAllowedposttags = array_map(function ($value) {
 | |
|             $global_attributes = array(
 | |
|                 'aria-describedby' => true,
 | |
|                 'aria-details'     => true,
 | |
|                 'aria-label'       => true,
 | |
|                 'aria-labelledby'  => true,
 | |
|                 'aria-hidden'      => true,
 | |
|                 'class'            => true,
 | |
|                 'data-*'           => true,
 | |
|                 'dir'              => true,
 | |
|                 'id'               => true,
 | |
|                 'lang'             => true,
 | |
|                 'style'            => true,
 | |
|                 'title'            => true,
 | |
|                 'role'             => true,
 | |
|                 'xml:lang'         => true,
 | |
|             );
 | |
| 
 | |
|             if (true === $value) {
 | |
|                 $value = array();
 | |
|             }
 | |
| 
 | |
|             if (is_array($value)) {
 | |
|                 return array_merge($value, $global_attributes);
 | |
|             }
 | |
| 
 | |
|             return $value;
 | |
|         }, $wpAllowedposttags);
 | |
| 
 | |
| 
 | |
|         self::$basicTags = array_merge_recursive($_allowedposttags, $wpAllowedposttags, array(
 | |
|             'div'    => array(
 | |
|                 'style' => true,
 | |
|             ),
 | |
|             'script' => array(),
 | |
|         ));
 | |
| 
 | |
|         self::$adminTemplateTags = array_merge_recursive(self::$basicTags, array(
 | |
|             'svg'  => array(
 | |
|                 'xmlns'  => true,
 | |
|                 'width'  => true,
 | |
|                 'height' => true,
 | |
|             ),
 | |
|             'path' => array(
 | |
|                 'fill' => true,
 | |
|                 'd'    => true,
 | |
|             ),
 | |
|             'a'    => array(
 | |
|                 'tabindex' => true,
 | |
|                 'onclick'  => true,
 | |
|             ),
 | |
|         ));
 | |
| 
 | |
|         self::$adminFormTags = array_merge_recursive(self::$basicTags, array(
 | |
|             'input'    => array(
 | |
|                 'id'           => true,
 | |
|                 'name'         => true,
 | |
|                 'value'        => true,
 | |
|                 'type'         => true,
 | |
|                 'autocomplete' => true,
 | |
|                 'style'        => true,
 | |
|             ),
 | |
|             'div'      => array(
 | |
|                 'aria-checked' => true,
 | |
|                 'tabindex'     => true,
 | |
|             ),
 | |
|             'a'        => array(
 | |
|                 'tabindex' => true,
 | |
|             ),
 | |
|             'select'   => array(
 | |
|                 'id'              => true,
 | |
|                 'name'            => true,
 | |
|                 'aria-labelledby' => true,
 | |
|                 'autocomplete'    => true,
 | |
|                 'multiple'        => true,
 | |
|                 'size'            => true,
 | |
|             ),
 | |
|             'option'   => array(
 | |
|                 'value'    => true,
 | |
|                 'selected' => true,
 | |
|             ),
 | |
|             'optgroup' => array(
 | |
|                 'label' => true
 | |
|             ),
 | |
|             'textarea' => array(
 | |
|                 'autocomplete' => true,
 | |
|             ),
 | |
|         ));
 | |
| 
 | |
|         self::$assetTags = array(
 | |
|             'style'  => array(
 | |
|                 'data-related' => true,
 | |
|             ),
 | |
|             'link'   => array(
 | |
|                 'rel'   => true,
 | |
|                 'type'  => true,
 | |
|                 'href'  => true,
 | |
|                 'media' => true,
 | |
|             ),
 | |
|             'script' => array(
 | |
|                 'src'   => true,
 | |
|                 'defer' => true,
 | |
|                 'async' => true,
 | |
|             ),
 | |
|         );
 | |
| 
 | |
|         self::$videoTags = array(
 | |
|             'video'  => array(
 | |
|                 'muted'              => true,
 | |
|                 'loop'               => true,
 | |
|                 'class'              => true,
 | |
|                 'style'              => true,
 | |
|                 'playsinline'        => true,
 | |
|                 'webkit-playsinline' => true,
 | |
|                 'data-*'             => true,
 | |
|                 'preload'            => true,
 | |
|             ),
 | |
|             'source' => array(
 | |
|                 'src'  => true,
 | |
|                 'type' => true,
 | |
|             )
 | |
|         );
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public static function esc_js_filter($safe_text, $text) {
 | |
|         $safe_text = wp_check_invalid_utf8($text);
 | |
| 
 | |
|         return $safe_text;
 | |
|     }
 | |
| } |