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 | /* |
||
4 | * This file is part of the 2amigos/qrcode-library project. |
||
5 | * |
||
6 | * (c) 2amigOS! <http://2amigos.us/> |
||
7 | * |
||
8 | * For the full copyright and license information, please view |
||
9 | * the LICENSE file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Da\QrCode\Traits; |
||
13 | |||
14 | use BaconQrCode\Renderer\Image\Png; |
||
15 | use BaconQrCode\Writer; |
||
16 | use Da\QrCode\Contracts\LabelInterface; |
||
17 | use Da\QrCode\Contracts\QrCodeInterface; |
||
18 | use Da\QrCode\Exception\BadMethodCallException; |
||
19 | use Da\QrCode\Exception\ValidationException; |
||
20 | use Da\QrCode\Renderer\Jpg; |
||
21 | use Zxing\QrReader; |
||
22 | |||
23 | trait ImageTrait |
||
24 | { |
||
25 | protected $validate = false; |
||
26 | |||
27 | /** |
||
28 | * Whether to validate result or not. |
||
29 | * |
||
30 | * @param bool $validate |
||
31 | * |
||
32 | * @return $this |
||
33 | */ |
||
34 | public function validateResult(bool $validate): self |
||
35 | { |
||
36 | $this->validate = $validate; |
||
37 | |||
38 | return $this; |
||
39 | } |
||
40 | |||
41 | /** |
||
42 | * {@inheritdoc} |
||
43 | * @throws ValidationException |
||
44 | * @throws BadMethodCallException |
||
45 | */ |
||
46 | public function writeString(QrCodeInterface $qrCode): string |
||
47 | { |
||
48 | /** @var Png|Jpg $renderer */ |
||
49 | $renderer = $this->renderer; |
||
0 ignored issues
–
show
|
|||
50 | |||
51 | $renderer->setWidth($qrCode->getSize()); |
||
52 | $renderer->setHeight($qrCode->getSize()); |
||
53 | $renderer->setMargin(0); |
||
54 | $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor())); |
||
0 ignored issues
–
show
It seems like
convertColor() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
55 | $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor())); |
||
0 ignored issues
–
show
It seems like
convertColor() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
56 | $writer = new Writer($renderer); |
||
57 | $string = $writer->writeString( |
||
58 | $qrCode->getText(), |
||
59 | $qrCode->getEncoding(), |
||
60 | $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()) |
||
0 ignored issues
–
show
It seems like
convertErrorCorrectionLevel() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
61 | ); |
||
62 | $image = imagecreatefromstring($string); |
||
63 | $image = $this->addMargin( |
||
64 | $image, |
||
65 | $qrCode->getMargin(), |
||
66 | $qrCode->getSize(), |
||
67 | $qrCode->getForegroundColor(), |
||
68 | $qrCode->getBackgroundColor() |
||
69 | ); |
||
70 | |||
71 | if ($qrCode->getLogoPath()) { |
||
72 | $image = $this->addLogo($image, $qrCode->getLogoPath(), $qrCode->getLogoWidth()); |
||
73 | } |
||
74 | |||
75 | if ($qrCode->getLabel()) { |
||
76 | $image = $this->addLabel( |
||
77 | $image, |
||
78 | $qrCode->getLabel(), |
||
79 | $qrCode->getForegroundColor(), |
||
80 | $qrCode->getBackgroundColor() |
||
81 | ); |
||
82 | } |
||
83 | $string = $this->imageToString($image); |
||
0 ignored issues
–
show
It seems like
imageToString() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
84 | if ($this->validate) { |
||
85 | $reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB); |
||
86 | if ($reader->text() !== $qrCode->getText()) { |
||
87 | throw new ValidationException( |
||
88 | sprintf( |
||
89 | 'Built-in validation reader read "%s" instead of "%s"' . |
||
90 | 'Adjust your parameters to increase readability or disable built-in validation.', |
||
91 | $reader->text(), |
||
92 | $qrCode->getText() |
||
93 | ) |
||
94 | ); |
||
95 | } |
||
96 | } |
||
97 | |||
98 | return $string; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * @param resource $sourceImage |
||
103 | * @param int $margin |
||
104 | * @param int $size |
||
105 | * @param int[] $foregroundColor |
||
106 | * @param int[] $backgroundColor |
||
107 | * |
||
108 | * @return resource |
||
109 | */ |
||
110 | protected function addMargin($sourceImage, $margin, $size, array $foregroundColor, array $backgroundColor) |
||
111 | { |
||
112 | $additionalWhitespace = $this->calculateAdditionalWhiteSpace($sourceImage, $foregroundColor); |
||
113 | |||
114 | if ($additionalWhitespace === 0 && $margin === 0) { |
||
115 | return $sourceImage; |
||
116 | } |
||
117 | |||
118 | $targetImage = imagecreatetruecolor($size + $margin * 2, $size + $margin * 2); |
||
119 | $backgroundColor = imagecolorallocate( |
||
120 | $targetImage, |
||
121 | $backgroundColor['r'], |
||
122 | $backgroundColor['g'], |
||
123 | $backgroundColor['b'] |
||
124 | ); |
||
125 | imagefill($targetImage, 0, 0, $backgroundColor); |
||
126 | imagecopyresampled( |
||
127 | $targetImage, |
||
128 | $sourceImage, |
||
129 | $margin, |
||
130 | $margin, |
||
131 | $additionalWhitespace, |
||
132 | $additionalWhitespace, |
||
133 | $size, |
||
134 | $size, |
||
135 | $size - 2 * $additionalWhitespace, |
||
136 | $size - 2 * $additionalWhitespace |
||
137 | ); |
||
138 | |||
139 | return $targetImage; |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * @param resource $image |
||
144 | * @param int[] $foregroundColor |
||
145 | * |
||
146 | * @return int |
||
147 | */ |
||
148 | protected function calculateAdditionalWhiteSpace($image, array $foregroundColor): int |
||
149 | { |
||
150 | $width = imagesx($image); |
||
151 | $height = imagesy($image); |
||
152 | $foregroundColor = imagecolorallocate( |
||
153 | $image, |
||
154 | $foregroundColor['r'], |
||
155 | $foregroundColor['g'], |
||
156 | $foregroundColor['b'] |
||
157 | ); |
||
158 | $whitespace = $width; |
||
159 | for ($y = 0; $y < $height; $y++) { |
||
160 | for ($x = 0; $x < $width; $x++) { |
||
161 | $color = imagecolorat($image, $x, $y); |
||
162 | if ($color == $foregroundColor || $x == $whitespace) { |
||
163 | $whitespace = min($whitespace, $x); |
||
164 | break; |
||
165 | } |
||
166 | } |
||
167 | } |
||
168 | |||
169 | return $whitespace; |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * @param resource $sourceImage |
||
174 | * @param string $logoPath |
||
175 | * @param int $logoWidth |
||
176 | * |
||
177 | * @return resource |
||
178 | */ |
||
179 | protected function addLogo($sourceImage, $logoPath, $logoWidth = null) |
||
180 | { |
||
181 | $logoImage = imagecreatefromstring(file_get_contents($logoPath)); |
||
182 | $logoSourceWidth = imagesx($logoImage); |
||
183 | $logoSourceHeight = imagesy($logoImage); |
||
184 | $logoTargetWidth = $logoWidth; |
||
185 | |||
186 | if ($logoTargetWidth === null) { |
||
187 | $logoTargetWidth = $logoSourceWidth; |
||
188 | $logoTargetHeight = $logoSourceHeight; |
||
189 | } else { |
||
190 | $scale = $logoTargetWidth / $logoSourceWidth; |
||
191 | $logoTargetHeight = intval($scale * imagesy($logoImage)); |
||
192 | } |
||
193 | |||
194 | $logoX = imagesx($sourceImage) / 2 - $logoTargetWidth / 2; |
||
195 | $logoY = imagesy($sourceImage) / 2 - $logoTargetHeight / 2; |
||
196 | |||
197 | imagecopyresampled( |
||
198 | $sourceImage, |
||
199 | $logoImage, |
||
200 | $logoX, |
||
201 | $logoY, |
||
202 | 0, |
||
203 | 0, |
||
204 | $logoTargetWidth, |
||
205 | $logoTargetHeight, |
||
206 | $logoSourceWidth, |
||
207 | $logoSourceHeight |
||
208 | ); |
||
209 | |||
210 | return $sourceImage; |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * @param resource $sourceImage |
||
215 | * @param LabelInterface $label |
||
216 | * @param int[] $foregroundColor |
||
217 | * @param int[] $backgroundColor |
||
218 | * |
||
219 | * @throws BadMethodCallException |
||
220 | * @return resource |
||
221 | */ |
||
222 | protected function addLabel( |
||
223 | $sourceImage, |
||
224 | LabelInterface $label, |
||
225 | array $foregroundColor, |
||
226 | array $backgroundColor |
||
227 | ) { |
||
228 | if (!function_exists('imagettfbbox')) { |
||
229 | throw new BadMethodCallException('Missing function "imagettfbbox". Did you install the FreeType library?'); |
||
230 | } |
||
231 | $labelText = $label->getText(); |
||
232 | $labelFontSize = $label->getFontSize(); |
||
233 | $labelFontPath = $label->getFont(); |
||
234 | $labelMargin = $label->getMargins(); |
||
235 | $labelAlignment = $label->getAlignment(); |
||
236 | |||
237 | $labelBox = imagettfbbox($labelFontSize, 0, $labelFontPath, $labelText); |
||
238 | $labelBoxWidth = ($labelBox[2] - $labelBox[0]); |
||
239 | $labelBoxHeight = ($labelBox[0] - $labelBox[7]); |
||
240 | $sourceWidth = imagesx($sourceImage); |
||
241 | $sourceHeight = imagesy($sourceImage); |
||
242 | $targetWidth = $sourceWidth; |
||
243 | $targetHeight = $sourceHeight + $labelBoxHeight + $labelMargin['t'] + $labelMargin['b']; |
||
244 | |||
245 | // Create empty target image |
||
246 | $targetImage = imagecreatetruecolor($targetWidth, $targetHeight); |
||
247 | $foregroundColor = imagecolorallocate( |
||
248 | $targetImage, |
||
249 | $foregroundColor['r'], |
||
250 | $foregroundColor['g'], |
||
251 | $foregroundColor['b'] |
||
252 | ); |
||
253 | $backgroundColor = imagecolorallocate( |
||
254 | $targetImage, |
||
255 | $backgroundColor['r'], |
||
256 | $backgroundColor['g'], |
||
257 | $backgroundColor['b'] |
||
258 | ); |
||
259 | imagefill($targetImage, 0, 0, $backgroundColor); |
||
260 | // Copy source image to target image |
||
261 | imagecopyresampled( |
||
262 | $targetImage, |
||
263 | $sourceImage, |
||
264 | 0, |
||
265 | 0, |
||
266 | 0, |
||
267 | 0, |
||
268 | $sourceWidth, |
||
269 | $sourceHeight, |
||
270 | $sourceWidth, |
||
271 | $sourceHeight |
||
272 | ); |
||
273 | switch ($labelAlignment) { |
||
274 | case LabelInterface::ALIGN_LEFT: |
||
275 | $labelX = $labelMargin['l']; |
||
276 | break; |
||
277 | case LabelInterface::ALIGN_RIGHT: |
||
278 | $labelX = $targetWidth - $labelBoxWidth - $labelMargin['r']; |
||
279 | break; |
||
280 | default: |
||
281 | $labelX = (int)($targetWidth / 2 - $labelBoxWidth / 2); |
||
282 | break; |
||
283 | } |
||
284 | $labelY = $targetHeight - $labelMargin['b']; |
||
285 | imagettftext($targetImage, $labelFontSize, 0, $labelX, $labelY, $foregroundColor, $labelFontPath, $labelText); |
||
286 | |||
287 | return $targetImage; |
||
288 | } |
||
289 | } |
||
290 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: