keep-alive [HTTP_X_REQUESTED_WITH] => XMLHttpRequest [HTTP_X_PROTOTYPE_VERSION] => 1.7_rc2 */ //&& ( strpos($_SERVER['CONTENT_TYPE'],"multipart/form-data")!==false ) if((!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || !$_SERVER['HTTP_X_REQUESTED_WITH']) && ( strpos($_SERVER['SCRIPT_FILENAME'],"server.php") !== false ) ){ return true; } else{ return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')); } } class DitRequest{ static function getMethod(){ return strtoupper( $_SERVER['REQUEST_METHOD'] ); } static function getVar($name, $default = null, $hash = 'default', $type = 'none', $mask = 0){ // Ensure hash and type are uppercase $hash = strtoupper( $hash ); if ($hash === 'METHOD') { $hash = DitRequest::getMethod(); } $type = strtoupper( $type ); $sig = $hash.$type.$mask; // Get the input hash switch ($hash) { case 'GET' : $input = &$_GET; break; case 'POST' : $input = &$_POST; break; case 'FILES' : $input = &$_FILES; break; case 'COOKIE' : $input = &$_COOKIE; break; case 'ENV' : $input = &$_ENV; break; case 'SERVER' : $input = &$_SERVER; break; default: $input = &$_REQUEST; $hash = 'REQUEST'; break; } if (isset($GLOBALS['_DITREQUEST'][$name]['SET.'.$hash]) && ($GLOBALS['_DITREQUEST'][$name]['SET.'.$hash] === true)) { // Get the variable from the input hash if(isset($input[$name]) && $input[$name] !== null && is_array($input[$name])){ $var = $input[$name]; foreach($var as $ik => $iv){ $iv = DitRequest::_cleanVar($iv, $mask, $type); } } else{ $var = (isset($input[$name]) && $input[$name] !== null) ? $input[$name] : $default; $var = DitRequest::_cleanVar($var, $mask, $type); } } elseif (!isset($GLOBALS['_DITREQUEST'][$name][$sig])) { if (isset($input[$name]) && $input[$name] !== null) { // Get the variable from the input hash and clean it if(is_array($input[$name])){ $var = $input[$name]; foreach($var as $ik => $iv){ $iv = DitRequest::_cleanVar($iv, $mask, $type); if (get_magic_quotes_gpc() && ($iv != $default) && ($hash != 'FILES')) { $iv = DitRequest::_stripSlashesRecursive( $iv ); } } } else{ $var = DitRequest::_cleanVar($input[$name], $mask, $type); // Handle magic quotes compatability if (get_magic_quotes_gpc() && ($var != $default) && ($hash != 'FILES')) { $var = DitRequest::_stripSlashesRecursive( $var ); } } $GLOBALS['_DITREQUEST'][$name][$sig] = $var; } elseif ($default !== null) { // Clean the default value $var = DitRequest::_cleanVar($default, $mask, $type); } else { $var = $default; } } else { $var = $GLOBALS['_DITREQUEST'][$name][$sig]; } return $var; } function getInteger($name, $default = 0, $hash = 'default'){ $var = DitRequest::getVar($name, $default, $hash, 'int'); if(is_array($var)){ return $var; } return $var; } function getInt($name, $default = 0, $hash = 'default'){ $var = DitRequest::getVar($name, $default, $hash, 'int'); if(is_array($var)){ return $var; } return $var; } function getFloat($name, $default = 0.0, $hash = 'default'){ $var = DitRequest::getVar($name, $default, $hash, 'float'); if(is_array($var)){ return $var; } return $var; } function getBool($name, $default = false, $hash = 'default'){ $var = DitRequest::getVar($name, $default, $hash, 'bool'); if(is_array($var)){ return $var; } return $var; } function getWord($name, $default = '', $hash = 'default'){ return DitRequest::getVar($name, $default, $hash, 'word'); } function getCmd($name, $default = '', $hash = 'default'){ return DitRequest::getVar($name, $default, $hash, 'cmd'); } function getString($name, $default = '', $hash = 'default', $mask = 0, $is_array = false){ // Cast to string, in case JREQUEST_ALLOWRAW was specified for mask $var = DitRequest::getVar($name, $default, $hash, 'string', $mask); //echo $var; if(is_array($var)){ return $var; } return (string) $var; //return (string) DitRequest::getVar($name, $default, $hash, 'string', $mask); } /** * Set a variabe in on of the request variables * * @access public * @param string $name Name * @param string $value Value * @param string $hash Hash * @param boolean $overwrite Boolean * @return string Previous value * @since 1.5 */ function setVar($name, $value = null, $hash = 'method', $overwrite = true) { //If overwrite is true, makes sure the variable hasn't been set yet if(!$overwrite && array_key_exists($name, $_REQUEST)) { return $_REQUEST[$name]; } // Clean global request var $GLOBALS['_DITREQUEST'][$name] = array(); // Get the request hash value $hash = strtoupper($hash); if ($hash === 'METHOD') { $hash = DitRequest::getMethod(); } $previous = array_key_exists($name, $_REQUEST) ? $_REQUEST[$name] : null; switch ($hash) { case 'GET' : $_GET[$name] = $value; $_REQUEST[$name] = $value; break; case 'POST' : $_POST[$name] = $value; $_REQUEST[$name] = $value; break; case 'COOKIE' : $_COOKIE[$name] = $value; $_REQUEST[$name] = $value; break; case 'FILES' : $_FILES[$name] = $value; break; case 'ENV' : $_ENV['name'] = $value; break; case 'SERVER' : $_SERVER['name'] = $value; break; } // Mark this variable as 'SET' $GLOBALS['_DITREQUEST'][$name]['SET.'.$hash] = true; $GLOBALS['_DITREQUEST'][$name]['SET.REQUEST'] = true; return $previous; } /** * Fetches and returns a request array. * * The default behaviour is fetching variables depending on the * current request method: GET and HEAD will result in returning * $_GET, POST and PUT will result in returning $_POST. * * You can force the source by setting the $hash parameter: * * post $_POST * get $_GET * files $_FILES * cookie $_COOKIE * env $_ENV * server $_SERVER * method via current $_SERVER['REQUEST_METHOD'] * default $_REQUEST * * @static * @param string $hash to get (POST, GET, FILES, METHOD) * @param int $mask Filter mask for the variable * @return mixed Request hash * @since 1.5 */ function get($hash = 'default', $mask = 0) { $hash = strtoupper($hash); if ($hash === 'METHOD') { $hash = DitRequest::getMethod(); } switch ($hash) { case 'GET' : $input = $_GET; break; case 'POST' : $input = $_POST; break; case 'FILES' : $input = $_FILES; break; case 'COOKIE' : $input = $_COOKIE; break; case 'ENV' : $input = &$_ENV; break; case 'SERVER' : $input = &$_SERVER; break; default: $input = $_REQUEST; break; } $result = DitRequest::_cleanVar($input, $mask); // Handle magic quotes compatability if (get_magic_quotes_gpc() && ($hash != 'FILES')) { $result = DitRequest::_stripSlashesRecursive( $result ); } return $result; } /** * Sets a request variable * * @param array An associative array of key-value pairs * @param string The request variable to set (POST, GET, FILES, METHOD) * @param boolean If true and an existing key is found, the value is overwritten, otherwise it is ingored */ function set( $array, $hash = 'default', $overwrite = true ) { foreach ($array as $key => $value) { DitRequest::setVar($key, $value, $hash, $overwrite); } } /** * Cleans the request from script injection. */ function clean() { DitRequest::_cleanArray( $_FILES ); DitRequest::_cleanArray( $_ENV ); DitRequest::_cleanArray( $_GET ); DitRequest::_cleanArray( $_POST ); DitRequest::_cleanArray( $_COOKIE ); DitRequest::_cleanArray( $_SERVER ); if (isset( $_SESSION )) { DitRequest::_cleanArray( $_SESSION ); } $REQUEST = $_REQUEST; $GET = $_GET; $POST = $_POST; $COOKIE = $_COOKIE; $FILES = $_FILES; $ENV = $_ENV; $SERVER = $_SERVER; if (isset ( $_SESSION )) { $SESSION = $_SESSION; } foreach ($GLOBALS as $key => $value) { if ( $key != 'GLOBALS' ) { unset ( $GLOBALS [ $key ] ); } } $_REQUEST = $REQUEST; $_GET = $GET; $_POST = $POST; $_COOKIE = $COOKIE; $_FILES = $FILES; $_ENV = $ENV; $_SERVER = $SERVER; if (isset ( $SESSION )) { $_SESSION = $SESSION; } // Make sure the request hash is clean on file inclusion $GLOBALS['_DITREQUEST'] = array(); } /** * Adds an array to the GLOBALS array and checks that the GLOBALS variable is not being attacked * * @access protected * @param array $array Array to clean * @param boolean True if the array is to be added to the GLOBALS * @since 1.5 */ function _cleanArray( &$array, $globalise=false ) { static $banned = array( '_files', '_env', '_get', '_post', '_cookie', '_server', '_session', 'globals' ); foreach ($array as $key => $value) { // PHP GLOBALS injection bug $failed = in_array( strtolower( $key ), $banned ); // PHP Zend_Hash_Del_Key_Or_Index bug $failed |= is_numeric( $key ); if ($failed) { //jexit( 'Illegal variable ' . implode( ' or ', $banned ) . ' passed to script.' ); } if ($globalise) { $GLOBALS[$key] = $value; } } } /** * Clean up an input variable. * * @param mixed The input variable. * @param int Filter bit mask. 1=no trim: If this flag is cleared and the * input is a string, the string will have leading and trailing whitespace * trimmed. 2=allow_raw: If set, no more filtering is performed, higher bits * are ignored. 4=allow_html: HTML is allowed, but passed through a safe * HTML filter first. If set, no more filtering is performed. If no bits * other than the 1 bit is set, a strict filter is applied. * @param string The variable type {@see JFilterInput::clean()}. */ function _cleanVar($var, $mask = 0, $type=null) { // Static input filters for specific settings static $noHtmlFilter = null; static $safeHtmlFilter = null; // If the no trim flag is not set, trim the variable if (!($mask & 1) && is_string($var)) { $var = trim($var); } // Now we handle input filtering if ($mask & 2) { // If the allow raw flag is set, do not modify the variable $var = $var; } elseif ($mask & 4) { // If the allow html flag is set, apply a safe html filter to the variable if (is_null($safeHtmlFilter)) { $safeHtmlFilter = & DitFilterInput::getInstance(null, null, 1, 1); } $var = $safeHtmlFilter->clean($var, $type); } else { // Since no allow flags were set, we will apply the most strict filter to the variable if (is_null($noHtmlFilter)) { $noHtmlFilter = & DitFilterInput::getInstance(/* $tags, $attr, $tag_method, $attr_method, $xss_auto */); } $var = $noHtmlFilter->clean($var, $type); } return $var; } /** * Strips slashes recursively on an array * * @access protected * @param array $array Array of (nested arrays of) strings * @return array The input array with stripshlashes applied to it */ function _stripSlashesRecursive( $value ) { $value = is_array( $value ) ? array_map( array( 'JRequest', '_stripSlashesRecursive' ), $value ) : stripslashes( $value ); return $value; } } class DitFilterInput { var $tagsArray; // default = empty array var $attrArray; // default = empty array var $tagsMethod; // default = 0 var $attrMethod; // default = 0 var $xssAuto; // default = 1 var $tagBlacklist = array ('applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml'); var $attrBlacklist = array ('action', 'background', 'codebase', 'dynsrc', 'lowsrc'); // also will strip ALL event handlers /** * Constructor for inputFilter class. Only first parameter is required. * * @access protected * @param array $tagsArray list of user-defined tags * @param array $attrArray list of user-defined attributes * @param int $tagsMethod WhiteList method = 0, BlackList method = 1 * @param int $attrMethod WhiteList method = 0, BlackList method = 1 * @param int $xssAuto Only auto clean essentials = 0, Allow clean blacklisted tags/attr = 1 * @since 1.5 */ function __construct($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1) { // Make sure user defined arrays are in lowercase $tagsArray = array_map('strtolower', (array) $tagsArray); $attrArray = array_map('strtolower', (array) $attrArray); // Assign member variables $this->tagsArray = $tagsArray; $this->attrArray = $attrArray; $this->tagsMethod = $tagsMethod; $this->attrMethod = $attrMethod; $this->xssAuto = $xssAuto; } /** * Returns a reference to an input filter object, only creating it if it doesn't already exist. * * This method must be invoked as: *
  $filter = & JFilterInput::getInstance();
