Skip to content

Commit

Permalink
Added validation to pasted files to the wysiwyg editor
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuszkrzaczkowski committed May 5, 2022
1 parent ddb29d4 commit bf69c42
Show file tree
Hide file tree
Showing 6 changed files with 427 additions and 234 deletions.
57 changes: 35 additions & 22 deletions app/Fields/File.php
Expand Up @@ -166,6 +166,39 @@ public static function loadFromPath(string $path)
return $instance;
}

/**
* Load file instance from base string.
*
* @param string $contents
* @param array $param
*
* @return \self|null
*/
public static function loadFromBase(string $contents, array $param = []): ?self
{
$result = explode(',', $contents, 2);
$contentType = $isBase64 = false;
if (2 === \count($result)) {
[$metadata, $data] = $result;
foreach (explode(';', $metadata) as $cur) {
if ('base64' === $cur) {
$isBase64 = true;
} elseif ('data:' === substr($cur, 0, 5)) {
$contentType = str_replace('data:', '', $cur);
}
}
} else {
$data = $result[0];
}
$data = rawurldecode($data);
$rawData = $isBase64 ? base64_decode($data) : $data;
if (\strlen($rawData) < 12) {
Log::error('Incorrect content value: ' . $contents, __CLASS__);
return null;
}
return static::loadFromContent($rawData, false, array_merge($param, ['mimeType' => $contentType]));
}

/**
* Load file instance from content.
*
Expand Down Expand Up @@ -881,27 +914,7 @@ public static function getMimeContentType($fileName)
*/
public static function saveFromString(string $contents, array $param = [])
{
$result = explode(',', $contents, 2);
$contentType = $isBase64 = false;
if (2 === \count($result)) {
[$metadata, $data] = $result;
foreach (explode(';', $metadata) as $cur) {
if ('base64' === $cur) {
$isBase64 = true;
} elseif ('data:' === substr($cur, 0, 5)) {
$contentType = str_replace('data:', '', $cur);
}
}
} else {
$data = $result[0];
}
$data = rawurldecode($data);
$rawData = $isBase64 ? base64_decode($data) : $data;
if (\strlen($rawData) < 12) {
Log::error('Incorrect content value: ' . $contents, __CLASS__);
return false;
}
$fileInstance = static::loadFromContent($rawData, false, array_merge($param, ['mimeType' => $contentType]));
$fileInstance = static::loadFromBase($contents, $param);
if ($fileInstance->validateAndSecure()) {
return $fileInstance;
}
Expand Down Expand Up @@ -1230,7 +1243,7 @@ public function insertTempFile(array $params): int
'createdtime' => date('Y-m-d H:i:s'),
'fieldname' => null,
'key' => null,
'crmid' => 0
'crmid' => 0,
];
foreach ($data as $key => &$value) {
if (isset($params[$key])) {
Expand Down
16 changes: 16 additions & 0 deletions app/Validator.php
Expand Up @@ -483,4 +483,20 @@ public static function path(string $input): bool
return !self::dirName($dir);
});
}

/**
* Check base64.
*
* @param string $input
*
* @return bool
*/
public static function base64(string $input): bool
{
if (empty($input)) {
return false;
}
$explode = explode(',', $input);
return 2 === \count($explode) && 1 === preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $explode[1]);
}
}
2 changes: 1 addition & 1 deletion config/version.php
@@ -1,7 +1,7 @@
<?php

return [
'appVersion' => '6.3.220',
'appVersion' => '6.3.221',
'patchVersion' => '2022.05.05',
'lib_roundcube' => '0.2.12',
];
43 changes: 35 additions & 8 deletions modules/Vtiger/actions/Fields.php
Expand Up @@ -59,6 +59,7 @@ public function __construct()
$this->exposeMethod('validateByMode');
$this->exposeMethod('verifyPhoneNumber');
$this->exposeMethod('changeFavoriteOwner');
$this->exposeMethod('validateFile');
}

