web/wp-content/plugins/slideshow-jquery-image-gallery/classes/SlideshowPluginSecurity.php
changeset 204 09a1c134465b
parent 203 f507feede89a
child 205 a4f7897e21a9
equal deleted inserted replaced
203:f507feede89a 204:09a1c134465b
     1 <?php
       
     2 /**
       
     3  * The SlideshowPluginSecurity class contains functions for sanitizing in- and output.
       
     4  *
       
     5  * @author Stefan Boonstra
       
     6  * @since 2.1.16
       
     7  * @updated 2.1.16
       
     8  */
       
     9 class SlideshowPluginSecurity {
       
    10 
       
    11 	/**
       
    12 	 * @since 2.1.16
       
    13 	 * @var array List of allowed element tags
       
    14 	 */
       
    15 	private static $allowedElements = array(
       
    16 		'b' => array('endTag' => true, 'attributes' => 'default'),
       
    17 		'br' => array('endTag' => false),
       
    18 		'div' => array('endTag' => true, 'attributes' => 'default'),
       
    19 		'h1' => array('endTag' => true, 'attributes' => 'default'),
       
    20 		'h2' => array('endTag' => true, 'attributes' => 'default'),
       
    21 		'h3' => array('endTag' => true, 'attributes' => 'default'),
       
    22 		'h4' => array('endTag' => true, 'attributes' => 'default'),
       
    23 		'h5' => array('endTag' => true, 'attributes' => 'default'),
       
    24 		'h6' => array('endTag' => true, 'attributes' => 'default'),
       
    25 		'i' => array('endTag' => true, 'attributes' => 'default'),
       
    26 		'li' => array('endTag' => true, 'attributes' => 'default'),
       
    27 		'ol' => array('endTag' => true, 'attributes' => 'default'),
       
    28 		'p' => array('endTag' => true, 'attributes' => 'default'),
       
    29 		'span' => array('endTag' => true, 'attributes' => 'default'),
       
    30 		'strong' => array('endTag' => true, 'attributes' => 'default'),
       
    31 		'sub' => array('endTag' => true, 'attributes' => 'default'),
       
    32 		'sup' => array('endTag' => true, 'attributes' => 'default'),
       
    33 		'table' => array('endTag' => true, 'attributes' => 'default'),
       
    34 		'tbody' => array('endTag' => true, 'attributes' => 'default'),
       
    35 		'td' => array('endTag' => true, 'attributes' => 'default'),
       
    36 		'tfoot' => array('endTag' => true, 'attributes' => 'default'),
       
    37 		'th' => array('endTag' => true, 'attributes' => 'default'),
       
    38 		'thead' => array('endTag' => true, 'attributes' => 'default'),
       
    39 		'tr' => array('endTag' => true, 'attributes' => 'default'),
       
    40 		'ul' => array('endTag' => true, 'attributes' => 'default')
       
    41 	);
       
    42 
       
    43 	/**
       
    44 	 * @since 2.1.16
       
    45 	 * @var array List of attributes allowed in the tags
       
    46 	 */
       
    47 	private static $defaultAllowedAttributes = array(
       
    48 		'class',
       
    49 		'id',
       
    50 		'style'
       
    51 	);
       
    52 
       
    53 	/**
       
    54 	 * Similar to the htmlspecialchars($text) function, except this function
       
    55 	 * allows the exceptions defined in this class.
       
    56 	 *
       
    57 	 * @since 2.1.16
       
    58 	 * @updated 2.1.16
       
    59 	 */
       
    60 	static function htmlspecialchars_allow_exceptions($text){
       
    61 		$text = htmlspecialchars(htmlspecialchars_decode($text));
       
    62 
       
    63 		$allowedElements = self::$allowedElements;
       
    64 
       
    65 		// Loop through allowed elements decoding their HTML special chars and allowed attributes.
       
    66 		if(is_array($allowedElements) && count($allowedElements) > 0){
       
    67 			foreach($allowedElements as $element => $attributes){
       
    68 
       
    69 				$position = 0;
       
    70 
       
    71 				while(($position = stripos($text, $element, $position)) !== false){ // While element tags found
       
    72 
       
    73 					$openingTag = '<';
       
    74 					$encodedOpeningTag = htmlspecialchars($openingTag);
       
    75 
       
    76 					if(substr($text, $position - strlen($encodedOpeningTag), strlen($encodedOpeningTag)) == $encodedOpeningTag){ // Check if an opening tag '<' can be found before the tag name
       
    77 
       
    78 						// Replace encoded opening tag
       
    79 						$text = substr_replace($text, '<', $position - strlen($encodedOpeningTag), strlen($encodedOpeningTag));
       
    80 						$position -= strlen($encodedOpeningTag) - strlen($openingTag);
       
    81 
       
    82 						// Get the position of the first element closing tag
       
    83 						$closingTag = '>';
       
    84 						$encodedClosingTag = htmlspecialchars($closingTag);
       
    85 						$closingTagPosition = stripos($text, $encodedClosingTag, $position);
       
    86 
       
    87 						// Replace encoded closing tag
       
    88 						if($closingTagPosition !== false)
       
    89 							$text = substr_replace($text, '>', $closingTagPosition, strlen($encodedClosingTag));
       
    90 
       
    91 						$elementAttributes = null;
       
    92 						if(isset($attributes['attributes']) && is_array($attributes['attributes']))
       
    93 							$elementAttributes = $attributes['attributes'];
       
    94 						elseif(isset($attributes['attributes']) && $attributes['attributes'] == 'default')
       
    95 							$elementAttributes = self::$defaultAllowedAttributes;
       
    96 						else
       
    97 							continue;
       
    98 
       
    99 						if(!is_array($elementAttributes))
       
   100 							continue;
       
   101 
       
   102 						$tagText = substr($text, $position, $closingTagPosition - $position);
       
   103 
       
   104 						// Decode allowed attributes
       
   105 						foreach($elementAttributes as $attribute){
       
   106 
       
   107 							$attributeOpener = $attribute . '=' . htmlspecialchars('"');
       
   108 
       
   109 							$attributePosition = 0;
       
   110 							if(($attributePosition = stripos($tagText, $attributeOpener, $attributePosition)) !== false){ // Attribute was found
       
   111 
       
   112 								$attributeClosingPosition = 0;
       
   113 								if(($attributeClosingPosition = stripos($tagText, htmlspecialchars('"'), $attributePosition + strlen($attributeOpener))) === false) // If no closing position of attribute was found, skip.
       
   114 									continue;
       
   115 
       
   116 								// Open the attribute
       
   117 								$tagText = str_ireplace($attributeOpener, $attribute . '="', $tagText);
       
   118 
       
   119 								// Close the attribute
       
   120 								$attributeClosingPosition -= strlen($attributeOpener) - strlen($attribute . '="');
       
   121 								$tagText = substr_replace($tagText, '"', $attributeClosingPosition, strlen(htmlspecialchars('"')));
       
   122 							}
       
   123 
       
   124 						}
       
   125 
       
   126 						// Put the attributes of the tag back in place
       
   127 						$text = substr_replace($text, $tagText, $position, $closingTagPosition - $position);
       
   128 					}
       
   129 
       
   130 					$position++;
       
   131 				}
       
   132 
       
   133 				// Decode closing tags
       
   134 				if(isset($attributes['endTag']) && $attributes['endTag'])
       
   135 					$text = str_ireplace(htmlspecialchars('</' . $element . '>'), '</' . $element . '>', $text);
       
   136 			}
       
   137 		}
       
   138 
       
   139 		return $text;
       
   140 	}
       
   141 }