Merge branch '4.3' into 4.4
* 4.3: [Security/Core] align defaults for sodium with PHP 7.4 fix inline handling when dumping tagged values [HttpClient] fix canceling responses in a streaming loop [Messenger] Flatten collection of stamps collected by the traceable middleware [PropertyAccess] Fix PropertyAccessorCollectionTest [HttpClient] rewind stream when using Psr18Client Typo in web profiler [4.3] Remove dead test fixtures [Routing] Fix CHANGELOG relax some date parser patterns Avoid getting right to left style
This commit is contained in:
commit
5db58f6d37
@ -663,7 +663,7 @@
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="empty">
|
||||
<p>No options where passed when constructing this form.</p>
|
||||
<p>No options were passed when constructing this form.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -54,6 +54,7 @@
|
||||
text-align: left;
|
||||
text-transform: none;
|
||||
z-index: 99999;
|
||||
direction: ltr;
|
||||
|
||||
/* neutralize the aliasing defined by external CSS styles */
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
@ -78,9 +78,15 @@ final class Psr18Client implements ClientInterface, RequestFactoryInterface, Str
|
||||
public function sendRequest(RequestInterface $request): ResponseInterface
|
||||
{
|
||||
try {
|
||||
$body = $request->getBody();
|
||||
|
||||
if ($body->isSeekable()) {
|
||||
$body->seek(0);
|
||||
}
|
||||
|
||||
$response = $this->client->request($request->getMethod(), (string) $request->getUri(), [
|
||||
'headers' => $request->getHeaders(),
|
||||
'body' => (string) $request->getBody(),
|
||||
'body' => $body->getContents(),
|
||||
'http_version' => '1.0' === $request->getProtocolVersion() ? '1.0' : null,
|
||||
]);
|
||||
|
||||
@ -93,8 +99,13 @@ final class Psr18Client implements ClientInterface, RequestFactoryInterface, Str
|
||||
}
|
||||
|
||||
$body = isset(class_uses($response)[ResponseTrait::class]) ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client);
|
||||
$body = $this->streamFactory->createStreamFromResource($body);
|
||||
|
||||
return $psrResponse->withBody($this->streamFactory->createStreamFromResource($body));
|
||||
if ($body->isSeekable()) {
|
||||
$body->seek(0);
|
||||
}
|
||||
|
||||
return $psrResponse->withBody($body);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
if ($e instanceof \InvalidArgumentException) {
|
||||
throw new Psr18RequestException($e, $request);
|
||||
|
@ -78,6 +78,15 @@ class MockResponse implements ResponseInterface
|
||||
return null !== $type ? $this->info[$type] ?? null : $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function cancel(): void
|
||||
{
|
||||
$this->info['error'] = 'Response has been canceled.';
|
||||
$this->body = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -150,8 +159,11 @@ class MockResponse implements ResponseInterface
|
||||
foreach ($responses as $response) {
|
||||
$id = $response->id;
|
||||
|
||||
if (!$response->body) {
|
||||
// Last chunk
|
||||
if (null === $response->body) {
|
||||
// Canceled response
|
||||
$response->body = [];
|
||||
} elseif ([] === $response->body) {
|
||||
// Error chunk
|
||||
$multi->handlesActivity[$id][] = null;
|
||||
$multi->handlesActivity[$id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null;
|
||||
} elseif (null === $chunk = array_shift($response->body)) {
|
||||
@ -242,7 +254,7 @@ class MockResponse implements ResponseInterface
|
||||
|
||||
// populate info related to headers
|
||||
$info = $mock->getInfo() ?: [];
|
||||
$response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode(false) ?: 200;
|
||||
$response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode() ?: 200;
|
||||
$response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers);
|
||||
$dlSize = isset($response->headers['content-encoding']) ? 0 : (int) ($response->headers['content-length'][0] ?? 0);
|
||||
|
||||
|
@ -349,7 +349,7 @@ trait ResponseTrait
|
||||
|
||||
unset($multi->handlesActivity[$j]);
|
||||
|
||||
if ($chunk instanceof FirstChunk && null === $response->initializer) {
|
||||
if ($chunk instanceof FirstChunk && null === $response->initializer && null === $response->info['error']) {
|
||||
// Ensure the HTTP status code is always checked
|
||||
$response->getHeaders(true);
|
||||
} elseif ($chunk instanceof ErrorChunk && !$chunk->didThrow()) {
|
||||
|
@ -33,7 +33,7 @@ class DayTransformer extends Transformer
|
||||
*/
|
||||
public function getReverseMatchingRegExp(int $length): string
|
||||
{
|
||||
return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}';
|
||||
return 1 === $length ? '\d{1,2}' : '\d{1,'.$length.'}';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,7 +104,7 @@ class MonthTransformer extends Transformer
|
||||
$regExp = '[JFMASOND]';
|
||||
break;
|
||||
default:
|
||||
$regExp = '\d{'.$length.'}';
|
||||
$regExp = '\d{1,'.$length.'}';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ class YearTransformer extends Transformer
|
||||
*/
|
||||
public function getReverseMatchingRegExp(int $length): string
|
||||
{
|
||||
return 2 === $length ? '\d{2}' : '\d{4}';
|
||||
return 2 === $length ? '\d{2}' : '\d{1,4}';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -600,6 +600,7 @@ abstract class AbstractIntlDateFormatterTest extends TestCase
|
||||
{
|
||||
return [
|
||||
['y-M-d', '1970-1-1', 0],
|
||||
['y-MM-d', '1970-1-1', 0],
|
||||
['y-MMM-d', '1970-Jan-1', 0],
|
||||
['y-MMMM-d', '1970-January-1', 0],
|
||||
];
|
||||
@ -618,6 +619,7 @@ abstract class AbstractIntlDateFormatterTest extends TestCase
|
||||
{
|
||||
return [
|
||||
['y-M-d', '1970-1-1', 0],
|
||||
['y-M-dd', '1970-1-1', 0],
|
||||
['y-M-dd', '1970-1-01', 0],
|
||||
['y-M-ddd', '1970-1-001', 0],
|
||||
];
|
||||
|
@ -183,6 +183,17 @@ class IntlDateFormatterTest extends AbstractIntlDateFormatterTest
|
||||
return $this->notImplemented(parent::parseQuarterProvider());
|
||||
}
|
||||
|
||||
public function testParseThreeDigitsYears()
|
||||
{
|
||||
if (PHP_INT_SIZE < 8) {
|
||||
$this->markTestSkipped('Parsing three digits years requires a 64bit PHP.');
|
||||
}
|
||||
|
||||
$formatter = $this->getDefaultDateFormatter('yyyy-M-d');
|
||||
$this->assertSame(-32157648000, $formatter->parse('950-12-19'));
|
||||
$this->assertIsIntlSuccess($formatter, 'U_ZERO_ERROR', IntlGlobals::U_ZERO_ERROR);
|
||||
}
|
||||
|
||||
protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null)
|
||||
{
|
||||
return new IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern);
|
||||
|
@ -62,7 +62,7 @@ class TraceableMessageBusTest extends TestCase
|
||||
unset($actualTracedMessage['callTime']); // don't check, too variable
|
||||
$this->assertEquals([
|
||||
'message' => $message,
|
||||
'stamps' => [[$stamp]],
|
||||
'stamps' => [$stamp],
|
||||
'caller' => [
|
||||
'name' => 'TraceableMessageBusTest.php',
|
||||
'file' => __FILE__,
|
||||
|
@ -31,7 +31,7 @@ class TraceableMessageBus implements MessageBusInterface
|
||||
{
|
||||
$envelope = Envelope::wrap($message, $stamps);
|
||||
$context = [
|
||||
'stamps' => array_values($envelope->all()),
|
||||
'stamps' => array_merge([], ...array_values($envelope->all())),
|
||||
'message' => $envelope->getMessage(),
|
||||
'caller' => $this->getCaller(),
|
||||
'callTime' => microtime(true),
|
||||
|
@ -43,6 +43,28 @@ class PropertyAccessorCollectionTest_Car
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyAccessorCollectionTest_CarOnlyAdder
|
||||
{
|
||||
public function addAxis($axis)
|
||||
{
|
||||
}
|
||||
|
||||
public function getAxes()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyAccessorCollectionTest_CarOnlyRemover
|
||||
{
|
||||
public function removeAxis($axis)
|
||||
{
|
||||
}
|
||||
|
||||
public function getAxes()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyAccessorCollectionTest_CarNoAdderAndRemover
|
||||
{
|
||||
public function getAxes()
|
||||
@ -143,25 +165,25 @@ abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAcces
|
||||
|
||||
public function testIsWritableReturnsTrueIfAdderAndRemoverExists()
|
||||
{
|
||||
$car = $this->getMockBuilder(__CLASS__.'_Car')->getMock();
|
||||
$car = new PropertyAccessorCollectionTest_Car();
|
||||
$this->assertTrue($this->propertyAccessor->isWritable($car, 'axes'));
|
||||
}
|
||||
|
||||
public function testIsWritableReturnsFalseIfOnlyAdderExists()
|
||||
{
|
||||
$car = $this->getMockBuilder(__CLASS__.'_CarOnlyAdder')->getMock();
|
||||
$car = new PropertyAccessorCollectionTest_CarOnlyAdder();
|
||||
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
||||
}
|
||||
|
||||
public function testIsWritableReturnsFalseIfOnlyRemoverExists()
|
||||
{
|
||||
$car = $this->getMockBuilder(__CLASS__.'_CarOnlyRemover')->getMock();
|
||||
$car = new PropertyAccessorCollectionTest_CarOnlyRemover();
|
||||
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
||||
}
|
||||
|
||||
public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists()
|
||||
{
|
||||
$car = $this->getMockBuilder(__CLASS__.'_CarNoAdderAndRemover')->getMock();
|
||||
$car = new PropertyAccessorCollectionTest_CarNoAdderAndRemover();
|
||||
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
||||
}
|
||||
|
||||
@ -171,7 +193,7 @@ abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAcces
|
||||
*/
|
||||
public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable()
|
||||
{
|
||||
$car = $this->getMockBuilder(__CLASS__.'_Car')->getMock();
|
||||
$car = new PropertyAccessorCollectionTest_Car();
|
||||
|
||||
$this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable');
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ CHANGELOG
|
||||
Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible
|
||||
with the new serialization methods in PHP 7.4.
|
||||
* exposed `utf8` Route option, defaults "locale" and "format" in configuration loaders and configurators
|
||||
* added support for invokable route loader services
|
||||
* added support for invokable service route loaders
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
@ -30,7 +30,7 @@ final class NativePasswordEncoder implements PasswordEncoderInterface, SelfSalti
|
||||
public function __construct(int $opsLimit = null, int $memLimit = null, int $cost = null)
|
||||
{
|
||||
$cost = $cost ?? 13;
|
||||
$opsLimit = $opsLimit ?? max(6, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE : 6);
|
||||
$opsLimit = $opsLimit ?? max(4, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
|
||||
$memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024);
|
||||
|
||||
if (3 > $opsLimit) {
|
||||
|
@ -34,7 +34,7 @@ final class SodiumPasswordEncoder implements PasswordEncoderInterface, SelfSalti
|
||||
throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
|
||||
}
|
||||
|
||||
$this->opsLimit = $opsLimit ?? max(6, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE : 6);
|
||||
$this->opsLimit = $opsLimit ?? max(4, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
|
||||
$this->memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 2014);
|
||||
|
||||
if (3 > $this->opsLimit) {
|
||||
|
@ -380,7 +380,3 @@ class ArrayDenormalizerDummy implements DenormalizerInterface, SerializerAwareIn
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ObjectSerializerDenormalizer implements SerializerInterface, DenormalizerInterface
|
||||
{
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Yaml;
|
||||
|
||||
use Symfony\Component\Yaml\Tag\TaggedValue;
|
||||
|
||||
/**
|
||||
* Dumper dumps PHP variables to YAML strings.
|
||||
*
|
||||
@ -56,7 +58,7 @@ class Dumper
|
||||
$dumpObjectAsInlineMap = empty((array) $input);
|
||||
}
|
||||
|
||||
if ($inline <= 0 || (!\is_array($input) && $dumpObjectAsInlineMap) || empty($input)) {
|
||||
if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) {
|
||||
$output .= $prefix.Inline::dump($input, $flags);
|
||||
} else {
|
||||
$dumpAsMap = Inline::isHash($input);
|
||||
@ -75,6 +77,19 @@ class Dumper
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value instanceof TaggedValue) {
|
||||
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());
|
||||
|
||||
if ($inline - 1 <= 0) {
|
||||
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
|
||||
} else {
|
||||
$output .= "\n";
|
||||
$output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$dumpObjectAsInlineMap = true;
|
||||
|
||||
if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Yaml\Tests;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Yaml\Dumper;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use Symfony\Component\Yaml\Tag\TaggedValue;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class DumperTest extends TestCase
|
||||
@ -368,6 +369,94 @@ outer2:
|
||||
inner2: c
|
||||
inner3: { deep1: d, deep2: e }
|
||||
|
||||
YAML;
|
||||
$this->assertSame($expected, $yaml);
|
||||
}
|
||||
|
||||
public function testDumpingTaggedValueSequenceRespectsInlineLevel()
|
||||
{
|
||||
$data = [
|
||||
new TaggedValue('user', [
|
||||
'username' => 'jane',
|
||||
]),
|
||||
new TaggedValue('user', [
|
||||
'username' => 'john',
|
||||
]),
|
||||
];
|
||||
|
||||
$yaml = $this->dumper->dump($data, 2);
|
||||
|
||||
$expected = <<<YAML
|
||||
- !user
|
||||
username: jane
|
||||
- !user
|
||||
username: john
|
||||
|
||||
YAML;
|
||||
$this->assertSame($expected, $yaml);
|
||||
}
|
||||
|
||||
public function testDumpingTaggedValueSequenceWithInlinedTagValues()
|
||||
{
|
||||
$data = [
|
||||
new TaggedValue('user', [
|
||||
'username' => 'jane',
|
||||
]),
|
||||
new TaggedValue('user', [
|
||||
'username' => 'john',
|
||||
]),
|
||||
];
|
||||
|
||||
$yaml = $this->dumper->dump($data, 1);
|
||||
|
||||
$expected = <<<YAML
|
||||
- !user { username: jane }
|
||||
- !user { username: john }
|
||||
|
||||
YAML;
|
||||
$this->assertSame($expected, $yaml);
|
||||
}
|
||||
|
||||
public function testDumpingTaggedValueMapRespectsInlineLevel()
|
||||
{
|
||||
$data = [
|
||||
'user1' => new TaggedValue('user', [
|
||||
'username' => 'jane',
|
||||
]),
|
||||
'user2' => new TaggedValue('user', [
|
||||
'username' => 'john',
|
||||
]),
|
||||
];
|
||||
|
||||
$yaml = $this->dumper->dump($data, 2);
|
||||
|
||||
$expected = <<<YAML
|
||||
user1: !user
|
||||
username: jane
|
||||
user2: !user
|
||||
username: john
|
||||
|
||||
YAML;
|
||||
$this->assertSame($expected, $yaml);
|
||||
}
|
||||
|
||||
public function testDumpingTaggedValueMapWithInlinedTagValues()
|
||||
{
|
||||
$data = [
|
||||
'user1' => new TaggedValue('user', [
|
||||
'username' => 'jane',
|
||||
]),
|
||||
'user2' => new TaggedValue('user', [
|
||||
'username' => 'john',
|
||||
]),
|
||||
];
|
||||
|
||||
$yaml = $this->dumper->dump($data, 1);
|
||||
|
||||
$expected = <<<YAML
|
||||
user1: !user { username: jane }
|
||||
user2: !user { username: john }
|
||||
|
||||
YAML;
|
||||
$this->assertSame($expected, $yaml);
|
||||
}
|
||||
|
@ -505,6 +505,21 @@ abstract class HttpClientTestCase extends TestCase
|
||||
$response->getHeaders();
|
||||
}
|
||||
|
||||
public function testCancelInStream()
|
||||
{
|
||||
$client = $this->getHttpClient(__FUNCTION__);
|
||||
$response = $client->request('GET', 'http://localhost:8057/404');
|
||||
|
||||
foreach ($client->stream($response) as $chunk) {
|
||||
$response->cancel();
|
||||
}
|
||||
|
||||
$this->expectException(TransportExceptionInterface::class);
|
||||
|
||||
foreach ($client->stream($response) as $chunk) {
|
||||
}
|
||||
}
|
||||
|
||||
public function testOnProgressCancel()
|
||||
{
|
||||
$client = $this->getHttpClient(__FUNCTION__);
|
||||
|
Reference in New Issue
Block a user