Issues (14)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Classes/Service/FocusCropService.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Crop images via focus crop.
5
 */
6
7
namespace HDNET\Focuspoint\Service;
8
9
use HDNET\Focuspoint\Domain\Repository\FileStandaloneRepository;
10
use TYPO3\CMS\Core\Resource\FileInterface;
11
use TYPO3\CMS\Core\Resource\FileReference as CoreFileReference;
12
use TYPO3\CMS\Core\Resource\ResourceFactory;
13
use TYPO3\CMS\Core\Utility\GeneralUtility;
14
use TYPO3\CMS\Core\Utility\MathUtility;
15
use TYPO3\CMS\Core\Utility\PathUtility;
16
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
17
use TYPO3\CMS\Extbase\Object\ObjectManager;
18
use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
19
20
/**
21
 * Crop images via focus crop.
22
 */
23
class FocusCropService extends AbstractService
24
{
25
    const SIGNAL_tempImageCropped = 'tempImageCropped';
26
27
    /**
28
     * @var Dispatcher
29
     */
30
    protected $signalSlotDispatcher;
31
32
    /**
33
     * @var string
34
     */
35
    protected $tempImageFolder;
36
37
    /**
38
     * get the image.
39
     *
40
     * @param $src
41
     * @param $image
42
     * @param $treatIdAsReference
43
     *
44
     * @throws \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
45
     * @throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
46
     *
47
     * @return \TYPO3\CMS\Core\Resource\File|FileInterface|CoreFileReference|\TYPO3\CMS\Core\Resource\Folder
48
     */
49
    public function getViewHelperImage($src, $image, $treatIdAsReference)
50
    {
51
        $resourceFactory = ResourceFactory::getInstance();
52
        if ($image instanceof \TYPO3\CMS\Core\Resource\FileReference) {
53
            return $image;
54
        }
55
        if ($image instanceof FileReference) {
56
            return $image->getOriginalResource();
57
        }
58
        if (!MathUtility::canBeInterpretedAsInteger($src)) {
59
            return $resourceFactory->retrieveFileOrFolderObject($src);
60
        }
61
        if (!$treatIdAsReference) {
62
            return $resourceFactory->getFileObject($src);
63
        }
64
        $image = $resourceFactory->getFileReferenceObject($src);
65
66
        return $image;
67
    }
68
69
    /**
70
     * Helper function for view helpers.
71
     *
72
     * @param $src
73
     * @param $image
74
     * @param $treatIdAsReference
75
     * @param $ratio
76
     *
77
     * @throws \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
78
     * @throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
79
     *
80
     * @return string
81
     */
82
    public function getCroppedImageSrcForViewHelper($src, $image, $treatIdAsReference, string $ratio)
83
    {
84
        $file = $this->getViewHelperImage($src, $image, $treatIdAsReference);
85
86
        return $this->getCroppedImageSrcByFile($file, $ratio);
0 ignored issues
show
It seems like $file defined by $this->getViewHelperImag...e, $treatIdAsReference) on line 84 can also be of type object<TYPO3\CMS\Core\Resource\Folder>; however, HDNET\Focuspoint\Service...CroppedImageSrcByFile() does only seem to accept object<TYPO3\CMS\Core\Resource\FileInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
87
    }
88
89
    /**
90
     * Get the cropped image.
91
     *
92
     * @param string $fileReference
93
     * @param string $ratio
94
     *
95
     * @return string The new filename
96
     */
97
    public function getCroppedImageSrcByFileReference($fileReference, string $ratio)
98
    {
99
        if ($fileReference instanceof FileReference) {
100
            $fileReference = $fileReference->getOriginalResource();
101
        }
102
        if ($fileReference instanceof CoreFileReference) {
103
            return $this->getCroppedImageSrcByFile($fileReference->getOriginalFile(), $ratio);
104
        }
105
        throw new \InvalidArgumentException('The given argument is not a valid file reference', 1475144027);
106
    }
107
108
    /**
109
     * Get the cropped image by File Object.
110
     *
111
     * @param FileInterface $file
112
     * @param string        $ratio
113
     *
114
     * @return string The new filename
115
     */
116
    public function getCroppedImageSrcByFile(FileInterface $file, string $ratio)
117
    {
118
        $result = $this->getCroppedImageSrcBySrc(
119
            $file->getForLocalProcessing(false),
120
            $ratio,
121
            $file->getProperty('focus_point_x'),
122
            $file->getProperty('focus_point_y')
123
        );
124
        if ('' === $result) {
125
            return $file->getPublicUrl();
126
        }
127
128
        return $result;
129
    }
130
131
    /**
132
     * Get the cropped image by src.
133
     *
134
     * @param string $src   Relative file name
135
     * @param string $ratio
136
     * @param int    $x
137
     * @param int    $y
138
     *
139
     * @return string The new filename
140
     */
141
    public function getCroppedImageSrcBySrc(string $src, string $ratio, int $x, int $y): string
