. class Misc { public $mode; // XSS-unsafe characters to search for protected $searchXSS = array ( '&', '<', '>', '"', "'", '/', '\\' ); // XSS-safe replacement character entities protected $replaceXSS = array ( '&', '<', '>', '"', ''', '/', '\' ); // Allowed JavaScript constructors protected $objects = array ( 'HashOver', 'HashOverCountLink', 'HashOverLatest' ); public function __construct ($mode) { $this->mode = $mode; } // Return JSON or JSONP function call public function jsonData ($data, $self_error = false) { // Encode JSON data $json = json_encode ($data); // Return JSON as-is if the request isn't for JSONP if (!isset ($_GET['jsonp']) or !isset ($_GET['jsonp_object'])) { return $json; } // Otherwise, make JSONP callback index XSS safe $index = $this->makeXSSsafe ($_GET['jsonp']); // Make JSONP object constructor name XSS safe $object = $this->makeXSSsafe ($_GET['jsonp_object']); // Check if constructor is allowed, if not use default $allowed_object = in_array ($object, $this->objects, true); $object = $allowed_object ? $object : 'HashOver'; // Check if the JSONP index contains a numeric value if (is_numeric ($index) or $self_error === true) { // If so, cast index to positive integer $index = ($self_error === true) ? 0 : (int)(abs ($index)); // Construct JSONP function call $jsonp = sprintf ('%s.jsonp[%d] (%s);', $object, $index, $json); // And return the JSONP script return $jsonp; } // Otherwise, return an error return $this->jsonData (array ( 'message' => 'JSONP index must have a numeric value.', 'type' => 'error' ), true); } // Make a string XSS-safe public function makeXSSsafe ($string) { // Return cookie value without harmful characters return str_replace ($this->searchXSS, $this->replaceXSS, $string); } // Returns error in HTML paragraph public function displayError ($error = 'Something went wrong!') { $xss_safe = $this->makeXSSsafe ($error); $data = array (); switch ($this->mode) { // Minimal JavaScript to display error message on page case 'javascript': { $data[] = 'var hashover = document.getElementById (\'hashover\') || document.body;'; $data[] = 'var error = \'

HashOver: ' . $xss_safe . '

\';' . PHP_EOL; $data[] = 'hashover.innerHTML += error;'; break; } // RSS XML to indicate error case 'rss': { $data[] = ''; $data[] = 'HashOver: ' . $xss_safe . ''; break; } // JSON to indicate error case 'json': { $data[] = $this->jsonData (array ( 'message' => $error, 'type' => 'error' )); break; } // Default just return the error message default: { $data[] = '

HashOver: ' . $error . '

'; break; } } echo implode (PHP_EOL, $data); } }