Skip to content

Commit 54a1653

Browse files
Merge branch '6.0' into 6.1
* 6.0: [Form] fix UUID tranformer [Uid] Ensure ULIDs are monotonic even when the time goes backward [HttpClient] fix merge [HttpClient] fix merge
2 parents b0daf10 + 2944d64 commit 54a1653

File tree

5 files changed

+32
-48
lines changed

5 files changed

+32
-48
lines changed

src/Symfony/Component/Form/Extension/Core/DataTransformer/UuidToStringTransformer.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ public function reverseTransform(mixed $value): ?Uuid
6060
throw new TransformationFailedException('Expected a string.');
6161
}
6262

63+
if (!Uuid::isValid($value)) {
64+
throw new TransformationFailedException(sprintf('The value "%s" is not a valid UUID.', $value));
65+
}
66+
6367
try {
64-
$uuid = new Uuid($value);
68+
return Uuid::fromString($value);
6569
} catch (\InvalidArgumentException $e) {
6670
throw new TransformationFailedException(sprintf('The value "%s" is not a valid UUID.', $value), $e->getCode(), $e);
6771
}
68-
69-
return $uuid;
7072
}
7173
}

src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/UuidToStringTransformerTest.php

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,15 @@
1515
use Symfony\Component\Form\Exception\TransformationFailedException;
1616
use Symfony\Component\Form\Extension\Core\DataTransformer\UuidToStringTransformer;
1717
use Symfony\Component\Uid\Uuid;
18+
use Symfony\Component\Uid\UuidV1;
1819

1920
class UuidToStringTransformerTest extends TestCase
2021
{
21-
public function provideValidUuid()
22-
{
23-
return [
24-
['123e4567-e89b-12d3-a456-426655440000', new Uuid('123e4567-e89b-12d3-a456-426655440000')],
25-
];
26-
}
27-
28-
/**
29-
* @dataProvider provideValidUuid
30-
*/
31-
public function testTransform($output, $input)
22+
public function testTransform()
3223
{
3324
$transformer = new UuidToStringTransformer();
3425

35-
$input = new Uuid($input);
36-
37-
$this->assertEquals($output, $transformer->transform($input));
26+
$this->assertEquals('123e4567-e89b-12d3-a456-426655440000', $transformer->transform(new UuidV1('123e4567-e89b-12d3-a456-426655440000')));
3827
}
3928

4029
public function testTransformEmpty()
@@ -53,16 +42,11 @@ public function testTransformExpectsUuid()
5342
$transformer->transform('1234');
5443
}
5544

56-
/**
57-
* @dataProvider provideValidUuid
58-
*/
59-
public function testReverseTransform($input, $output)
45+
public function testReverseTransform()
6046
{
61-
$reverseTransformer = new UuidToStringTransformer();
62-
63-
$output = new Uuid($output);
47+
$transformer = new UuidToStringTransformer();
6448

65-
$this->assertEquals($output, $reverseTransformer->reverseTransform($input));
49+
$this->assertEquals(new UuidV1('123e4567-e89b-12d3-a456-426655440000'), $transformer->reverseTransform('123e4567-e89b-12d3-a456-426655440000'));
6650
}
6751

6852
public function testReverseTransformEmpty()
@@ -78,7 +62,7 @@ public function testReverseTransformExpectsString()
7862

7963
$this->expectException(TransformationFailedException::class);
8064

81-
$reverseTransformer->reverseTransform(1234);
65+
$reverseTransformer->reverseTransform(Uuid::fromString('123e4567-e89b-12d3-a456-426655440000')->toBase32());
8266
}
8367

8468
public function testReverseTransformExpectsValidUuidString()

src/Symfony/Component/HttpClient/Tests/RetryableHttpClientTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,14 @@ public function testRetryWithDelay()
207207
new GenericRetryStrategy(),
208208
1,
209209
$logger = new class() extends TestLogger {
210-
public array $context = [];
210+
public $context = [];
211211

212212
public function log($level, $message, array $context = []): void
213213
{
214214
$this->context = $context;
215215
parent::log($level, $message, $context);
216216
}
217-
},
217+
}
218218
);
219219