* * @static * @param array $tagsArray list of user-defined tags * @param array $attrArray list of user-defined attributes * @param int $tagsMethod WhiteList method = 0, BlackList method = 1 * @param int $attrMethod WhiteList method = 0, BlackList method = 1 * @param int $xssAuto Only auto clean essentials = 0, Allow clean blacklisted tags/attr = 1 * @return object The JFilterInput object. * @since 1.5 */ function & getInstance($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1) { static $instances; $sig = md5(serialize(array($tagsArray,$attrArray,$tagsMethod,$attrMethod,$xssAuto))); if (!isset ($instances)) { $instances = array(); } if (empty ($instances[$sig])) { $instances[$sig] = new DitFilterInput($tagsArray, $attrArray, $tagsMethod, $attrMethod, $xssAuto); } return $instances[$sig]; } /** * Method to be called by another php script. Processes for XSS and * specified bad code. * * @access public * @param mixed $source Input string/array-of-string to be 'cleaned' * @param string $type Return type for the variable (INT, FLOAT, BOOLEAN, WORD, ALNUM, CMD, BASE64, STRING, ARRAY, PATH, NONE) * @return mixed 'Cleaned' version of input parameter * @since 1.5 * @static */ function clean($source, $type='string') { // Handle the type constraint switch (strtoupper($type)) { case 'INT' : case 'INTEGER' : // Only use the first integer value preg_match('/-?[0-9]+/', (string) $source, $matches); $result = @ (int) $matches[0]; break; case 'FLOAT' : case 'DOUBLE' : // Only use the first floating point value $float = str_replace(",",".",(string) $source); preg_match('/-?[0-9]+(\.[0-9]+)?/', $float, $matches); $result = @ (float) $matches[0]; break; case 'BOOL' : case 'BOOLEAN' : $result = (bool) $source; break; case 'WORD' : $result = (string) preg_replace( '/[^A-Z_]/i', '', $source ); break; case 'ALNUM' : $result = (string) preg_replace( '/[^A-Z0-9]/i', '', $source ); break; case 'CMD' : $result = (string) preg_replace( '/[^A-Z0-9_\.-]/i', '', $source ); $result = ltrim($result, '.'); break; case 'BASE64' : $result = (string) preg_replace( '/[^A-Z0-9\/+=]/i', '', $source ); break; case 'STRING' : // Check for static usage and assign $filter the proper variable if(isset($this) && is_a( $this, 'DitFilterInput' )) { $filter =& $this; } else { $filter =& DitFilterInput::getInstance(); } $result = (string) $filter->_remove($filter->_decode((string) $source)); break; case 'ARRAY' : $result = (array) $source; break; case 'PATH' : $pattern = '/^[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*([\\\\\/][A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$/'; preg_match($pattern, (string) $source, $matches); $result = @ (string) $matches[0]; break; case 'USERNAME' : $result = (string) preg_replace( '/[\x00-\x1F\x7F<>"\'%&]/', '', $source ); break; default : // Check for static usage and assign $filter the proper variable if(is_object($this) && get_class($this) == 'DitFilterInput') { $filter =& $this; } else { $filter =& DitFilterInput::getInstance(); } // Are we dealing with an array? if (is_array($source)) { foreach ($source as $key => $value) { // filter element for XSS and other 'bad' code etc. if (is_string($value)) { $source[$key] = $filter->_remove($filter->_decode($value)); } } $result = $source; } else { // Or a string? if (is_string($source) && !empty ($source)) { // filter source for XSS and other 'bad' code etc. $result = $filter->_remove($filter->_decode($source)); } else { // Not an array or string.. return the passed parameter $result = $source; } } break; } return $result; } /** * Function to determine if contents of an attribute is safe * * @static * @param array $attrSubSet A 2 element array for attributes name,value * @return boolean True if bad code is detected * @since 1.5 */ function checkAttribute($attrSubSet) { $attrSubSet[0] = strtolower($attrSubSet[0]); $attrSubSet[1] = strtolower($attrSubSet[1]); return (((strpos($attrSubSet[1], 'expression') !== false) && ($attrSubSet[0]) == 'style') || (strpos($attrSubSet[1], 'javascript:') !== false) || (strpos($attrSubSet[1], 'behaviour:') !== false) || (strpos($attrSubSet[1], 'vbscript:') !== false) || (strpos($attrSubSet[1], 'mocha:') !== false) || (strpos($attrSubSet[1], 'livescript:') !== false)); } /** * Internal method to iteratively remove all unwanted tags and attributes * * @access protected * @param string $source Input string to be 'cleaned' * @return string 'Cleaned' version of input parameter * @since 1.5 */ function _remove($source) { $loopCounter = 0; // Iteration provides nested tag protection while ($source != $this->_cleanTags($source)) { $source = $this->_cleanTags($source); $loopCounter ++; } return $source; } /** * Internal method to strip a string of certain tags * * @access protected * @param string $source Input string to be 'cleaned' * @return string 'Cleaned' version of input parameter * @since 1.5 */ function _cleanTags($source) { /* * In the beginning we don't really have a tag, so everything is * postTag */ $preTag = null; $postTag = $source; $currentSpace = false; $attr = ''; // moffats: setting to null due to issues in migration system - undefined variable errors // Is there a tag? If so it will certainly start with a '<' $tagOpen_start = strpos($source, '<'); while ($tagOpen_start !== false) { // Get some information about the tag we are processing $preTag .= substr($postTag, 0, $tagOpen_start); $postTag = substr($postTag, $tagOpen_start); $fromTagOpen = substr($postTag, 1); $tagOpen_end = strpos($fromTagOpen, '>'); // Let's catch any non-terminated tags and skip over them if ($tagOpen_end === false) { $postTag = substr($postTag, $tagOpen_start +1); $tagOpen_start = strpos($postTag, '<'); continue; } // Do we have a nested tag? $tagOpen_nested = strpos($fromTagOpen, '<'); $tagOpen_nested_end = strpos(substr($postTag, $tagOpen_end), '>'); if (($tagOpen_nested !== false) && ($tagOpen_nested < $tagOpen_end)) { $preTag .= substr($postTag, 0, ($tagOpen_nested +1)); $postTag = substr($postTag, ($tagOpen_nested +1)); $tagOpen_start = strpos($postTag, '<'); continue; } // Lets get some information about our tag and setup attribute pairs $tagOpen_nested = (strpos($fromTagOpen, '<') + $tagOpen_start +1); $currentTag = substr($fromTagOpen, 0, $tagOpen_end); $tagLength = strlen($currentTag); $tagLeft = $currentTag; $attrSet = array (); $currentSpace = strpos($tagLeft, ' '); // Are we an open tag or a close tag? if (substr($currentTag, 0, 1) == '/') { // Close Tag $isCloseTag = true; list ($tagName) = explode(' ', $currentTag); $tagName = substr($tagName, 1); } else { // Open Tag $isCloseTag = false; list ($tagName) = explode(' ', $currentTag); } /* * Exclude all "non-regular" tagnames * OR no tagname * OR remove if xssauto is on and tag is blacklisted */ if ((!preg_match("/^[a-z][a-z0-9]*$/i", $tagName)) || (!$tagName) || ((in_array(strtolower($tagName), $this->tagBlacklist)) && ($this->xssAuto))) { $postTag = substr($postTag, ($tagLength +2)); $tagOpen_start = strpos($postTag, '<'); // Strip tag continue; } /* * Time to grab any attributes from the tag... need this section in * case attributes have spaces in the values. */ while ($currentSpace !== false) { $attr = ''; $fromSpace = substr($tagLeft, ($currentSpace +1)); $nextSpace = strpos($fromSpace, ' '); $openQuotes = strpos($fromSpace, '"'); $closeQuotes = strpos(substr($fromSpace, ($openQuotes +1)), '"') + $openQuotes +1; // Do we have an attribute to process? [check for equal sign] if (strpos($fromSpace, '=') !== false) { /* * If the attribute value is wrapped in quotes we need to * grab the substring from the closing quote, otherwise grab * till the next space */ if (($openQuotes !== false) && (strpos(substr($fromSpace, ($openQuotes +1)), '"') !== false)) { $attr = substr($fromSpace, 0, ($closeQuotes +1)); } else { $attr = substr($fromSpace, 0, $nextSpace); } } else { /* * No more equal signs so add any extra text in the tag into * the attribute array [eg. checked] */ if ($fromSpace != '/') { $attr = substr($fromSpace, 0, $nextSpace); } } // Last Attribute Pair if (!$attr && $fromSpace != '/') { $attr = $fromSpace; } // Add attribute pair to the attribute array $attrSet[] = $attr; // Move search point and continue iteration $tagLeft = substr($fromSpace, strlen($attr)); $currentSpace = strpos($tagLeft, ' '); } // Is our tag in the user input array? $tagFound = in_array(strtolower($tagName), $this->tagsArray); // If the tag is allowed lets append it to the output string if ((!$tagFound && $this->tagsMethod) || ($tagFound && !$this->tagsMethod)) { // Reconstruct tag with allowed attributes if (!$isCloseTag) { // Open or Single tag $attrSet = $this->_cleanAttributes($attrSet); $preTag .= '<'.$tagName; for ($i = 0; $i < count($attrSet); $i ++) { $preTag .= ' '.$attrSet[$i]; } // Reformat single tags to XHTML if (strpos($fromTagOpen, ''; } else { $preTag .= ' />'; } } else { // Closing Tag $preTag .= ''; } } // Find next tag's start and continue iteration $postTag = substr($postTag, ($tagLength +2)); $tagOpen_start = strpos($postTag, '<'); } // Append any code after the end of tags and return if ($postTag != '<') { $preTag .= $postTag; } return $preTag; } /** * Internal method to strip a tag of certain attributes * * @access protected * @param array $attrSet Array of attribute pairs to filter * @return array Filtered array of attribute pairs * @since 1.5 */ function _cleanAttributes($attrSet) { // Initialize variables $newSet = array(); // Iterate through attribute pairs for ($i = 0; $i < count($attrSet); $i ++) { // Skip blank spaces if (!$attrSet[$i]) { continue; } // Split into name/value pairs $attrSubSet = explode('=', trim($attrSet[$i]), 2); list ($attrSubSet[0]) = explode(' ', $attrSubSet[0]); /* * Remove all "non-regular" attribute names * AND blacklisted attributes */ if ((!preg_match('/[a-z]*$/i', $attrSubSet[0])) || (($this->xssAuto) && ((in_array(strtolower($attrSubSet[0]), $this->attrBlacklist)) || (substr($attrSubSet[0], 0, 2) == 'on')))) { continue; } // XSS attribute value filtering if ($attrSubSet[1]) { // strips unicode, hex, etc $attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]); // strip normal newline within attr value $attrSubSet[1] = preg_replace('/[\n\r]/', '', $attrSubSet[1]); // strip double quotes $attrSubSet[1] = str_replace('"', '', $attrSubSet[1]); // convert single quotes from either side to doubles (Single quotes shouldn't be used to pad attr value) if ((substr($attrSubSet[1], 0, 1) == "'") && (substr($attrSubSet[1], (strlen($attrSubSet[1]) - 1), 1) == "'")) { $attrSubSet[1] = substr($attrSubSet[1], 1, (strlen($attrSubSet[1]) - 2)); } // strip slashes $attrSubSet[1] = stripslashes($attrSubSet[1]); } // Autostrip script tags if (DitFilterInput::checkAttribute($attrSubSet)) { continue; } // Is our attribute in the user input array? $attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray); // If the tag is allowed lets keep it if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod)) { // Does the attribute have a value? if ($attrSubSet[1]) { $newSet[] = $attrSubSet[0].'="'.$attrSubSet[1].'"'; } elseif ($attrSubSet[1] == "0") { /* * Special Case * Is the value 0? */ $newSet[] = $attrSubSet[0].'="0"'; } else { $newSet[] = $attrSubSet[0].'="'.$attrSubSet[0].'"'; } } } return $newSet; } /** * Try to convert to plaintext * * @access protected * @param string $source * @return string Plaintext string * @since 1.5 */ function _decode($source) { // entity decode $trans_tbl = get_html_translation_table(HTML_ENTITIES); foreach($trans_tbl as $k => $v) { $ttr[$v] = utf8_encode($k); } $source = strtr($source, $ttr); // convert decimal $source = preg_replace('/&#(\d+);/me', "utf8_encode(chr(\\1))", $source); // decimal notation // convert hex $source = preg_replace('/&#x([a-f0-9]+);/mei', "utf8_encode(chr(0x\\1))", $source); // hex notation return $source; } } ?>