This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Spatie\Image; |
||
4 | |||
5 | use Exception; |
||
6 | use FilesystemIterator; |
||
7 | use League\Glide\Server; |
||
8 | use League\Glide\ServerFactory; |
||
9 | use Spatie\Image\Exceptions\CouldNotConvert; |
||
10 | use Spatie\Image\Exceptions\InvalidTemporaryDirectory; |
||
11 | |||
12 | final class GlideConversion |
||
13 | { |
||
14 | /** @var string */ |
||
15 | private $inputImage; |
||
16 | |||
17 | /** @var string */ |
||
18 | private $imageDriver = 'gd'; |
||
19 | |||
20 | /** @var string */ |
||
21 | private $conversionResult = null; |
||
22 | |||
23 | /** @var string */ |
||
24 | private $temporaryDirectory = null; |
||
25 | |||
26 | public static function create(string $inputImage): self |
||
27 | { |
||
28 | return new self($inputImage); |
||
29 | } |
||
30 | |||
31 | public function setTemporaryDirectory(string $temporaryDirectory) |
||
32 | { |
||
33 | if (! isset($temporaryDirectory)) { |
||
34 | return $this; |
||
35 | } |
||
36 | |||
37 | if (! is_dir($temporaryDirectory)) { |
||
38 | try { |
||
39 | mkdir($temporaryDirectory); |
||
40 | } catch (Exception $exception) { |
||
41 | throw InvalidTemporaryDirectory::temporaryDirectoryNotCreatable($temporaryDirectory); |
||
42 | } |
||
43 | } |
||
44 | |||
45 | if (! is_writable($temporaryDirectory)) { |
||
46 | throw InvalidTemporaryDirectory::temporaryDirectoryNotWritable($temporaryDirectory); |
||
47 | } |
||
48 | |||
49 | $this->temporaryDirectory = $temporaryDirectory; |
||
50 | |||
51 | return $this; |
||
52 | } |
||
53 | |||
54 | public function getTemporaryDirectory(): string |
||
55 | { |
||
56 | return $this->temporaryDirectory; |
||
57 | } |
||
58 | |||
59 | public function __construct(string $inputImage) |
||
60 | { |
||
61 | $this->temporaryDirectory = sys_get_temp_dir(); |
||
62 | |||
63 | $this->inputImage = $inputImage; |
||
64 | } |
||
65 | |||
66 | public function useImageDriver(string $imageDriver): self |
||
67 | { |
||
68 | $this->imageDriver = $imageDriver; |
||
69 | |||
70 | return $this; |
||
71 | } |
||
72 | |||
73 | public function performManipulations(Manipulations $manipulations) |
||
74 | { |
||
75 | foreach ($manipulations->getManipulationSequence() as $manipulationGroup) { |
||
76 | $inputFile = $this->conversionResult ?? $this->inputImage; |
||
77 | |||
78 | $watermarkPath = $this->extractWatermarkPath($manipulationGroup); |
||
79 | |||
80 | $glideServer = $this->createGlideServer($inputFile, $watermarkPath); |
||
81 | |||
82 | $glideServer->setGroupCacheInFolders(false); |
||
83 | |||
84 | $manipulatedImage = $this->temporaryDirectory.DIRECTORY_SEPARATOR.$glideServer->makeImage( |
||
85 | pathinfo($inputFile, PATHINFO_BASENAME), |
||
86 | $this->prepareManipulations($manipulationGroup) |
||
87 | ); |
||
88 | |||
89 | if ($this->conversionResult) { |
||
90 | unlink($this->conversionResult); |
||
91 | } |
||
92 | |||
93 | $this->conversionResult = $manipulatedImage; |
||
94 | } |
||
95 | |||
96 | return $this; |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Removes the watermark path from the manipulationGroup and returns it. This way it can be injected into the Glide |
||
101 | * server as the `watermarks` path. |
||
102 | * |
||
103 | * @param $manipulationGroup |
||
104 | * |
||
105 | * @return null|string |
||
106 | */ |
||
107 | private function extractWatermarkPath(&$manipulationGroup) |
||
108 | { |
||
109 | if (array_key_exists('watermark', $manipulationGroup)) { |
||
110 | $watermarkPath = dirname($manipulationGroup['watermark']); |
||
111 | |||
112 | $manipulationGroup['watermark'] = basename($manipulationGroup['watermark']); |
||
113 | |||
114 | return $watermarkPath; |
||
115 | } |
||
116 | } |
||
117 | |||
118 | private function createGlideServer($inputFile, string $watermarkPath = null): Server |
||
119 | { |
||
120 | $config = [ |
||
121 | 'source' => dirname($inputFile), |
||
122 | 'cache' => $this->temporaryDirectory, |
||
123 | 'driver' => $this->imageDriver, |
||
124 | ]; |
||
125 | |||
126 | if ($watermarkPath) { |
||
0 ignored issues
–
show
|
|||
127 | $config['watermarks'] = $watermarkPath; |
||
128 | } |
||
129 | |||
130 | return ServerFactory::create($config); |
||
131 | } |
||
132 | |||
133 | public function save(string $outputFile) |
||
134 | { |
||
135 | if ($this->conversionResult == '') { |
||
136 | copy($this->inputImage, $outputFile); |
||
137 | |||
138 | return; |
||
139 | } |
||
140 | |||
141 | $conversionResultDirectory = pathinfo($this->conversionResult, PATHINFO_DIRNAME); |
||
142 | |||
143 | copy($this->conversionResult, $outputFile); |
||
144 | |||
145 | unlink($this->conversionResult); |
||
146 | |||
147 | if ($this->directoryIsEmpty($conversionResultDirectory) && $conversionResultDirectory !== '/tmp') { |
||
148 | rmdir($conversionResultDirectory); |
||
149 | } |
||
150 | } |
||
151 | |||
152 | private function prepareManipulations(array $manipulationGroup): array |
||
153 | { |
||
154 | $glideManipulations = []; |
||
155 | |||
156 | foreach ($manipulationGroup as $name => $argument) { |
||
157 | if ($name !== 'optimize') { |
||
158 | $glideManipulations[$this->convertToGlideParameter($name)] = $argument; |
||
159 | } |
||
160 | } |
||
161 | |||
162 | return $glideManipulations; |
||
163 | } |
||
164 | |||
165 | private function convertToGlideParameter(string $manipulationName): string |
||
166 | { |
||
167 | $conversions = [ |
||
168 | 'width' => 'w', |
||
169 | 'height' => 'h', |
||
170 | 'blur' => 'blur', |
||
171 | 'pixelate' => 'pixel', |
||
172 | 'crop' => 'fit', |
||
173 | 'manualCrop' => 'crop', |
||
174 | 'orientation' => 'or', |
||
175 | 'flip' => 'flip', |
||
176 | 'fit' => 'fit', |
||
177 | 'devicePixelRatio' => 'dpr', |
||
178 | 'brightness' => 'bri', |
||
179 | 'contrast' => 'con', |
||
180 | 'gamma' => 'gam', |
||
181 | 'sharpen' => 'sharp', |
||
182 | 'filter' => 'filt', |
||
183 | 'background' => 'bg', |
||
184 | 'border' => 'border', |
||
185 | 'quality' => 'q', |
||
186 | 'format' => 'fm', |
||
187 | 'watermark' => 'mark', |
||
188 | 'watermarkWidth' => 'markw', |
||
189 | 'watermarkHeight' => 'markh', |
||
190 | 'watermarkFit' => 'markfit', |
||
191 | 'watermarkPaddingX' => 'markx', |
||
192 | 'watermarkPaddingY' => 'marky', |
||
193 | 'watermarkPosition' => 'markpos', |
||
194 | 'watermarkOpacity' => 'markalpha', |
||
195 | ]; |
||
196 | |||
197 | if (! isset($conversions[$manipulationName])) { |
||
198 | throw CouldNotConvert::unknownManipulation($manipulationName); |
||
199 | } |
||
200 | |||
201 | return $conversions[$manipulationName]; |
||
202 | } |
||
203 | |||
204 | private function directoryIsEmpty(string $directory): bool |
||
205 | { |
||
206 | $iterator = new FilesystemIterator($directory); |
||
207 | |||
208 | return ! $iterator->valid(); |
||
209 | } |
||
210 | } |
||
211 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: