PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / lib / packages / Ramsey / Uuid / UuidFactory.php

UuidFactory.php in Defender Security – Malware Scanner, Login Security & Firewall 6.3.0, at lib/packages/Ramsey/Uuid/UuidFactory.php

477 lines 15.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the ramsey/uuid library
5 *
6 * For the full copyright and license information, please view the LICENSE
7 * file that was distributed with this source code.
8 *
9 * @copyright Copyright (c) Ben Ramsey <[email protected]>
10 * @license http://opensource.org/licenses/MIT MIT
11 */
12
13 declare(strict_types=1);
14
15 namespace WP_DEFENDER_VENDOR\Ramsey\Uuid;
16
17 use DateTimeInterface;
18 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Builder\UuidBuilderInterface;
19 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Codec\CodecInterface;
20 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Converter\NumberConverterInterface;
21 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Converter\TimeConverterInterface;
22 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Generator\DceSecurityGeneratorInterface;
23 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Generator\DefaultTimeGenerator;
24 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Generator\NameGeneratorInterface;
25 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Generator\RandomGeneratorInterface;
26 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Generator\TimeGeneratorInterface;
27 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Generator\UnixTimeGenerator;
28 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Lazy\LazyUuidFromString;
29 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Provider\NodeProviderInterface;
30 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Provider\Time\FixedTimeProvider;
31 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Type\Hexadecimal;
32 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Type\Integer as IntegerObject;
33 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Type\Time;
34 use WP_DEFENDER_VENDOR\Ramsey\Uuid\Validator\ValidatorInterface;
35
36 use function bin2hex;
37 use function hex2bin;
38 use function pack;
39 use function str_pad;
40 use function strtolower;
41 use function substr;
42 use function substr_replace;
43 use function unpack;
44
45 use const STR_PAD_LEFT;
46
47 class UuidFactory implements UuidFactoryInterface
48 {
49 private CodecInterface $codec;
50 private DceSecurityGeneratorInterface $dceSecurityGenerator;
51 private NameGeneratorInterface $nameGenerator;
52 private NodeProviderInterface $nodeProvider;
53 private NumberConverterInterface $numberConverter;
54 private RandomGeneratorInterface $randomGenerator;
55 private TimeConverterInterface $timeConverter;
56 private TimeGeneratorInterface $timeGenerator;
57 private TimeGeneratorInterface $unixTimeGenerator;
58 private UuidBuilderInterface $uuidBuilder;
59 private ValidatorInterface $validator;
60
61 /**
62 * @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions
63 */
64 private bool $isDefaultFeatureSet;
65
66 /**
67 * @param FeatureSet | null $features A set of available features in the current environment
68 */
69 public function __construct(?FeatureSet $features = null)
70 {
71 $this->isDefaultFeatureSet = $features === null;
72
73 $features = $features ?: new FeatureSet();
74
75 $this->codec = $features->getCodec();
76 $this->dceSecurityGenerator = $features->getDceSecurityGenerator();
77 $this->nameGenerator = $features->getNameGenerator();
78 $this->nodeProvider = $features->getNodeProvider();
79 $this->numberConverter = $features->getNumberConverter();
80 $this->randomGenerator = $features->getRandomGenerator();
81 $this->timeConverter = $features->getTimeConverter();
82 $this->timeGenerator = $features->getTimeGenerator();
83 $this->uuidBuilder = $features->getBuilder();
84 $this->validator = $features->getValidator();
85 $this->unixTimeGenerator = $features->getUnixTimeGenerator();
86 }
87
88 /**
89 * Returns the codec used by this factory
90 */
91 public function getCodec(): CodecInterface
92 {
93 return $this->codec;
94 }
95
96 /**
97 * Sets the codec to use for this factory
98 *
99 * @param CodecInterface $codec A UUID encoder-decoder
100 */
101 public function setCodec(CodecInterface $codec): void
102 {
103 $this->isDefaultFeatureSet = false;
104
105 $this->codec = $codec;
106 }
107
108 /**
109 * Returns the name generator used by this factory
110 */
111 public function getNameGenerator(): NameGeneratorInterface
112 {
113 return $this->nameGenerator;
114 }
115
116 /**
117 * Sets the name generator to use for this factory
118 *
119 * @param NameGeneratorInterface $nameGenerator A generator to generate binary data, based on a namespace and name
120 */
121 public function setNameGenerator(NameGeneratorInterface $nameGenerator): void
122 {
123 $this->isDefaultFeatureSet = false;
124
125 $this->nameGenerator = $nameGenerator;
126 }
127
128 /**
129 * Returns the node provider used by this factory
130 */
131 public function getNodeProvider(): NodeProviderInterface
132 {
133 return $this->nodeProvider;
134 }
135
136 /**
137 * Returns the random generator used by this factory
138 */
139 public function getRandomGenerator(): RandomGeneratorInterface
140 {
141 return $this->randomGenerator;
142 }
143
144 /**
145 * Returns the time generator used by this factory
146 */
147 public function getTimeGenerator(): TimeGeneratorInterface
148 {
149 return $this->timeGenerator;
150 }
151
152 /**
153 * Sets the time generator to use for this factory
154 *
155 * @param TimeGeneratorInterface $generator A generator to generate binary data, based on the time
156 */
157 public function setTimeGenerator(TimeGeneratorInterface $generator): void
158 {
159 $this->isDefaultFeatureSet = false;
160
161 $this->timeGenerator = $generator;
162 }
163
164 /**
165 * Returns the DCE Security generator used by this factory
166 */
167 public function getDceSecurityGenerator(): DceSecurityGeneratorInterface
168 {
169 return $this->dceSecurityGenerator;
170 }
171
172 /**
173 * Sets the DCE Security generator to use for this factory
174 *
175 * @param DceSecurityGeneratorInterface $generator A generator to generate binary data, based on a local domain and
176 * local identifier
177 */
178 public function setDceSecurityGenerator(DceSecurityGeneratorInterface $generator): void
179 {
180 $this->isDefaultFeatureSet = false;
181
182 $this->dceSecurityGenerator = $generator;
183 }
184
185 /**
186 * Returns the number converter used by this factory
187 */
188 public function getNumberConverter(): NumberConverterInterface
189 {
190 return $this->numberConverter;
191 }
192
193 /**
194 * Sets the random generator to use for this factory
195 *
196 * @param RandomGeneratorInterface $generator A generator to generate binary data, based on some random input
197 */
198 public function setRandomGenerator(RandomGeneratorInterface $generator): void
199 {
200 $this->isDefaultFeatureSet = false;
201
202 $this->randomGenerator = $generator;
203 }
204
205 /**
206 * Sets the number converter to use for this factory
207 *
208 * @param NumberConverterInterface $converter A converter to use for working with large integers (i.e., integers
209 * greater than PHP_INT_MAX)
210 */
211 public function setNumberConverter(NumberConverterInterface $converter): void
212 {
213 $this->isDefaultFeatureSet = false;
214
215 $this->numberConverter = $converter;
216 }
217
218 /**
219 * Returns the UUID builder used by this factory
220 */
221 public function getUuidBuilder(): UuidBuilderInterface
222 {
223 return $this->uuidBuilder;
224 }
225
226 /**
227 * Sets the UUID builder to use for this factory
228 *
229 * @param UuidBuilderInterface $builder A builder for constructing instances of UuidInterface
230 */
231 public function setUuidBuilder(UuidBuilderInterface $builder): void
232 {
233 $this->isDefaultFeatureSet = false;
234
235 $this->uuidBuilder = $builder;
236 }
237
238 public function getValidator(): ValidatorInterface
239 {
240 return $this->validator;
241 }
242
243 /**
244 * Sets the validator to use for this factory
245 *
246 * @param ValidatorInterface $validator A validator to use for validating whether a string is a valid UUID
247 */
248 public function setValidator(ValidatorInterface $validator): void
249 {
250 $this->isDefaultFeatureSet = false;
251
252 $this->validator = $validator;
253 }
254
255 /**
256 * @pure
257 */
258 public function fromBytes(string $bytes): UuidInterface
259 {
260 return $this->codec->decodeBytes($bytes);
261 }
262
263 /**
264 * @pure
265 */
266 public function fromString(string $uuid): UuidInterface
267 {
268 $uuid = strtolower($uuid);
269
270 return $this->codec->decode($uuid);
271 }
272
273 /**
274 * @pure
275 */
276 public function fromInteger(string $integer): UuidInterface
277 {
278 $hex = $this->numberConverter->toHex($integer);
279 $hex = str_pad($hex, 32, '0', STR_PAD_LEFT);
280
281 return $this->fromString($hex);
282 }
283
284 public function fromDateTime(
285 DateTimeInterface $dateTime,
286 ?Hexadecimal $node = null,
287 ?int $clockSeq = null,
288 ): UuidInterface {
289 $timeProvider = new FixedTimeProvider(new Time($dateTime->format('U'), $dateTime->format('u')));
290 $timeGenerator = new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $timeProvider);
291 $bytes = $timeGenerator->generate($node?->toString(), $clockSeq);
292
293 return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME);
294 }
295
296 /**
297 * @pure
298 */
299 public function fromHexadecimal(Hexadecimal $hex): UuidInterface
300 {
301 return $this->codec->decode($hex->__toString());
302 }
303
304 /**
305 * @inheritDoc
306 */
307 public function uuid1($node = null, ?int $clockSeq = null): UuidInterface
308 {
309 $bytes = $this->timeGenerator->generate($node, $clockSeq);
310
311 return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME);
312 }
313
314 public function uuid2(
315 int $localDomain,
316 ?IntegerObject $localIdentifier = null,
317 ?Hexadecimal $node = null,
318 ?int $clockSeq = null,
319 ): UuidInterface {
320 $bytes = $this->dceSecurityGenerator->generate($localDomain, $localIdentifier, $node, $clockSeq);
321
322 return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_DCE_SECURITY);
323 }
324
325 /**
326 * @inheritDoc
327 * @pure
328 */
329 public function uuid3($ns, string $name): UuidInterface
330 {
331 return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_MD5, 'md5');
332 }
333
334 public function uuid4(): UuidInterface
335 {
336 $bytes = $this->randomGenerator->generate(16);
337
338 return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_RANDOM);
339 }
340
341 /**
342 * @inheritDoc
343 * @pure
344 */
345 public function uuid5($ns, string $name): UuidInterface
346 {
347 return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_SHA1, 'sha1');
348 }
349
350 public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface
351 {
352 $bytes = $this->timeGenerator->generate($node?->toString(), $clockSeq);
353
354 // Rearrange the bytes, according to the UUID version 6 specification.
355 $v6 = $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5]
356 . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3];
357 $v6 = bin2hex($v6);
358
359 // Drop the first four bits, while adding an empty four bits for the version field. This allows us to
360 // reconstruct the correct time from the bytes of this UUID.
361 $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3));
362 $v6Bytes .= substr($bytes, 8);
363
364 return $this->uuidFromBytesAndVersion($v6Bytes, Uuid::UUID_TYPE_REORDERED_TIME);
365 }
366
367 /**
368 * Returns a version 7 (Unix Epoch time) UUID
369 *
370 * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not
371 * provided, the UUID is generated using the current date/time.
372 *
373 * @return UuidInterface A UuidInterface instance that represents a version 7 UUID
374 */
375 public function uuid7(?DateTimeInterface $dateTime = null): UuidInterface
376 {
377 assert($this->unixTimeGenerator instanceof UnixTimeGenerator);
378 $bytes = $this->unixTimeGenerator->generate(null, null, $dateTime);
379
380 return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_UNIX_TIME);
381 }
382
383 /**
384 * Returns a version 8 (custom format) UUID
385 *
386 * The bytes provided may contain any value according to your application's needs. Be aware, however, that other
387 * applications may not understand the semantics of the value.
388 *
389 * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of
390 * information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64
391 * and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs.
392 *
393 * @return UuidInterface A UuidInterface instance that represents a version 8 UUID
394 *
395 * @pure
396 */
397 public function uuid8(string $bytes): UuidInterface
398 {
399 /** @phpstan-ignore possiblyImpure.methodCall */
400 return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_CUSTOM);
401 }
402
403 /**
404 * Returns a Uuid created from the provided byte string
405 *
406 * Uses the configured builder and codec and the provided byte string to construct a Uuid object.
407 *
408 * @param string $bytes The byte string from which to construct a UUID
409 *
410 * @return UuidInterface An instance of UuidInterface, created from the provided bytes
411 *
412 * @pure
413 */
414 public function uuid(string $bytes): UuidInterface
415 {
416 return $this->uuidBuilder->build($this->codec, $bytes);
417 }
418
419 /**
420 * Returns a version 3 or 5 namespaced Uuid
421 *
422 * @param UuidInterface | string $ns The namespace (must be a valid UUID)
423 * @param string $name The name to hash together with the namespace
424 * @param int $version The version of UUID to create (3 or 5)
425 * @param string $hashAlgorithm The hashing algorithm to use when hashing together the namespace and name
426 *
427 * @return UuidInterface An instance of UuidInterface, created by hashing together the provided namespace and name
428 *
429 * @pure
430 */
431 private function uuidFromNsAndName(
432 UuidInterface | string $ns,
433 string $name,
434 int $version,
435 string $hashAlgorithm,
436 ): UuidInterface {
437 if (!($ns instanceof UuidInterface)) {
438 $ns = $this->fromString($ns);
439 }
440
441 $bytes = $this->nameGenerator->generate($ns, $name, $hashAlgorithm);
442
443 /** @phpstan-ignore possiblyImpure.methodCall */
444 return $this->uuidFromBytesAndVersion(substr($bytes, 0, 16), $version);
445 }
446
447 /**
448 * Returns a Uuid created from the provided bytes and version
449 *
450 * @param string $bytes The byte string to convert to a UUID
451 * @param int $version The version to apply to the UUID
452 *
453 * @return UuidInterface An instance of UuidInterface, created from the byte string and version
454 */
455 private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInterface
456 {
457 /** @var int[] $unpackedTime */
458 $unpackedTime = unpack('n*', substr($bytes, 6, 2));
459 $timeHi = $unpackedTime[1];
460 $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version));
461
462 /** @var int[] $unpackedClockSeq */
463 $unpackedClockSeq = unpack('n*', substr($bytes, 8, 2));
464 $clockSeqHi = $unpackedClockSeq[1];
465 $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi));
466
467 $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2);
468 $bytes = substr_replace($bytes, $clockSeqHiAndReserved, 8, 2);
469
470 if ($this->isDefaultFeatureSet) {
471 return LazyUuidFromString::fromBytes($bytes);
472 }
473
474 return $this->uuid($bytes);
475 }
476 }
477