Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
+183
-36
@@ -11,7 +11,7 @@
|
||||
namespace IPS;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -87,7 +87,7 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
foreach( $data as $k => $v )
|
||||
{
|
||||
if ( is_array( $v ) )
|
||||
if ( \is_array( $v ) )
|
||||
{
|
||||
array_walk_recursive( $v, array( $this, 'clean' ) );
|
||||
}
|
||||
@@ -112,18 +112,12 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
/* Remove NULL bytes and the RTL control byte */
|
||||
$v = str_replace( array( "\0", "\u202E" ), '', $v );
|
||||
|
||||
/* Undo magic quote madness */
|
||||
if ( get_magic_quotes_gpc() === 1 )
|
||||
{
|
||||
$v = stripslashes( $v );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value from array
|
||||
*
|
||||
* @param string Key with square brackets (e.g. "foo[bar]")
|
||||
* @param string $key Key with square brackets (e.g. "foo[bar]")
|
||||
* @return mixed Value
|
||||
*/
|
||||
public function valueFromArray( $key )
|
||||
@@ -151,6 +145,25 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
return $array[ $key ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object that can be cast to a string to get the value for a given input
|
||||
*
|
||||
* This can be used in place of passing strings as arguments to functions where it is
|
||||
* desirable to avoid the value being included in a backtrace if an error occurs.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function protect( $k )
|
||||
{
|
||||
return eval('return new class
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
return \IPS\Request::i()->' . $k . ' ?? \'\';
|
||||
}
|
||||
};' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an AJAX request?
|
||||
*
|
||||
@@ -161,6 +174,16 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
return ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) and $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this request from the mobile app?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isApp()
|
||||
{
|
||||
return isset( $_SERVER['HTTP_X_IPS_APP'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an SSL/Secure request?
|
||||
*
|
||||
@@ -206,7 +229,6 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
* Get current URL
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @see init.php
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
@@ -412,6 +434,10 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
$this->setCookie( 'member_id', NULL );
|
||||
$this->setCookie( 'login_key', NULL );
|
||||
$this->setCookie( 'loggedIn', NULL );
|
||||
$this->setCookie( 'guestTime', NULL );
|
||||
$this->setCookie( 'noCache', NULL );
|
||||
|
||||
foreach( $this->cookie as $name => $value )
|
||||
{
|
||||
if( mb_strpos( $name, "ipbforumpass_" ) !== FALSE )
|
||||
@@ -435,7 +461,12 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
public function setClearAutosaveCookie( $autoSaveKey )
|
||||
{
|
||||
$this->clearAutoSaveCookie[] = $autoSaveKey;
|
||||
\IPS\Request::i()->setCookie( 'clearAutosave', implode( ',', $this->clearAutoSaveCookie ), NULL, FALSE );
|
||||
|
||||
/* It is possible for this method to be called from tasks executing during __destruct() after the output has been sent. We want to avoid sending a cookie in that case, as it can cause an error to display. */
|
||||
if ( ! headers_sent() )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'clearAutosave', implode( ',', $this->clearAutoSaveCookie ), NULL, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -467,10 +498,6 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
if( $groupFloodSeconds )
|
||||
{
|
||||
$time = ( isset( \IPS\Request::i()->cookie['lastSearch'] ) ) ? \IPS\Request::i()->cookie['lastSearch'] : 0;
|
||||
if ( isset( $_SESSION['lastSearch'] ) and $_SESSION['lastSearch'] > $time )
|
||||
{
|
||||
$time = $_SESSION['lastSearch'];
|
||||
}
|
||||
|
||||
if( $time and ( time() - $time ) < $groupFloodSeconds )
|
||||
{
|
||||
@@ -478,9 +505,8 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'search_flood_error', FALSE, array( 'pluralize' => array( $secondsToWait ) ) ), '1C205/3', 429, \IPS\Member::loggedIn()->language()->addToStack( 'search_flood_error_admin', FALSE, array( 'pluralize' => array( $secondsToWait ) ) ), array( 'Retry-After' => \IPS\DateTime::create()->add( new \DateInterval( 'PT' . $secondsToWait . 'S' ) )->format('r') ) );
|
||||
}
|
||||
|
||||
$_SESSION['lastSearch'] = time();
|
||||
$expire = new \IPS\DateTime;
|
||||
\IPS\Request::i()->setCookie( 'lastSearch', time(), $expire->add( new \DateInterval( 'PT' . intval( $groupFloodSeconds ) . 'S' ) ) );
|
||||
\IPS\Request::i()->setCookie( 'lastSearch', time(), $expire->add( new \DateInterval( 'PT' . \intval( $groupFloodSeconds ) . 'S' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +538,7 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
/* The confirmation dialogs will send form_submitted=1, as will displaying a form, so we check for this.
|
||||
If the admin (or user) simply visited a delete URL directly, this would not be included in the request. */
|
||||
if ( ! isset( \IPS\Request::i()->wasConfirmed ) )
|
||||
if ( !isset( \IPS\Request::i()->wasConfirmed ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', $submit );
|
||||
$form->hiddenValues['wasConfirmed'] = 1;
|
||||
@@ -524,39 +550,160 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->genericBlock( $form, \IPS\Output::i()->title ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->genericBlock( $form, \IPS\Output::i()->title ), 200, 'text/html' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html' );
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are here, we're all good! */
|
||||
/* If we are here, just check the csrf key */
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Old IPB escape-on-input routine
|
||||
*
|
||||
* @param string $val The unescaped text
|
||||
* @param string|object $val The unescaped text (can be a string or an object that can be cast to a string)
|
||||
* @return string The IPB3-style escaped text
|
||||
*/
|
||||
public static function legacyEscape( $val )
|
||||
{
|
||||
$val = str_replace( "&" , "&" , $val );
|
||||
$val = str_replace( "<!--" , "<!--" , $val );
|
||||
$val = str_replace( "-->" , "-->" , $val );
|
||||
$val = str_ireplace( "<script" , "<script" , $val );
|
||||
$val = str_replace( ">" , ">" , $val );
|
||||
$val = str_replace( "<" , "<" , $val );
|
||||
$val = str_replace( '"' , """ , $val );
|
||||
$val = str_replace( "\n" , "<br />" , $val );
|
||||
$val = str_replace( "$" , "$" , $val );
|
||||
$val = str_replace( "!" , "!" , $val );
|
||||
$val = str_replace( "'" , "'" , $val );
|
||||
$val = str_replace( "\\" , "\" , $val );
|
||||
|
||||
return $val;
|
||||
$val = (string) $val;
|
||||
|
||||
$val = str_replace( "&" , "&" , $val );
|
||||
$val = str_replace( "<!--" , "<!--" , $val );
|
||||
$val = str_replace( "-->" , "-->" , $val );
|
||||
$val = str_ireplace( "<script" , "<script" , $val );
|
||||
$val = str_replace( ">" , ">" , $val );
|
||||
$val = str_replace( "<" , "<" , $val );
|
||||
$val = str_replace( '"' , """ , $val );
|
||||
$val = str_replace( "\n" , "<br />" , $val );
|
||||
$val = str_replace( "$" , "$" , $val );
|
||||
$val = str_replace( "!" , "!" , $val );
|
||||
$val = str_replace( "'" , "'" , $val );
|
||||
$val = str_replace( "\\" , "\" , $val );
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our referrer, looking for a specific request variable, then falling back to the header
|
||||
*
|
||||
* @param bool $allowExternal If set to TRUE, external URL's will be allowed and returned.
|
||||
* @param bool $onlyRequest If set to TRUE, will only look for the "ref" request parameter. Useful if you need to look for HTTP_REFERER at a specific point in time.
|
||||
* @param string|NULL $base If set, will only return URL's with this base.
|
||||
* @return \IPS\Http\Url|NULL
|
||||
*/
|
||||
public function referrer( bool $allowExternal=FALSE, bool $onlyRequest=FALSE, ?string $base = NULL ): ?\IPS\Http\Url
|
||||
{
|
||||
/* Do we have a _ref request parameter? */
|
||||
$ref = NULL;
|
||||
if ( isset( $this->ref ) )
|
||||
{
|
||||
$ref = @base64_decode( $this->ref );
|
||||
}
|
||||
|
||||
/* Maybe not - check HTTP_REFERER */
|
||||
if ( !$ref AND !$onlyRequest AND !empty( $_SERVER['HTTP_REFERER'] ) )
|
||||
{
|
||||
$ref = $_SERVER['HTTP_REFERER'];
|
||||
}
|
||||
|
||||
/* Did that work? */
|
||||
if ( $ref )
|
||||
{
|
||||
try
|
||||
{
|
||||
$ref = \IPS\Http\Url::createFromString( $ref );
|
||||
}
|
||||
catch( \IPS\Http\Url\Exception $e )
|
||||
{
|
||||
/* Failed to create? Nope. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return if URL is internal and not an open redirect, or if we're allowing external referrer references */
|
||||
if ( ( ( $ref instanceof \IPS\Http\Url\Internal ) AND !$ref->openRedirect() ) OR $allowExternal )
|
||||
{
|
||||
if ( $base !== NULL AND ( $ref instanceof \IPS\Http\Url\Internal ) )
|
||||
{
|
||||
if ( $ref->base === $base )
|
||||
{
|
||||
return $ref;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $ref;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Still here? Nothing worked */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any Authorization header (or otherwise passed API key or OAuth access token) in the request
|
||||
* Note: doesn't do any kind of decoding, value will be something like "Basic xxxxx" or "Bearer xxxxx"
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function authorizationHeader()
|
||||
{
|
||||
/* Check if an API Key or Access Token has been passed as a parameter in the query string. Because of the
|
||||
obvious security issues with this, we do not recommend it, but sometimes it is the only choice */
|
||||
if ( isset( $this->key ) )
|
||||
{
|
||||
return 'Basic ' . base64_encode( $this->key . ':' );
|
||||
}
|
||||
if ( isset( $this->access_token ) and ( !\IPS\OAUTH_REQUIRES_HTTPS or $this->isSecure() ) )
|
||||
{
|
||||
return 'Bearer ' . $this->access_token;
|
||||
}
|
||||
|
||||
/* Look for an API key in an automatically decoded HTTP Basic header */
|
||||
if ( isset( $_SERVER['PHP_AUTH_USER'] ) )
|
||||
{
|
||||
return 'Basic ' . base64_encode( $_SERVER['PHP_AUTH_USER'] . ':' );
|
||||
}
|
||||
|
||||
/* If we're still here, try to find an Authorization header - start with $_SERVER... */
|
||||
$authorizationHeader = NULL;
|
||||
foreach ( $_SERVER as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, -18 ) == 'HTTP_AUTHORIZATION' or mb_substr( $k, -20 ) == 'HTTP_X_AUTHORIZATION' )
|
||||
{
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
||||
/* ...if we didn't find anything there, try apache_request_headers() */
|
||||
if ( \function_exists('apache_request_headers') )
|
||||
{
|
||||
$headers = @apache_request_headers();
|
||||
if ( isset( $headers['Authorization'] ) )
|
||||
{
|
||||
return $headers['Authorization'];
|
||||
}
|
||||
elseif ( isset( $headers['X-Authorization'] ) )
|
||||
{
|
||||
return $headers['X-Authorization'];
|
||||
}
|
||||
}
|
||||
|
||||
/* Still here? We got nothing */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user