220220
$client->request('GET', 'http://example.com/foo-bar')->getContent();

src/Symfony/Component/Uid/Tests/UlidTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ public function testGenerate()
2626
{
2727
$a = new Ulid();
2828
$b = new Ulid();
29+
usleep(-10000);
30+
$c = new Ulid();
2931

3032
$this->assertSame(0, strncmp($a, $b, 20));
33+
$this->assertSame(0, strncmp($a, $c, 20));
3134
$a = base_convert(strtr(substr($a, -6), 'ABCDEFGHJKMNPQRSTVWXYZ', 'abcdefghijklmnopqrstuv'), 32, 10);
3235
$b = base_convert(strtr(substr($b, -6), 'ABCDEFGHJKMNPQRSTVWXYZ', 'abcdefghijklmnopqrstuv'), 32, 10);
36+
$c = base_convert(strtr(substr($c, -6), 'ABCDEFGHJKMNPQRSTVWXYZ', 'abcdefghijklmnopqrstuv'), 32, 10);
3337
$this->assertSame(1, $b - $a);
38+
$this->assertSame(1, $c - $b);
3439
}
3540

3641
public function testWithInvalidUlid()

src/Symfony/Component/Uid/Ulid.php

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,33 +137,23 @@ public function getDateTime(): \DateTimeImmutable
137137
}
138138

139139
if (4 > \strlen($time)) {
140-
$time = str_pad($time, 4, '0', \STR_PAD_LEFT);
140+
$time = '000'.$time;
141141
}
142142

143143
return \DateTimeImmutable::createFromFormat('U.u', substr_replace($time, '.', -3, 0));
144144
}
145145

146146
public static function generate(\DateTimeInterface $time = null): string
147147
{
148-
if (null === $time) {
149-
return self::doGenerate();
150-
}
151-
152-
if (0 > $time = substr($time->format('Uu'), 0, -3)) {
153-
throw new \InvalidArgumentException('The timestamp must be positive.');
154-
}
155-
156-
return self::doGenerate($time);
157-
}
158-
159-
private static function doGenerate(string $mtime = null): string
160-
{
161-
if (null === $time = $mtime) {
148+
if (null === $mtime = $time) {
162149
$time = microtime(false);
163150
$time = substr($time, 11).substr($time, 2, 3);
151+
} elseif (0 > $time = $time->format('Uv')) {
152+
throw new \InvalidArgumentException('The timestamp must be positive.');
164153
}
165154

166-
if ($time !== self::$time) {
155+
if ($time > self::$time || (null !== $mtime && $time !== self::$time)) {
156+
randomize:
167157
$r = unpack('nr1/nr2/nr3/nr4/nr', random_bytes(10));
168158
$r['r1'] |= ($r['r'] <<= 4) & 0xF0000;
169159
$r['r2'] |= ($r['r'] <<= 4) & 0xF0000;
@@ -173,19 +163,22 @@ private static function doGenerate(string $mtime = null): string
173163
self::$rand = array_values($r);
174164
self::$time = $time;
175165
} elseif ([0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF] === self::$rand) {
176-
if (null === $mtime) {
177-
usleep(100);
166+
if (\PHP_INT_SIZE >= 8 || 10 > \strlen($time = self::$time)) {
167+
$time = (string) (1 + $time);
168+
} elseif ('999999999' === $mtime = substr($time, -9)) {
169+
$time = (1 + substr($time, 0, -9)).'000000000';
178170
} else {
179-
self::$rand = [0, 0, 0, 0];
171+
$time = substr_replace($time, str_pad(++$mtime, 9, '0', \STR_PAD_LEFT), -9);
180172
}
181173

182-
return self::doGenerate($mtime);
174+
goto randomize;
183175
} else {
184176
for ($i = 3; $i >= 0 && 0xFFFFF === self::$rand[$i]; --$i) {
185177
self::$rand[$i] = 0;
186178
}
187179

188180
++self::$rand[$i];
181+
$time = self::$time;
189182
}
190183

191184
if (\PHP_INT_SIZE >= 8) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy