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;
|
||
|
}
|
||
|
}
|