mirror of
https://github.com/Karaka-Management/oms-Media.git
synced 2026-02-16 09:18:42 +00:00
Fix #2
This commit is contained in:
parent
be2b4fe17c
commit
d8bc472fa6
|
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||||
namespace Modules\Media\Models;
|
namespace Modules\Media\Models;
|
||||||
|
|
||||||
use phpOMS\System\File\Local\Directory;
|
use phpOMS\System\File\Local\Directory;
|
||||||
|
use phpOMS\System\File\FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload.
|
* Upload.
|
||||||
|
|
@ -32,10 +33,10 @@ class UploadFile
|
||||||
/**
|
/**
|
||||||
* Image interlaced.
|
* Image interlaced.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var bool
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
private $interlaced = true;
|
private $isInterlaced = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload max size.
|
* Upload max size.
|
||||||
|
|
@ -80,7 +81,8 @@ class UploadFile
|
||||||
/**
|
/**
|
||||||
* Upload file to server.
|
* Upload file to server.
|
||||||
*
|
*
|
||||||
* @param array $files File data ($_FILE)
|
* @param array $files File data ($_FILE)
|
||||||
|
* @param string $encoding Encoding used for uploaded file. Empty string will not convert file content.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*
|
*
|
||||||
|
|
@ -88,7 +90,7 @@ class UploadFile
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function upload(array $files) : array
|
public function upload(array $files, string $encoding = 'UTF-8') : array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
|
|
@ -96,7 +98,10 @@ class UploadFile
|
||||||
$files = [$files];
|
$files = [$files];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->findOutputDir($files);
|
if (count($files) > 1) {
|
||||||
|
$this->outputDir = $this->findOutputDir($files);
|
||||||
|
}
|
||||||
|
|
||||||
$path = $this->outputDir;
|
$path = $this->outputDir;
|
||||||
|
|
||||||
foreach ($files as $key => $f) {
|
foreach ($files as $key => $f) {
|
||||||
|
|
@ -117,7 +122,6 @@ class UploadFile
|
||||||
$result[$key]['size'] = $f['size'];
|
$result[$key]['size'] = $f['size'];
|
||||||
|
|
||||||
if ($f['size'] > $this->maxSize) {
|
if ($f['size'] > $this->maxSize) {
|
||||||
// too large2
|
|
||||||
$result[$key]['status'] = UploadStatus::CONFIG_SIZE;
|
$result[$key]['status'] = UploadStatus::CONFIG_SIZE;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
|
@ -125,96 +129,135 @@ class UploadFile
|
||||||
|
|
||||||
// TODO: do I need pecl fileinfo?
|
// TODO: do I need pecl fileinfo?
|
||||||
if (!empty($this->allowedTypes) && ($ext = array_search($f['type'], $this->allowedTypes, true)) === false) {
|
if (!empty($this->allowedTypes) && ($ext = array_search($f['type'], $this->allowedTypes, true)) === false) {
|
||||||
// wrong file format
|
|
||||||
$result[$key]['status'] = UploadStatus::WRONG_EXTENSION;
|
$result[$key]['status'] = UploadStatus::WRONG_EXTENSION;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->preserveFileName) {
|
|
||||||
$this->fileName = $f['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$split = \explode('.', $f['name']);
|
$split = \explode('.', $f['name']);
|
||||||
$result[$key]['name'] = $split[0];
|
$result[$key]['name'] = $split[0];
|
||||||
$extension = count($split) > 1 ? $split[count($split) - 1] : '';
|
$extension = count($split) > 1 ? $split[count($split) - 1] : '';
|
||||||
$result[$key]['extension'] = $extension;
|
$result[$key]['extension'] = $extension;
|
||||||
|
|
||||||
// ! and empty same?!
|
if ($this->preserveFileName) {
|
||||||
$result[$key]['filename'] = $this->fileName;
|
$this->fileName = $f['name'];
|
||||||
if (!$this->fileName || empty($this->fileName) || \file_exists($path . '/' . $this->fileName)) {
|
}
|
||||||
$rnd = '';
|
|
||||||
|
|
||||||
$limit = 0;
|
if (empty($this->fileName) || \file_exists($path . '/' . $this->fileName)) {
|
||||||
do {
|
try {
|
||||||
$sha = sha1_file($f['tmp_name'] . $rnd);
|
$this->fileName = $this->createFileName($path, $f['tmp_name'], $extension);
|
||||||
|
$result[$key]['filename'] = $this->fileName;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$result[$key]['filename'] = $f['name'];
|
||||||
|
$result[$key]['status'] = UploadStatus::FAILED_HASHING;
|
||||||
|
|
||||||
if ($sha === false) {
|
return $result;
|
||||||
$result[$key]['status'] = UploadStatus::FAILED_HASHING;
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sha .= '.' . $extension;
|
|
||||||
|
|
||||||
$this->fileName = $sha;
|
|
||||||
$rnd = mt_rand();
|
|
||||||
$limit++;
|
|
||||||
} while (file_exists($path . '/' . $this->fileName) && $limit < self::PATH_GENERATION_LIMIT);
|
|
||||||
|
|
||||||
if ($limit >= self::PATH_GENERATION_LIMIT) {
|
|
||||||
throw new \Exception('No file path could be found. Potential attack!');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_dir($path)) {
|
if (!\is_dir($path)) {
|
||||||
Directory::create($path, 0655, true);
|
Directory::create($path, 0655, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_uploaded_file($f['tmp_name'])) {
|
if (!\is_uploaded_file($f['tmp_name'])) {
|
||||||
$result[$key]['status'] = UploadStatus::NOT_UPLOADED;
|
$result[$key]['status'] = UploadStatus::NOT_UPLOADED;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!move_uploaded_file($f['tmp_name'], $dest = $path . '/' . $this->fileName)) {
|
if (!\move_uploaded_file($f['tmp_name'], $dest = $path . '/' . $this->fileName)) {
|
||||||
$result[$key]['status'] = UploadStatus::NOT_MOVABLE;
|
$result[$key]['status'] = UploadStatus::NOT_MOVABLE;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->interlaced && \in_array($extension, ['png', 'jpg', 'jpeg', 'gif'])) {
|
if ($this->isInterlaced && \in_array($extension, FileUtils::IMAGE_EXTENSION)) {
|
||||||
$this->interlace($extension, $dest);
|
$this->interlace($extension, $dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[$key]['path'] = realpath($this->outputDir);
|
if ($encoding !== '') {
|
||||||
|
FileUtils::changeFileEncoding($dest, $encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[$key]['path'] = \realpath($this->outputDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create file name if file already exists or if file name should be random.
|
||||||
|
*
|
||||||
|
* @param string $path Path where file should be saved
|
||||||
|
* @param string $tempName Temp. file name generated during upload
|
||||||
|
* @param string $extension Extension name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
private function createFileName(string $path, string $tempName, string $extension) : string
|
||||||
|
{
|
||||||
|
$rnd = '';
|
||||||
|
$limit = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
$sha = \sha1_file($tempName . $rnd);
|
||||||
|
|
||||||
|
if ($sha === false) {
|
||||||
|
throw new \Exception('No file path could be found. Potential attack!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sha .= '.' . $extension;
|
||||||
|
$fileName = $sha;
|
||||||
|
$rnd = \mt_rand();
|
||||||
|
$limit++;
|
||||||
|
} while (\file_exists($path . '/' . $fileName) && $limit < self::PATH_GENERATION_LIMIT);
|
||||||
|
|
||||||
|
if ($limit >= self::PATH_GENERATION_LIMIT) {
|
||||||
|
throw new \Exception('No file path could be found. Potential attack!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make image interlace
|
||||||
|
*
|
||||||
|
* @param string $extension Image extension
|
||||||
|
* @param string $path File path
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
private function interlace(string $extension, string $path) : void
|
private function interlace(string $extension, string $path) : void
|
||||||
{
|
{
|
||||||
|
if ($extension === 'png') {
|
||||||
|
$img = \imagecreatefrompng($path);
|
||||||
|
} elseif ($extension === 'jpg' || $extension === 'jpeg') {
|
||||||
|
$img = \imagecreatefromjpeg($path);
|
||||||
|
} else {
|
||||||
|
$img = \imagecreatefromgif($path);
|
||||||
|
}
|
||||||
|
|
||||||
if ($extension === 'png') {
|
if ($img === false) {
|
||||||
$img = imagecreatefrompng($path);
|
return;
|
||||||
} elseif ($extension === 'jpg' || $extension === 'jpeg') {
|
}
|
||||||
$img = imagecreatefromjpeg($path);
|
|
||||||
} else {
|
|
||||||
$img = imagecreatefromgif($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
imageinterlace($img, (int) $this->interlaced);
|
\imageinterlace($img, (int) $this->isInterlaced);
|
||||||
|
|
||||||
if ($extension === 'png') {
|
if ($extension === 'png') {
|
||||||
imagepng($img, $path);
|
\imagepng($img, $path);
|
||||||
} elseif ($extension === 'jpg' || $extension === 'jpeg') {
|
} elseif ($extension === 'jpg' || $extension === 'jpeg') {
|
||||||
imagejpeg($img, $path);
|
\imagejpeg($img, $path);
|
||||||
} else {
|
} else {
|
||||||
imagegif($img, $path);
|
\imagegif($img, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
imagedestroy($img);
|
\imagedestroy($img);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -222,19 +265,17 @@ class UploadFile
|
||||||
*
|
*
|
||||||
* @param array $files Array of files
|
* @param array $files Array of files
|
||||||
*
|
*
|
||||||
* @return void
|
* @return string
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
private function findOutputDir(array $files)
|
private function findOutputDir(array $files) : string
|
||||||
{
|
{
|
||||||
if (count($files) > 1) {
|
do {
|
||||||
do {
|
$rndPath = \str_pad(\dechex(rand(0, 65535)), 4, '0', STR_PAD_LEFT);
|
||||||
$rndPath = str_pad(dechex(rand(0, 65535)), 4, '0', STR_PAD_LEFT);
|
} while (\file_exists($this->outputDir . '/' . $rndPath));
|
||||||
} while (file_exists($this->outputDir . '/' . $rndPath));
|
|
||||||
|
|
||||||
$this->outputDir = $this->outputDir . '/' . $rndPath;
|
return $this->outputDir . '/' . $rndPath;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -270,9 +311,16 @@ class UploadFile
|
||||||
return $this->maxSize;
|
return $this->maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setInterlaced(bool $interlaced) : void
|
/**
|
||||||
|
* @param bool $isInterlaced Is interlaced
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public function setInterlaced(bool $isInterlaced) : void
|
||||||
{
|
{
|
||||||
$this->interlaced = $interlaced;
|
$this->isInterlaced = $isInterlaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -282,7 +330,7 @@ class UploadFile
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setMaxSize(int $maxSize)
|
public function setMaxSize(int $maxSize) : void
|
||||||
{
|
{
|
||||||
$this->maxSize = $maxSize;
|
$this->maxSize = $maxSize;
|
||||||
}
|
}
|
||||||
|
|
@ -310,13 +358,13 @@ class UploadFile
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $allowedTypes Allowed file types
|
* @param string $allowedTypes Allowed file types
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function addAllowedTypes($allowedTypes)
|
public function addAllowedTypes(string $allowedTypes) : void
|
||||||
{
|
{
|
||||||
$this->allowedTypes[] = $allowedTypes;
|
$this->allowedTypes[] = $allowedTypes;
|
||||||
}
|
}
|
||||||
|
|
@ -333,14 +381,14 @@ class UploadFile
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define output directory of the upload
|
* Define output directory of the upload
|
||||||
*
|
*
|
||||||
* @param string $outputDir Output directory of the uploaded file
|
* @param string $outputDir Output directory of the uploaded file
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setOutputDir(string $outputDir)
|
public function setOutputDir(string $outputDir) : void
|
||||||
{
|
{
|
||||||
$this->outputDir = $outputDir;
|
$this->outputDir = $outputDir;
|
||||||
}
|
}
|
||||||
|
|
@ -357,28 +405,28 @@ class UploadFile
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the file name of the uploaded file
|
* Set the file name of the uploaded file
|
||||||
*
|
*
|
||||||
* @param string $fileName File name of the uploaded file
|
* @param string $fileName File name of the uploaded file
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setFileName(string $fileName)
|
public function setFileName(string $fileName) : void
|
||||||
{
|
{
|
||||||
$this->fileName = $fileName;
|
$this->fileName = $fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define if the uploaded file name should be the same file name as the original file
|
* Define if the uploaded file name should be the same file name as the original file
|
||||||
*
|
*
|
||||||
* @param bool $preserveFileName Keep file name of the original file
|
* @param bool $preserveFileName Keep file name of the original file
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function setPreserveFileName(bool $preserveFileName)
|
public function setPreserveFileName(bool $preserveFileName) : void
|
||||||
{
|
{
|
||||||
$this->preserveFileName = $preserveFileName;
|
$this->preserveFileName = $preserveFileName;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user