Skip to content

Instantly share code, notes, and snippets.

@HLeithner
Created April 10, 2020 12:55
Show Gist options
  • Save HLeithner/90c36ea1a732207b87b8b4004ff5e21d to your computer and use it in GitHub Desktop.
Save HLeithner/90c36ea1a732207b87b8b4004ff5e21d to your computer and use it in GitHub Desktop.
<?php
/**
* Part of the Joomla Framework Input Package
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
namespace Joomla\Input;
use Joomla\Filter;
/**
* Joomla! Input Base Class
*
* This is an abstracted input class used to manage retrieving data from the application environment.
*
* @since 1.0
*
* @property-read Input $get
* @property-read Input $post
* @property-read Input $request
* @property-read Input $server
* @property-read Input $env
* @property-read Files $files
* @property-read Cookie $cookie
*
* @method integer getInt($name, $default = null) Get a signed integer.
* @method integer getUint($name, $default = null) Get an unsigned integer.
* @method float getFloat($name, $default = null) Get a floating-point number.
* @method boolean getBool($name, $default = null) Get a boolean value.
* @method string getWord($name, $default = null) Get a word.
* @method string getAlnum($name, $default = null) Get an alphanumeric string.
* @method string getCmd($name, $default = null) Get a CMD filtered string.
* @method string getBase64($name, $default = null) Get a base64 encoded string.
* @method string getString($name, $default = null) Get a string.
* @method string getHtml($name, $default = null) Get a HTML string.
* @method string getPath($name, $default = null) Get a file path.
* @method string getUsername($name, $default = null) Get a username.
*/
class Input implements \Serializable, \Countable
{
/**
* Gets a value from the input data.
*
* @param string $name Name of the value to get.
* @param mixed $default Default value to return if variable does not exist.
* @param string $filter Filter to apply to the value.
*
* @return mixed The filtered input value.
*
* @see \Joomla\Filter\InputFilter::clean()
* @since 1.0
*/
public function get($name, $default = null, $filter = 'cmd', $asArray = null)
{
if (isset($this->data[$name]))
{
return $this->filter->clean($this->data[$name], $filter, $asArray);
}
return $default;
}
}
class InputFilter
{
/**
* Constructor for InputFilter class.
*
* @param array $tagsArray List of user-defined tags
* @param array $attrArray List of user-defined attributes
* @param integer $tagsMethod WhiteList method = 0, BlackList method = 1
* @param integer $attrMethod WhiteList method = 0, BlackList method = 1
* @param integer $xssAuto Only auto clean essentials = 0, Allow clean blacklisted tags/attr = 1
/**
* Method to be called by another php script. Processes for XSS and
* specified bad code.
*
* @param mixed $source Input string/array-of-string to be 'cleaned'
* @param string $type The return type for the variable:
* INT: An integer, or an array of integers,
* UINT: An unsigned integer, or an array of unsigned integers,
* FLOAT: A floating point number, or an array of floating point numbers,
* BOOLEAN: A boolean value,
* WORD: A string containing A-Z or underscores only (not case sensitive),
* ALNUM: A string containing A-Z or 0-9 only (not case sensitive),
* CMD: A string containing A-Z, 0-9, underscores, periods or hyphens (not case sensitive),
* BASE64: A string containing A-Z, 0-9, forward slashes, plus or equals (not case sensitive),
* STRING: A fully decoded and sanitised string (default),
* HTML: A sanitised string,
* ARRAY: An array,
* PATH: A sanitised file path, or an array of sanitised file paths,
* TRIM: A string trimmed from normal, non-breaking and multibyte spaces
* USERNAME: Do not use (use an application specific filter),
* RAW: The raw string is returned with no filtering,
* unknown: An unknown filter will act like STRING. If the input is an array it will return an
* array of fully decoded and sanitised strings.
*
* @return mixed 'Cleaned' version of input parameter
*
* @since 1.0
*/
public function clean($source, $type = 'string', $asArray = null)
{
if ($asArray === null)
{
// Throw deprecation warning
$asArray = false;
}
// Handle the type constraint cases
switch (strtoupper($type))
{
case 'INT':
case 'INTEGER':
$pattern = '/[-+]?[0-9]+/';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
preg_match($pattern, (string) $eachString, $matches);
$result[] = isset($matches[0]) ? (int) $matches[0] : 0;
}
}
else
{
preg_match($pattern, (string) $source, $matches);
$result = isset($matches[0]) ? (int) $matches[0] : 0;
}
break;
case 'UINT':
$pattern = '/[-+]?[0-9]+/';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
preg_match($pattern, (string) $eachString, $matches);
$result[] = isset($matches[0]) ? abs((int) $matches[0]) : 0;
}
}
else
{
preg_match($pattern, (string) $source, $matches);
$result = isset($matches[0]) ? abs((int) $matches[0]) : 0;
}
break;
case 'FLOAT':
case 'DOUBLE':
$pattern = '/[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?/';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
preg_match($pattern, (string) $eachString, $matches);
$result[] = isset($matches[0]) ? (float) $matches[0] : 0;
}
}
else
{
preg_match($pattern, (string) $source, $matches);
$result = isset($matches[0]) ? (float) $matches[0] : 0;
}
break;
case 'BOOL':
case 'BOOLEAN':
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (bool) $eachString;
}
}
else
{
$result = (bool) $source;
}
break;
case 'WORD':
$pattern = '/[^A-Z_]/i';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (string) preg_replace($pattern, '', $eachString);
}
}
else
{
$result = (string) preg_replace($pattern, '', $source);
}
break;
case 'ALNUM':
$pattern = '/[^A-Z0-9]/i';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (string) preg_replace($pattern, '', $eachString);
}
}
else
{
$result = (string) preg_replace($pattern, '', $source);
}
break;
case 'CMD':
$pattern = '/[^A-Z0-9_\.-]/i';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$cleaned = (string) preg_replace($pattern, '', $eachString);
$result[] = ltrim($cleaned, '.');
}
}
else
{
$result = (string) preg_replace($pattern, '', $source);
$result = ltrim($result, '.');
}
break;
case 'BASE64':
$pattern = '/[^A-Z0-9\/+=]/i';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (string) preg_replace($pattern, '', $eachString);
}
}
else
{
$result = (string) preg_replace($pattern, '', $source);
}
break;
case 'STRING':
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (string) $this->remove($this->decode((string) $eachString));
}
}
else
{
$result = (string) $this->remove($this->decode((string) $source));
}
break;
case 'HTML':
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (string) $this->remove((string) $eachString);
}
}
else
{
$result = (string) $this->remove((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_\.-]*)*$/';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
preg_match($pattern, (string) $eachString, $matches);
$result[] = isset($matches[0]) ? (string) $matches[0] : '';
}
}
else
{
preg_match($pattern, $source, $matches);
$result = isset($matches[0]) ? (string) $matches[0] : '';
}
break;
case 'TRIM':
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$cleaned = (string) trim($eachString);
$cleaned = StringHelper::trim($cleaned, chr(0xE3) . chr(0x80) . chr(0x80));
$result[] = StringHelper::trim($cleaned, chr(0xC2) . chr(0xA0));
}
}
else
{
$result = (string) trim($source);
$result = StringHelper::trim($result, chr(0xE3) . chr(0x80) . chr(0x80));
$result = StringHelper::trim($result, chr(0xC2) . chr(0xA0));
}
break;
case 'USERNAME':
$pattern = '/[\x00-\x1F\x7F<>"\'%&]/';
if (is_array($source))
{
$result = array();
// Iterate through the array
foreach ($source as $eachString)
{
$result[] = (string) preg_replace($pattern, '', $eachString);
}
}
else
{
$result = (string) preg_replace($pattern, '', $source);
}
break;
case 'RAW':
$result = $source;
break;
default:
// 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] = $this->remove($this->decode($value));
}
}
$result = $source;
}
else
{
// Or a string?
if (is_string($source) && !empty($source))
{
// Filter source for XSS and other 'bad' code etc.
$result = $this->remove($this->decode($source));
}
else
{
// Not an array or string... return the passed parameter
$result = $source;
}
}
break;
}
if ($asArray) {
$result = (array) $result;
}
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment