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 | namespace Fwolf\Util\Uuid; |
||
3 | |||
4 | /** |
||
5 | * Common define and function of UUID generators |
||
6 | * |
||
7 | * Length and separator are default configured for Base16, but they should be |
||
8 | * re-defined in child class. |
||
9 | * |
||
10 | * If check digit length is not zero, its enabled. |
||
11 | * |
||
12 | * @copyright Copyright 2008-2016 Fwolf |
||
13 | * @license http://opensource.org/licenses/MIT MIT |
||
14 | */ |
||
15 | abstract class AbstractTimeBasedUuidGenerator implements GeneratorInterface |
||
16 | { |
||
17 | /** |
||
18 | * Name of class to store explanation information |
||
19 | */ |
||
20 | const EXPLANATION_CLASS = Explanation::class; |
||
21 | |||
22 | /** |
||
23 | * Total UUID length |
||
24 | */ |
||
25 | const LENGTH = 36; |
||
26 | |||
27 | /** |
||
28 | * Length of second part |
||
29 | */ |
||
30 | const LENGTH_SECOND = 8; |
||
31 | |||
32 | /** |
||
33 | * Length of microsecond part |
||
34 | */ |
||
35 | const LENGTH_MICROSECOND = 4; |
||
36 | |||
37 | /** |
||
38 | * Length of group part |
||
39 | */ |
||
40 | const LENGTH_GROUP = 4; |
||
41 | |||
42 | /** |
||
43 | * Length of custom part |
||
44 | */ |
||
45 | const LENGTH_CUSTOM = 4; |
||
46 | |||
47 | /** |
||
48 | * Length of random part |
||
49 | */ |
||
50 | const LENGTH_RANDOM = 12; |
||
51 | |||
52 | /** |
||
53 | * How many chars check digit use, zero to disable it |
||
54 | * |
||
55 | * Longer can avoid duplicate but consume more length of random part. |
||
56 | */ |
||
57 | const LENGTH_CHECK_DIGIT = 0; |
||
58 | |||
59 | /** |
||
60 | * Separator chars between UUID parts |
||
61 | */ |
||
62 | const SEPARATOR = '-'; |
||
63 | |||
64 | |||
65 | /** |
||
66 | * Add check digit to an UUID |
||
67 | * |
||
68 | * Check digit will be add by replace chars from tail of UUID. |
||
69 | * |
||
70 | * Check digit should not include separator in common case. |
||
71 | * |
||
72 | * @param string $uuid |
||
73 | * @return string |
||
74 | */ |
||
75 | protected function addCheckDigit($uuid) |
||
76 | { |
||
77 | $headPartLength = static::LENGTH - static::LENGTH_CHECK_DIGIT; |
||
78 | $headPart = substr($uuid, 0, $headPartLength); |
||
79 | |||
80 | $checkDigit = $this->computeCheckDigit($headPart); |
||
81 | |||
82 | return $headPart . $checkDigit; |
||
83 | } |
||
84 | |||
85 | |||
86 | /** |
||
87 | * Compute check digit by given head part of UUID |
||
88 | * |
||
89 | * @param string $headPart |
||
90 | * @return string |
||
91 | */ |
||
92 | protected function computeCheckDigit($headPart) |
||
93 | { |
||
94 | // Use md5 which result only 0-0 a-f to fit all UUID mode |
||
95 | $checkDigit = substr(md5($headPart), 0, static::LENGTH_CHECK_DIGIT); |
||
96 | |||
97 | return $checkDigit; |
||
98 | } |
||
99 | |||
100 | |||
101 | /** |
||
102 | * {@inheritdoc} |
||
103 | */ |
||
104 | public function explain($uuid) |
||
105 | { |
||
106 | // Time is various by UUID mode, so meaning of time parts remain |
||
107 | // to child class to explain. |
||
108 | $second = substr($uuid, 0, static::LENGTH_SECOND); |
||
109 | $position = static::LENGTH_SECOND + strlen(static::SEPARATOR); |
||
110 | |||
111 | $microSecond = substr($uuid, $position, static::LENGTH_MICROSECOND); |
||
112 | $position += static::LENGTH_MICROSECOND + strlen(static::SEPARATOR); |
||
113 | |||
114 | $group = substr($uuid, $position, static::LENGTH_GROUP); |
||
115 | $position += static::LENGTH_GROUP + strlen(static::SEPARATOR); |
||
116 | |||
117 | $custom = substr($uuid, $position, static::LENGTH_CUSTOM); |
||
118 | $position += static::LENGTH_CUSTOM + strlen(static::SEPARATOR); |
||
119 | |||
120 | $random = substr($uuid, $position, static::LENGTH_RANDOM); |
||
121 | |||
122 | if (0 != static::LENGTH_CHECK_DIGIT) { |
||
123 | $checkDigit = substr($random, -1 * static::LENGTH_CHECK_DIGIT); |
||
124 | $random = substr( |
||
125 | $random, |
||
126 | 0, |
||
127 | static::LENGTH_RANDOM - static::LENGTH_CHECK_DIGIT |
||
128 | ); |
||
129 | } else { |
||
130 | $checkDigit = ''; |
||
131 | } |
||
132 | |||
133 | $verified = $this->verify($uuid); |
||
134 | |||
135 | |||
136 | $className = static::EXPLANATION_CLASS; |
||
137 | /** @var Explanation $explanation */ |
||
138 | $explanation = (new $className); |
||
139 | |||
140 | $explanation->setSecond($second) |
||
141 | ->setMicrosecond($microSecond) |
||
142 | ->setGroup($group) |
||
143 | ->setCustom($custom) |
||
144 | ->setRandom($random) |
||
145 | ->setCheckDigit($checkDigit) |
||
146 | ->setVerified($verified); |
||
147 | |||
148 | return $explanation; |
||
149 | } |
||
150 | |||
151 | |||
152 | /** |
||
153 | * {@inheritdoc} |
||
154 | */ |
||
155 | public function generate($groupId = '1', $custom = '') |
||
156 | { |
||
157 | $parts = array_merge($this->generateTimeParts(), [ |
||
158 | $this->generateGroupPart($groupId), |
||
159 | $this->generateCustomPart($custom), |
||
160 | $this->generateRandomPart(), |
||
161 | ]); |
||
162 | $uuid = implode(static::SEPARATOR, $parts); |
||
163 | |||
164 | if (0 != static::LENGTH_CHECK_DIGIT) { |
||
165 | $uuid = $this->addCheckDigit($uuid); |
||
166 | } |
||
167 | |||
168 | return $uuid; |
||
169 | } |
||
170 | |||
171 | |||
172 | /** |
||
173 | * @param string $custom |
||
174 | * @return string |
||
175 | */ |
||
176 | protected function generateCustomPart($custom = '') |
||
177 | { |
||
178 | if (static::LENGTH_CUSTOM > strlen($custom)) { |
||
179 | $custom .= $this->generateCustomPartAuto(); |
||
180 | } |
||
181 | |||
182 | return substr($custom, 0, static::LENGTH_CUSTOM); |
||
183 | } |
||
184 | |||
185 | |||
186 | /** |
||
187 | * Generate custom part if not assigned from param |
||
188 | * |
||
189 | * Get something contains machine signature, used for custom part if needed |
||
190 | * |
||
191 | * Suggest generate from machine signature, got same result for one machine |
||
192 | * or environment, but random is also OK. |
||
193 | * |
||
194 | * Result length should >= custom part, will be used from left. |
||
195 | * |
||
196 | * @return string |
||
197 | */ |
||
198 | protected function generateCustomPartAuto() |
||
199 | { |
||
200 | $seed = strval(filter_input(INPUT_SERVER, 'SCRIPT_NAME')) . |
||
201 | php_uname(); |
||
202 | |||
203 | return md5($seed); |
||
204 | } |
||
205 | |||
206 | |||
207 | /** |
||
208 | * @param string $groupId |
||
209 | * @return string |
||
210 | */ |
||
211 | protected function generateGroupPart($groupId) |
||
212 | { |
||
213 | $groupPart = substr( |
||
214 | str_repeat('0', static::LENGTH_GROUP) . $groupId, |
||
215 | -1 * static::LENGTH_GROUP |
||
216 | ); |
||
217 | |||
218 | return $groupPart; |
||
219 | } |
||
220 | |||
221 | |||
222 | /** |
||
223 | * @return string |
||
224 | */ |
||
225 | protected function generateRandomPart() |
||
226 | { |
||
227 | $randomPart = substr(md5(uniqid('', true)), 0, static::LENGTH_RANDOM); |
||
228 | |||
229 | return $randomPart; |
||
230 | } |
||
231 | |||
232 | |||
233 | /** |
||
234 | * @return array |
||
235 | */ |
||
236 | protected function generateTimeParts() |
||
237 | { |
||
238 | list($microSecond, $second) = explode(' ', microtime()); |
||
239 | |||
240 | // 8 chars timestamp second, hex mode |
||
241 | // 2030-12-31 = 1924876800 = 0x72bb4a00 |
||
0 ignored issues
–
show
|
|||
242 | // 0xffffff = 4294967295 = 2106-02-07 14:28:15 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
243 | $len = static::LENGTH_SECOND; |
||
244 | $second = substr( |
||
245 | str_repeat('0', $len) . base_convert($second, 10, 16), |
||
246 | -1 * $len |
||
247 | ); |
||
248 | |||
249 | // 4 chars from left-side start of current microsecond |
||
250 | // 0xffff = 65535 |
||
251 | // To make value fit range, * 100000 and div by 2(max 50000) |
||
252 | $len = static::LENGTH_MICROSECOND; |
||
253 | $microSecond = substr( |
||
254 | str_repeat('0', $len) . |
||
255 | base_convert(round($microSecond * 100000 / 2), 10, 16), |
||
256 | -1 * $len |
||
257 | ); |
||
258 | |||
259 | return [$second, $microSecond]; |
||
260 | } |
||
261 | |||
262 | |||
263 | /** |
||
264 | * {@inheritdoc} |
||
265 | * |
||
266 | * Without checkDigit, UUID can only verified by a few constraint like |
||
267 | * compare its length with definition. |
||
268 | * |
||
269 | * With checkDigit, UUID can be verified by re-compute check digits. |
||
270 | */ |
||
271 | public function verify($uuid) |
||
272 | { |
||
273 | // Length check |
||
274 | if (static::LENGTH != strlen($uuid)) { |
||
275 | return false; |
||
276 | } |
||
277 | |||
278 | // Check digit |
||
279 | if (0 != static::LENGTH_CHECK_DIGIT && |
||
280 | $uuid != $this->addCheckDigit($uuid) |
||
281 | ) { |
||
282 | return false; |
||
283 | } |
||
284 | |||
285 | return true; |
||
286 | } |
||
287 | } |
||
288 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.