Version 4.7.23
This commit is contained in:
1 parent
7124a02564
commit
25ddeb65d6
1791 files changed
+76990
-44452
No files matched your search
@@ -159,20 +159,23 @@ class _Encrypt
|
||||
}
|
||||
|
||||
/**
|
||||
* Decript
|
||||
* Decrypt
|
||||
*
|
||||
* @param string|null $encryptionKey Custom decryption key
|
||||
* @return string
|
||||
*/
|
||||
public function decrypt()
|
||||
public function decrypt( ?string $encryptionKey=NULL ): string
|
||||
{
|
||||
$keyToUse = $encryptionKey ?? static::key();
|
||||
|
||||
if ( $this->tag )
|
||||
{
|
||||
return openssl_decrypt( $this->cipher, 'aes-128-gcm', static::key(), 0, $this->iv, $this->tag );
|
||||
return openssl_decrypt( $this->cipher, 'aes-128-gcm', $keyToUse, 0, $this->iv, $this->tag );
|
||||
}
|
||||
elseif ( $this->hmac )
|
||||
{
|
||||
$decrypted = openssl_decrypt( $this->cipher, 'aes-128-cbc', static::key(), OPENSSL_RAW_DATA, $this->iv );
|
||||
if ( hash_equals( $this->hmac, hash_hmac( 'sha256', $this->cipher, static::key(), TRUE ) ) )
|
||||
$decrypted = openssl_decrypt( $this->cipher, 'aes-128-cbc', $keyToUse, OPENSSL_RAW_DATA, $this->iv );
|
||||
if ( hash_equals( $this->hmac, hash_hmac( 'sha256', $this->cipher, $keyToUse, TRUE ) ) )
|
||||
{
|
||||
return $decrypted;
|
||||
}
|
||||
@@ -181,7 +184,7 @@ class _Encrypt
|
||||
else
|
||||
{
|
||||
require_once \IPS\ROOT_PATH . '/system/3rd_party/AES/AES.php';
|
||||
return \AesCtr::decrypt( $this->cipher, static::key(), 256 );
|
||||
return \AesCtr::decrypt( $this->cipher, $keyToUse, 256 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief A HTMLPurifier Attribute Definition used for attributes which must be internal URLs or Integers (such as data-fileid for attachments)
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 October 2024
|
||||
*/
|
||||
|
||||
namespace IPS\Text;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* A HTMLPurifier Attribute Definition used for attributes which must be internal URLs or Integers (such as data-fileid for attachments)
|
||||
*/
|
||||
class _HtmlPurifierIntOrInternalLink extends HtmlPurifierInternalLinkDef
|
||||
{
|
||||
/**
|
||||
* Validate
|
||||
*
|
||||
* @param string $value
|
||||
* @param \HTMLPurifier_Config $config
|
||||
* @param \HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate( $value, $config, $context )
|
||||
{
|
||||
$parentCheck = parent::validate( $value, $config, $context );
|
||||
|
||||
if( $parentCheck !== FALSE )
|
||||
{
|
||||
return $parentCheck;
|
||||
}
|
||||
|
||||
$integer = new \HTMLPurifier_AttrDef_Integer( false );
|
||||
return $integer->validate( $value, $config, $context );
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,14 @@ class _HtmlPurifierInternalLinkDef extends \HTMLPurifier_AttrDef_URI
|
||||
public function validate($uri, $config, $context)
|
||||
{
|
||||
/* Create the URL */
|
||||
$url = \IPS\Http\Url::createFromString( str_replace( array( '%7B___base_url___%7D/', '{___base_url___}/' ), \IPS\Settings::i()->base_url, $uri ) );
|
||||
try
|
||||
{
|
||||
$url = \IPS\Http\Url::createFromString( str_replace( array( '%7B___base_url___%7D/', '{___base_url___}/' ), \IPS\Settings::i()->base_url, $uri ) );
|
||||
}
|
||||
catch( \IPS\Http\Url\Exception $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If it's not internal, we can stop now */
|
||||
if ( !( $url instanceof \IPS\Http\Url\Internal ) )
|
||||
|
||||
+40
-12
@@ -11,6 +11,9 @@
|
||||
namespace IPS\Text;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use function preg_replace;
|
||||
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
@@ -640,8 +643,8 @@ class _Parser
|
||||
$def->addAttribute( 'img', 'data-emoticon', 'Bool' ); // Identifies emoticons and stops lightbox running on them
|
||||
|
||||
/* Attachments (set by _parseAElement, _parseImgElement and "insert existing attachment") - Gallery/Downloads use the full URL rather than an ID, hence Text */
|
||||
$def->addAttribute( 'a', 'data-fileid', 'Text' );
|
||||
$def->addAttribute( 'img', 'data-fileid', 'Text' );
|
||||
$def->addAttribute( 'a', 'data-fileid', new HtmlPurifierIntOrInternalLink() );
|
||||
$def->addAttribute( 'img', 'data-fileid', new HtmlPurifierIntOrInternalLink() );
|
||||
$def->addAttribute( 'a', 'data-fileext', 'Text' );
|
||||
|
||||
/* Existing media (inserted with data-extension by the JS so that _getFile is able to locate) */
|
||||
@@ -656,7 +659,7 @@ class _Parser
|
||||
/* iFrames (used by embeddableMedia) */
|
||||
$def->addAttribute( 'iframe', 'data-controller', new \HTMLPurifier_AttrDef_Enum( array( 'core.front.core.autosizeiframe' ) ) ); // used in core/global/embed/iframe.phtml
|
||||
$def->addAttribute( 'iframe', 'data-embedid', 'Text' ); // used in core/global/embed/iframe.phtml
|
||||
$def->addAttribute( 'iframe', 'data-embedauthorid', 'Text' ); // used for embed notifications
|
||||
$def->addAttribute( 'iframe', 'data-embedauthorid', 'Number' ); // used for embed notifications
|
||||
$def->addAttribute( 'iframe', 'data-embedcontent', 'Text' ); // used in embeddableMedia
|
||||
$def->addAttribute( 'iframe', 'allowfullscreen', 'Text' ); // Some services will specify this property
|
||||
|
||||
@@ -2061,8 +2064,21 @@ class _Parser
|
||||
*/
|
||||
protected function _parseSourceElement( \DOMElement $element, \DOMElement $originalElement = NULL )
|
||||
{
|
||||
$parentIsVideo = function( \DOMElement $element ) use ( &$parentIsVideo ) {
|
||||
if( $element->tagName === 'video' )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
elseif( $element->parentNode !== NULL AND $element->parentNode instanceof \DOMElement )
|
||||
{
|
||||
return $parentIsVideo( $element->parentNode );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
/* We only want to do this for videos */
|
||||
if( $originalElement !== NULL AND $originalElement->parentNode->tagName !== 'video' )
|
||||
if( $originalElement !== NULL AND !$parentIsVideo( $originalElement ) )
|
||||
{
|
||||
return $element;
|
||||
}
|
||||
@@ -2088,7 +2104,7 @@ class _Parser
|
||||
* Parse <iframe> element
|
||||
*
|
||||
* @param \DOMElement $element The element
|
||||
* @return bool
|
||||
* @return \DOMElement
|
||||
*/
|
||||
protected function _parseIframeElement( \DOMElement $element )
|
||||
{
|
||||
@@ -2096,7 +2112,7 @@ class _Parser
|
||||
{
|
||||
$src = \IPS\Http\Url::createFromString( $element->getAttribute('src') );
|
||||
|
||||
if( mb_strpos( $src->data['host'], 'youtube.com' ) !== FALSE )
|
||||
if( mb_strpos( $src->data['host'], 'youtube.com' ) !== FALSE OR mb_strpos( $src->data['host'], 'youtube-nocookie.com' ) !== FALSE )
|
||||
{
|
||||
/* If this is a youtube link, let's strip auto-play... */
|
||||
$src = $src->stripQueryString( 'autoplay' );
|
||||
@@ -2105,7 +2121,7 @@ class _Parser
|
||||
$element->setAttribute( 'src', static::blankPage() );
|
||||
}
|
||||
else if ( $src instanceof \IPS\Http\Url\Internal )
|
||||
{
|
||||
{
|
||||
/* If this is an internal embed, replace src and controller for lazy loading */
|
||||
if ( \IPS\Settings::i()->lazy_load_enabled )
|
||||
{
|
||||
@@ -3051,7 +3067,7 @@ class _Parser
|
||||
{
|
||||
if ( $bbcode->permissionCheck( $member, $area ) )
|
||||
{
|
||||
list( $app, $tag ) = explode( '_', $key );
|
||||
[ $app, $tag ] = explode( '_', $key );
|
||||
$return[ $tag ] = $bbcode->getConfiguration();
|
||||
}
|
||||
}
|
||||
@@ -3287,6 +3303,7 @@ class _Parser
|
||||
'tiktok.com' => array( 'https://www.tiktok.com/oembed', static::EMBED_VIDEO ),
|
||||
'm.tiktok.com' => array( 'https://www.tiktok.com/oembed', static::EMBED_VIDEO ),
|
||||
'vm.tiktok.com' => array( 'https://www.tiktok.com/oembed', static::EMBED_VIDEO ),
|
||||
'bsky.app' => [ 'https://embed.bsky.app/oembed', static::EMBED_TWEET ]
|
||||
);
|
||||
|
||||
/* Can we support Facebook and Instagram oembeds? */
|
||||
@@ -3977,9 +3994,15 @@ class _Parser
|
||||
protected static function _internalEmbed( \IPS\Http\Url $url, $iframe=FALSE, $member=NULL )
|
||||
{
|
||||
/* If this URL has a #comment-123 fragment, change it to the findComment URL so the comment embeds rather than the item */
|
||||
if ( isset( $url->data['fragment'] ) and mb_strstr( $url->data['fragment'], 'comment-' ) and empty( $url->queryString['do'] ) )
|
||||
if ( isset( $url->data['fragment'] ) and mb_stristr( $url->data['fragment'], 'comment-' ) and empty( $url->queryString['do'] ) )
|
||||
{
|
||||
$url = $url->setQueryString( array( 'do' => 'findComment', 'comment' => str_replace( 'comment-', '', $url->data['fragment'] ) ) );
|
||||
$url = $url->setQueryString( array( 'do' => 'findComment', 'comment' => preg_replace( '#(find)?comment-#i', '', $url->data['fragment'] ) ) );
|
||||
}
|
||||
|
||||
/* And for reviews */
|
||||
if ( isset( $url->data['fragment'] ) and mb_stristr( $url->data['fragment'], 'review-' ) and empty( $url->queryString['do'] ) )
|
||||
{
|
||||
$url = $url->setQueryString( array( 'do' => 'findReview', 'review' => preg_replace( '#(find)?review-#i', '', $url->data['fragment'] ) ) );
|
||||
}
|
||||
|
||||
/* Get the "real" query string (whatever the query string is, plus what we can get from decoding the FURL) */
|
||||
@@ -4168,11 +4191,16 @@ class _Parser
|
||||
{
|
||||
return (string) $url;
|
||||
}
|
||||
|
||||
$width = (int) $width;
|
||||
$height = (int) $height;
|
||||
|
||||
$maxImageDims = \IPS\Settings::i()->attachment_image_size ? explode( 'x', \IPS\Settings::i()->attachment_image_size ) : array( 1000, 750 );
|
||||
$widthToUse = $width;
|
||||
$heightToUse = $height;
|
||||
|
||||
$maxImageDims = array_map('intval', $maxImageDims);
|
||||
|
||||
/* 0x0 means unlimited, so only do these calculations if a specific size has been set */
|
||||
if( \intval( $maxImageDims[0] ) !== 0 || \intval( $maxImageDims[1] ) !== 0 )
|
||||
{
|
||||
@@ -4195,7 +4223,7 @@ class _Parser
|
||||
|
||||
if ( $widthToUse > $maxImageDims[0] )
|
||||
{
|
||||
$heightToUse = floor( $maxImageDims[0] * ( $heightToUse / $widthToUse ) );
|
||||
$heightToUse = floor( $maxImageDims[0] * ( $heightToUse / $widthToUse ) );
|
||||
$widthToUse = $maxImageDims[0];
|
||||
}
|
||||
}
|
||||
@@ -4255,7 +4283,7 @@ class _Parser
|
||||
if( $element->tagName == $matches[1] )
|
||||
{
|
||||
/* Break up the definition into name and value */
|
||||
list( $attribute, $value ) = explode( '=', trim( $matches[2] ) );
|
||||
[ $attribute, $value ] = explode( '=', trim( $matches[2] ) );
|
||||
|
||||
/* Remove quotes */
|
||||
$value = str_replace( array( '"', "'" ), '', $value );
|
||||
|
||||
Reference in new issue
Block a user