Merge branch '4.4' into 5.1
* 4.4: Dont allow unserializing classes with a destructor Dont allow unserializing classes with a destructor - 4.4 [Cache] fix possible collision when writing tmp file in filesystem adapter a colon followed by spaces exclusively separates mapping keys and values Contracts: Remove ellipsis fix handling float-like key attribute values Fix missing BCC recipients in SES bridge
This commit is contained in:
commit
73a70acb2b
@ -129,6 +129,16 @@ class ElasticsearchLogstashHandler extends AbstractHandler
|
||||
$this->wait(false);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->wait(true);
|
||||
|
@ -89,6 +89,12 @@ class AppKernel extends Kernel implements ExtensionInterface, ConfigurationInter
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
foreach ($this as $k => $v) {
|
||||
if (\is_object($v)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
}
|
||||
|
||||
$this->__construct($this->varDir, $this->testCase, $this->rootConfig, $this->environment, $this->debug);
|
||||
}
|
||||
|
||||
|
@ -93,9 +93,20 @@ trait FilesystemCommonTrait
|
||||
set_error_handler(__CLASS__.'::throwError');
|
||||
try {
|
||||
if (null === $this->tmp) {
|
||||
$this->tmp = $this->directory.uniqid('', true);
|
||||
$this->tmp = $this->directory.bin2hex(random_bytes(6));
|
||||
}
|
||||
file_put_contents($this->tmp, $data);
|
||||
try {
|
||||
$h = fopen($this->tmp, 'x');
|
||||
} catch (\ErrorException $e) {
|
||||
if (false === strpos($e->getMessage(), 'File exists')) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->tmp = $this->directory.bin2hex(random_bytes(6));
|
||||
$h = fopen($this->tmp, 'x');
|
||||
}
|
||||
fwrite($h, $data);
|
||||
fclose($h);
|
||||
|
||||
if (null !== $expiresAt) {
|
||||
touch($this->tmp, $expiresAt);
|
||||
|
@ -227,6 +227,10 @@ class PrototypedArrayNode extends ArrayNode
|
||||
} elseif (isset($v[$this->keyAttribute])) {
|
||||
$k = $v[$this->keyAttribute];
|
||||
|
||||
if (\is_float($k)) {
|
||||
$k = var_export($k, true);
|
||||
}
|
||||
|
||||
// remove the key attribute when required
|
||||
if ($this->removeKeyAttribute) {
|
||||
unset($v[$this->keyAttribute]);
|
||||
|
@ -201,6 +201,32 @@ class NormalizationTest extends TestCase
|
||||
$this->assertNormalized($tree, $data, $data);
|
||||
}
|
||||
|
||||
public function testFloatLikeValueAsMapKeyAttribute()
|
||||
{
|
||||
$tree = (new TreeBuilder('root'))
|
||||
->getRootNode()
|
||||
->useAttributeAsKey('number')
|
||||
->arrayPrototype()
|
||||
->children()
|
||||
->scalarNode('foo')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->buildTree()
|
||||
;
|
||||
|
||||
$this->assertNormalized($tree, [
|
||||
[
|
||||
'number' => 3.0,
|
||||
'foo' => 'bar',
|
||||
],
|
||||
], [
|
||||
'3.0' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
|
||||
{
|
||||
self::assertSame($normalized, $tree->normalize($denormalized));
|
||||
|
@ -40,6 +40,16 @@ abstract class AbstractConfigurator
|
||||
throw new \BadMethodCallException(sprintf('Call to undefined method "%s::%s()".', static::class, $method));
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value.
|
||||
*
|
||||
|
@ -35,6 +35,16 @@ class BufferingLogger extends AbstractLogger
|
||||
return $logs;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->logs as [$level, $message, $context]) {
|
||||
|
@ -76,6 +76,16 @@ class OrderedHashMapIterator implements \Iterator
|
||||
$this->managedCursors[$this->cursorId] = &$this->cursor;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the iterator's cursors from the managed cursors of the
|
||||
* corresponding {@link OrderedHashMap} instance.
|
||||
|
@ -116,6 +116,16 @@ class ErrorChunk implements ChunkInterface
|
||||
return $this->didThrow;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (!$this->didThrow) {
|
||||
|
@ -362,6 +362,16 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
||||
}
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->reset();
|
||||
|
@ -218,6 +218,16 @@ final class HttplugClient implements HttplugInterface, HttpAsyncClient, RequestF
|
||||
throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__));
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->wait();
|
||||
|
@ -199,6 +199,16 @@ trait ResponseTrait
|
||||
return $stream;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the response and all its network handles.
|
||||
*/
|
||||
|
@ -179,7 +179,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
|
||||
$fileLinkFormat = array_pop($this->data);
|
||||
$this->dataCount = \count($this->data);
|
||||
|
||||
self::__construct($this->stopwatch, $fileLinkFormat, $charset);
|
||||
self::__construct($this->stopwatch, \is_string($fileLinkFormat) || $fileLinkFormat instanceof FileLinkFormatter ? $fileLinkFormat : null, \is_string($charset) ? $charset : null);
|
||||
}
|
||||
|
||||
public function getDumpsCount(): int
|
||||
|
@ -825,6 +825,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
if (\is_object($this->environment) || \is_object($this->debug)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
$this->__construct($this->environment, $this->debug);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,16 @@ class Connection extends AbstractConnection
|
||||
/** @var resource */
|
||||
private $connection;
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->disconnect();
|
||||
|
@ -38,6 +38,16 @@ class Query extends AbstractQuery
|
||||
parent::__construct($connection, $dn, $query, $options);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$con = $this->connection->getResource();
|
||||
|
@ -50,6 +50,16 @@ final class Lock implements LockInterface, LoggerAwareInterface
|
||||
$this->logger = new NullLogger();
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically releases the underlying lock when the object is destructed.
|
||||
*/
|
||||
|
@ -63,6 +63,12 @@ class SesHttpTransportTest extends TestCase
|
||||
$this->assertStringContainsString('AWS3-HTTPS AWSAccessKeyId=ACCESS_KEY,Algorithm=HmacSHA256,Signature=', $options['headers'][0] ?? $options['request_headers'][0]);
|
||||
|
||||
parse_str($options['body'], $body);
|
||||
|
||||
$this->assertArrayHasKey('Destinations_member_1', $body);
|
||||
$this->assertSame('saif.gmati@symfony.com', $body['Destinations_member_1']);
|
||||
$this->assertArrayHasKey('Destinations_member_2', $body);
|
||||
$this->assertSame('jeremy@derusse.com', $body['Destinations_member_2']);
|
||||
|
||||
$content = base64_decode($body['RawMessage_Data']);
|
||||
|
||||
$this->assertStringContainsString('Hello!', $content);
|
||||
@ -86,6 +92,7 @@ class SesHttpTransportTest extends TestCase
|
||||
$mail = new Email();
|
||||
$mail->subject('Hello!')
|
||||
->to(new Address('saif.gmati@symfony.com', 'Saif Eddin'))
|
||||
->bcc(new Address('jeremy@derusse.com', 'Jérémy Derussé'))
|
||||
->from(new Address('fabpot@symfony.com', 'Fabien'))
|
||||
->text('Hello There!');
|
||||
|
||||
|
@ -54,7 +54,7 @@ class SesHttpTransport extends AbstractHttpTransport
|
||||
$date = gmdate('D, d M Y H:i:s e');
|
||||
$auth = sprintf('AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s', $this->accessKey, $this->getSignature($date));
|
||||
|
||||
$response = $this->client->request('POST', 'https://'.$this->getEndpoint(), [
|
||||
$request = [
|
||||
'headers' => [
|
||||
'X-Amzn-Authorization' => $auth,
|
||||
'Date' => $date,
|
||||
@ -63,7 +63,13 @@ class SesHttpTransport extends AbstractHttpTransport
|
||||
'Action' => 'SendRawEmail',
|
||||
'RawMessage.Data' => base64_encode($message->toString()),
|
||||
],
|
||||
]);
|
||||
];
|
||||
$index = 1;
|
||||
foreach ($message->getEnvelope()->getRecipients() as $recipient) {
|
||||
$request['body']['Destinations.member.'.$index++] = $recipient->getAddress();
|
||||
}
|
||||
|
||||
$response = $this->client->request('POST', 'https://'.$this->getEndpoint(), $request);
|
||||
|
||||
$result = new \SimpleXMLElement($response->getContent(false));
|
||||
if (200 !== $response->getStatusCode()) {
|
||||
|
@ -340,6 +340,16 @@ class SmtpTransport extends AbstractTransport
|
||||
$this->restartCounter = 0;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->stop();
|
||||
|
@ -155,7 +155,13 @@ class DataPart extends TextPart
|
||||
$r->setValue($this, $this->_headers);
|
||||
unset($this->_headers);
|
||||
|
||||
if (!\is_array($this->_parent)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
|
||||
if (null !== $this->_parent[$name] && !\is_string($this->_parent[$name])) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
$r = new \ReflectionProperty(TextPart::class, $name);
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, $this->_parent[$name]);
|
||||
|
@ -35,6 +35,16 @@ class UnixPipes extends AbstractPipes
|
||||
parent::__construct($input);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
|
@ -88,6 +88,16 @@ class WindowsPipes extends AbstractPipes
|
||||
parent::__construct($input);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
|
@ -194,6 +194,16 @@ class Process implements \IteratorAggregate
|
||||
return $process;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->stop(0);
|
||||
|
@ -38,6 +38,16 @@ class CollectionConfigurator
|
||||
$this->parentPrefixes = $parentPrefixes;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (null === $this->prefixes) {
|
||||
|
@ -30,6 +30,16 @@ class ImportConfigurator
|
||||
$this->route = $route;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->parent->addCollection($this->route);
|
||||
|
@ -203,7 +203,7 @@ class Parser
|
||||
array_pop($this->refsBeingParsed);
|
||||
}
|
||||
} elseif (
|
||||
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
|
||||
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:( ++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
|
||||
&& (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"]))
|
||||
) {
|
||||
if ($context && 'sequence' == $context) {
|
||||
|
@ -915,4 +915,21 @@ class InlineTest extends TestCase
|
||||
[['!'], '! ["!"]'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ideographicSpaceProvider
|
||||
*/
|
||||
public function testParseIdeographicSpace(string $yaml, string $expected)
|
||||
{
|
||||
$this->assertSame($expected, Inline::parse($yaml));
|
||||
}
|
||||
|
||||
public function ideographicSpaceProvider(): array
|
||||
{
|
||||
return [
|
||||
["\u{3000}", ' '],
|
||||
["'\u{3000}'", ' '],
|
||||
["'a b'", 'a b'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -2732,6 +2732,22 @@ YAML;
|
||||
// (before, there was no \n after row2)
|
||||
$this->assertSame(['a' => ['b' => "row\nrow2\n"], 'c' => 'd'], $this->parser->parse($longDocument));
|
||||
}
|
||||
|
||||
public function testParseIdeographicSpaces()
|
||||
{
|
||||
$expected = <<<YAML
|
||||
unquoted: \u{3000}
|
||||
quoted: '\u{3000}'
|
||||
within_string: 'a b'
|
||||
regular_space: 'a b'
|
||||
YAML;
|
||||
$this->assertSame([
|
||||
'unquoted' => ' ',
|
||||
'quoted' => ' ',
|
||||
'within_string' => 'a b',
|
||||
'regular_space' => 'a b',
|
||||
], $this->parser->parse($expected));
|
||||
}
|
||||
}
|
||||
|
||||
class B
|
||||
|
@ -11,7 +11,7 @@ Design Principles
|
||||
|
||||
* contracts are split by domain, each into their own sub-namespaces;
|
||||
* contracts are small and consistent sets of PHP interfaces, traits, normative
|
||||
docblocks and reference test suites when applicable, ...;
|
||||
docblocks and reference test suites when applicable;
|
||||
* all contracts must have a proven implementation to enter this repository;
|
||||
* they must be backward compatible with existing Symfony components.
|
||||
|
||||
|
Reference in New Issue
Block a user