/**
Expand All @@ -68,7 +69,7 @@ public function __construct()
*
* @throws \App\Exceptions\NoPermitted
*/
public function getOwners(App\Request $request)
public function getOwners(App\Request $request): void
{
if (!App\Config::performance('SEARCH_OWNERS_BY_AJAX')) {
throw new \App\Exceptions\NoPermitted('LBL_PERMISSION_DENIED', 406);
Expand Down Expand Up @@ -121,7 +122,7 @@ public function getOwners(App\Request $request)
*
* @throws \App\Exceptions\NoPermitted
*/
public function getUserRole(App\Request $request)
public function getUserRole(App\Request $request): void
{
if (!App\Config::performance('SEARCH_ROLES_BY_AJAX')) {
throw new \App\Exceptions\NoPermitted('LBL_PERMISSION_DENIED', 406);
Expand All @@ -148,7 +149,7 @@ public function getUserRole(App\Request $request)
*
* @throws \App\Exceptions\NoPermitted
*/
public function getReference(App\Request $request)
public function getReference(App\Request $request): void
{
if ($request->has('fieldName')) {
$fieldModel = Vtiger_Module_Model::getInstance($request->getModule())->getFieldByName($request->getByType('fieldName', 2));
Expand Down Expand Up @@ -195,7 +196,7 @@ public function getReference(App\Request $request)
*
* @throws \App\Exceptions\NoPermitted
*/
public function verifyPhoneNumber(App\Request $request)
public function verifyPhoneNumber(App\Request $request): void
{
if ('phone' !== $this->fieldModel->getFieldDataType()) {
throw new \App\Exceptions\NoPermitted('ERR_NO_PERMISSIONS_TO_FIELD');
Expand Down Expand Up @@ -224,7 +225,7 @@ public function verifyPhoneNumber(App\Request $request)
*
* @param \App\Request $request
*/
public function findAddress(App\Request $request)
public function findAddress(App\Request $request): void
{
$instance = \App\Map\Address::getInstance($request->getByType('type'));
$response = new Vtiger_Response();
Expand All @@ -243,7 +244,7 @@ public function findAddress(App\Request $request)
* @throws \App\Exceptions\NoPermitted
* @throws \yii\db\Exception
*/
public function changeFavoriteOwner(App\Request $request)
public function changeFavoriteOwner(App\Request $request): void
{
if (!App\Config::module('Users', 'FAVORITE_OWNERS') || (\App\User::getCurrentUserRealId() !== \App\User::getCurrentUserId())) {
throw new \App\Exceptions\NoPermitted('LBL_PERMISSION_DENIED', 406);
Expand All @@ -265,7 +266,7 @@ public function changeFavoriteOwner(App\Request $request)
*
* @throws \App\Exceptions\NoPermitted
*/
public function validateForField(App\Request $request)
public function validateForField(App\Request $request): void
{
$fieldModel = Vtiger_Module_Model::getInstance($request->getModule())->getFieldByName($request->getByType('fieldName', 2));
if (!$fieldModel || !$fieldModel->isActiveField() || !$fieldModel->isViewEnabled()) {
Expand All @@ -288,7 +289,7 @@ public function validateForField(App\Request $request)
*
* @throws \App\Exceptions\NoPermitted
*/
public function validateByMode(App\Request $request)
public function validateByMode(App\Request $request): void
{
if ($request->isEmpty('purifyMode') || !$request->has('value')) {
throw new \App\Exceptions\NoPermitted('ERR_ILLEGAL_VALUE', 406);
Expand All @@ -299,4 +300,30 @@ public function validateByMode(App\Request $request)
]);
$response->emit();
}

/**
* Validate file.
*
* @param App\Request $request
*
* @return void
*/
public function validateFile(App\Request $request): void
{
$validate = false;
if ($request->has('base64')) {
$fileInstance = \App\Fields\File::loadFromBase($request->getByType('base64', 'base64'), ['validateAllowedFormat' => 'image']);
if ($fileInstance && $fileInstance->validate()) {
$validate = true;
} else {
$validateError = $fileInstance->validateError;
}
}
$response = new Vtiger_Response();
$response->setResult([
'validate' => $validate,
'validateError' => $validateError ?? null,
]);
$response->emit();
}
}

0 comments on commit bf69c42

Please sign in to comment.