Version 4.7.0

This commit is contained in:
Neo committed 2025-12-19 16:00:35 -08:00
1 parent 517a5e1f70
commit 8ba7d43898
1933 files changed
+65613 -11332

No files matched your search

+102 -26
View File
@@ -51,13 +51,18 @@ abstract class _File
/**
* @brief File extensions considered safe. Not an exhaustive list but these are the files we're most interested in being recognised.
*/
public static $safeFileExtensions = array( 'js', 'css', 'txt', 'ico', 'gif', 'jpg', 'jpe', 'jpeg', 'png', 'mp4', '3gp', 'mov', 'ogg', 'ogv', 'mp3', 'mpg', 'mpeg', 'ico', 'flv', 'webm', 'wmv', 'avi', 'm4v' );
public static $safeFileExtensions = array( 'js', 'css', 'txt', 'ico', 'gif', 'jpg', 'jpe', 'jpeg', 'png', 'mp4', '3gp', 'mov', 'ogg', 'ogv', 'mp3', 'mpg', 'mpeg', 'ico', 'flv', 'webm', 'wmv', 'avi', 'm4v', 'webp', 'm4a' );
/**
* @brief File extensions for HTML5 compatible videos
*/
public static $videoExtensions = array( 'mp4', '3gp', 'mov', 'ogg', 'ogv', 'mpg', 'mpeg', 'flv', 'webm', 'wmv', 'avi', 'm4v' );
/**
* @brief File extensions for HTML5 compatible audio
*/
public static $audioExtensions = array( 'mp3', 'ogg', 'wav', 'm4a' );
/**
* @brief Does this storage method support chunked uploads?
*/
@@ -385,7 +390,7 @@ abstract class _File
/* Now loop over each file */
$currentTotal = 0;
foreach( $files as $file )
foreach( $files as $i => $file )
{
/* First, validate the upload */
try
@@ -426,13 +431,13 @@ abstract class _File
if( $callback !== NULL )
{
$contents = file_get_contents( $file['tmp_name'] );
$contents = $callback( $contents, $file['name'] );
$contents = $callback( $contents, $file['name'], $i );
$fileObjects[] = static::create( $storageLocation, $file['name'], $contents, $container, FALSE, NULL, $obscure );
$fileObjects[ $i ] = static::create( $storageLocation, $file['name'], $contents, $container, FALSE, NULL, $obscure );
}
else
{
$fileObjects[] = static::create( $storageLocation, $file['name'], NULL, $container, FALSE, $file['tmp_name'], $obscure );
$fileObjects[ $i ] = static::create( $storageLocation, $file['name'], NULL, $container, FALSE, $file['tmp_name'], $obscure );
}
if( is_file( $file['tmp_name'] ) and file_exists( $file['tmp_name'] ) )
@@ -745,6 +750,11 @@ abstract class _File
*/
public $tempId;
/**
* @brief A flag used immediately after the file is uploaded to indicate if it has been flagged by the image scanner
*/
public $requiresModeration = NULL;
/**
* Constructor
*
@@ -983,7 +993,7 @@ abstract class _File
$filename = str_replace( '.' . $matches[2], '_' . $matches[2], $filename );
}
return str_replace( array( ' ', '#' ), '_', $filename ) . '.' . md5( mt_rand() ) . ( ( $safe ) ? '.' . $ext : '' );
return str_replace( array( ' ', '#' ), '_', $filename ) . '.' . \IPS\Login::generateRandomString( 32 ) . ( ( $safe ) ? '.' . $ext : '' );
}
/**
@@ -997,7 +1007,7 @@ abstract class _File
$ext = mb_substr( $filename, ( mb_strrpos( $filename, '.' ) + 1 ) );
if ( mb_strlen( $ext ) == 32 )
{
preg_match( '#(.*)_([A-Z0-9\-]{2,10})\.([A-Z0-9]{32})#i', $filename, $matches );
preg_match( '#(.*)_([A-Z0-9\-]{2,14})\.([A-Z0-9]{32})#i', $filename, $matches );
if ( isset( $matches[1] ) and isset( $matches[2] ) )
{
@@ -1006,7 +1016,7 @@ abstract class _File
else
{
/* Fix foo.pdf.hash */
preg_match( '#(.*)\.([A-Z0-9\-]{2,10})\.([A-Z0-9]{32})#i', $filename, $matches );
preg_match( '#(.*)\.([A-Z0-9\-]{2,14})\.([A-Z0-9]{32})#i', $filename, $matches );
if ( isset( $matches[1] ) and isset( $matches[2] ) )
{
@@ -1287,12 +1297,14 @@ abstract class _File
/**
* Make into an attachment
*
* @param string $postKey Post key
* @param \IPS\Member|NULL $member Member who uploaded the attachment
* @param string $postKey Post key
* @param \IPS\Member|NULL $member Member who uploaded the attachment
* @param bool $requiresModeration If this attachment requires moderation
* @param array|NULL $labels Image scanner labels
* @return array
* @throws \DomainException
*/
public function makeAttachment( $postKey, \IPS\Member $member = NULL )
public function makeAttachment( $postKey, \IPS\Member $member = NULL, $requiresModeration = FALSE, $labels=NULL )
{
$ext = mb_substr( $this->originalFilename, mb_strrpos($this->originalFilename, '.') + 1 );
@@ -1301,21 +1313,22 @@ abstract class _File
$this->securityKey = \IPS\Login::generateRandomString();
$data = array(
'attach_ext' => $ext,
'attach_file' => $this->originalFilename,
'attach_location' => (string) $this,
'attach_thumb_location' => '',
'attach_thumb_width' => 0,
'attach_thumb_height' => 0,
'attach_is_image' => 0,
'attach_hits' => 0,
'attach_date' => time(),
'attach_post_key' => $postKey,
'attach_member_id' => $memberId,
'attach_filesize' => $this->filesize(),
'attach_img_width' => 0,
'attach_img_height' => 0,
'attach_is_archived' => FALSE,
'attach_ext' => $ext,
'attach_file' => $this->originalFilename,
'attach_location' => (string) $this,
'attach_thumb_location' => '',
'attach_thumb_width' => 0,
'attach_thumb_height' => 0,
'attach_is_image' => 0,
'attach_hits' => 0,
'attach_date' => time(),
'attach_post_key' => $postKey,
'attach_member_id' => $memberId,
'attach_filesize' => $this->filesize(),
'attach_img_width' => 0,
'attach_img_height' => 0,
'attach_is_archived' => FALSE,
'attach_moderation_status' => $requiresModeration ? 'pending' : 'skipped',
'attach_security_key' => $this->securityKey
);
@@ -1339,6 +1352,8 @@ abstract class _File
$this->attachmentThumbnailUrl = $data['attach_thumb_location'];
}
$data['attach_labels'] = $labels;
}
catch ( \InvalidArgumentException $e ) { }
@@ -1380,6 +1395,23 @@ abstract class _File
return FALSE;
}
/**
* Determine if the file is a video
*
* @return bool
*/
public function isAudio()
{
$ext = mb_substr( $this->originalFilename, mb_strrpos( $this->originalFilename, '.' ) + 1 );
if ( \in_array( mb_strtolower( $ext ), \IPS\File::$audioExtensions ) )
{
return TRUE;
}
return FALSE;
}
/**
* Get media type ("file", "image" or "video")
@@ -1396,6 +1428,10 @@ abstract class _File
{
return 'image';
}
elseif ( $this->isAudio() )
{
return 'audio';
}
else
{
return 'file';
@@ -1763,6 +1799,7 @@ abstract class _File
'ogg' => 'file-audio-o',
'ogv' => 'file-audio-o',
'wav' => 'file-audio-o',
'm4a' => 'file-audio-o',
'avi' => 'file-video-o',
'flv' => 'file-video-o',
'mkv' => 'file-video-o',
@@ -2692,4 +2729,43 @@ abstract class _File
'zmm' => 'application/vnd.handheld-entertainment+xml'
);
/**
* Is this an animated image ( does it contain multiple frames )?
*
* @return bool
*/
public function isAnimatedImage(): bool
{
$offset = 0;
$frame = 0;
$contents = $this->contents();
while ( $frame < 2 )
{
$pos = \strpos( $contents, "\x00\x21\xF9\x04", $offset );
if ( $pos === false )
{
break;
}
else
{
$offset = $pos + 1;
$newPos = \strpos( $contents, "\x00\x2C", $offset );
if ( $newPos === false )
{
break;
}
else
{
if ( $pos + 8 == $newPos )
{
$frame++;
}
$offset = $newPos + 1;
}
}
}
return $frame > 1;
}
}