142
    {
143
        $absoluteImageName = GeneralUtility::getFileAbsFileName($src);
144
        if (!\is_file($absoluteImageName)) {
145
            return '';
146
        }
147
148
        /** @var \TYPO3\CMS\Core\Http\NormalizedParams $params */
149
        $params = $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams');
150
        $docRoot = \rtrim($params->getDocumentRoot(), '/') . '/';
151
        $relativeSrc = \str_replace($docRoot, '', $absoluteImageName);
152
        $focusPointX = MathUtility::forceIntegerInRange((int) $x, -100, 100, 0);
153
        $focusPointY = MathUtility::forceIntegerInRange((int) $y, -100, 100, 0);
154
155
        if (0 === $focusPointX && 0 === $focusPointY) {
156
            $row = GeneralUtility::makeInstance(FileStandaloneRepository::class)->findOneByRelativeFilePath($relativeSrc);
157
            if (isset($row['focus_point_x'])) {
158
                $focusPointX = MathUtility::forceIntegerInRange((int) $row['focus_point_x'], -100, 100, 0);
159
                $focusPointY = MathUtility::forceIntegerInRange((int) $row['focus_point_y'], -100, 100, 0);
160
            }
161
        }
162
163
        $tempImageFolder = $this->getTempImageFolder();
164
        $tempImageName = $this->generateTempImageName($absoluteImageName, $ratio, $focusPointX, $focusPointY);
165
        $tempImageName = $tempImageFolder . $tempImageName;
166
167
        $absoluteTempImageName = GeneralUtility::getFileAbsFileName($tempImageName);
168
169
        if (\is_file($absoluteTempImageName)) {
170
            return $tempImageName;
171
        }
172
173
        $absoluteTempImageFolder = GeneralUtility::getFileAbsFileName($tempImageFolder);
174
        if (!\is_dir($absoluteTempImageFolder)) {
175
            GeneralUtility::mkdir_deep($absoluteTempImageFolder);
176
        }
177
178
        $imageSizeInformation = \getimagesize($absoluteImageName);
179
        $width = $imageSizeInformation[0];
180
        $height = $imageSizeInformation[1];
181
182
        // dimensions
183
        /** @var DimensionService $dimensionService */
184
        $dimensionService = GeneralUtility::makeInstance(DimensionService::class);
185
        list($focusWidth, $focusHeight) = $dimensionService->getFocusWidthAndHeight($width, $height, $ratio);
186
187
        $cropMode = $dimensionService->getCropMode($width, $height, $ratio);
188
        list($sourceX, $sourceY) = $dimensionService->calculateSourcePosition(
189
            $cropMode,
190
            $width,
191
            $height,
192
            $focusWidth,
193
            $focusHeight,
194
            $focusPointX,
195
            $focusPointY
196
        );
197
198
        $cropService = GeneralUtility::makeInstance(CropService::class);
199
        $cropService->createImage(
200
            $absoluteImageName,
201
            $focusWidth,
202
            $focusHeight,
203
            $sourceX,
204
            $sourceY,
205
            $absoluteTempImageName
206
        );
207
208
        $this->emitTempImageCropped($tempImageName);
209
210
        return $tempImageName;
211
    }
212
213
    /**
214
     * Emit tempImageCropped signal.
215
     *
216
     * @param string $tempImageName
217
     *
218
     * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException
219
     * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException
220
     */
221
    protected function emitTempImageCropped(string $tempImageName)
222
    {
223
        $this->getSignalSlotDispatcher()->dispatch(__CLASS__, self::SIGNAL_tempImageCropped, [$tempImageName]);
224
    }
225
226
    /**
227
     * Get the SignalSlot dispatcher.
228
     *
229
     * @return Dispatcher
230
     */
231
    protected function getSignalSlotDispatcher()
232
    {
233
        if (!isset($this->signalSlotDispatcher)) {
234
            $this->signalSlotDispatcher = $this->getObjectManager()->get(Dispatcher::class);
235
        }
236
237
        return $this->signalSlotDispatcher;
238
    }
239
240
    /**
241
     * Gets the ObjectManager.
242
     *
243
     * @return ObjectManager
244
     */
245
    protected function getObjectManager()
246
    {
247
        return GeneralUtility::makeInstance(ObjectManager::class);
248
    }
249
250
    /**
251
     * @param string $absoluteImageName
252
     * @param string $ratio
253
     * @param int    $focusPointX
254
     * @param int    $focusPointY
255
     *
256
     * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException
257
     * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException
258
     *
259
     * @return string
260
     */
261
    protected function generateTempImageName(string $absoluteImageName, string $ratio, int $focusPointX, int $focusPointY): string
262
    {
263
        $name = '';
264
265
        list($name) = $this->getSignalSlotDispatcher()->dispatch(__CLASS__, __FUNCTION__, [
266
            $name,
267
            $absoluteImageName,
268
            $ratio,
269
            $focusPointX,
270
            $focusPointY,
271
        ]);
272
273
        if ($name) {
274
            return $name;
275
        }
276
277
        $hash = \function_exists('sha1_file') ? \sha1_file($absoluteImageName) : \md5_file($absoluteImageName);
278
        $name = $hash . '-fp-' . \preg_replace(
279
            '/[^0-9a-z-]/',
280
            '-',
281
            $ratio
282
        ) . '-' . $focusPointX . '-' . $focusPointY . '.' . PathUtility::pathinfo(
283
            $absoluteImageName,
284
            PATHINFO_EXTENSION
285
        );
286
        $name = \preg_replace('/--+/', '-', $name);
287
288
        return $name;
289
    }
290
291
    /**
292
     * Return the folder for generated images.
293
     *
294
     * @return string Path relative to PATH_site
295
     */
296
    protected function getTempImageFolder(): string
297
    {
298
        if (null === $this->tempImageFolder) {
299
            $extConf = \unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['focuspoint']);
300
            if (isset($extConf['tempImageFolder'])) {
301
                $this->tempImageFolder = $extConf['tempImageFolder'];
302
            } else {
303
                $this->tempImageFolder = 'typo3temp/focuscrop/';
304
            }
305
        }
306
307
        return $this->tempImageFolder;
308
    }
309
}
310