Merge branch '4.4' into 5.1

* 4.4:
  Disable the PhpUnit bridge when testing it
  [PropertyInfo] Support for the mixed type.
  Don't unset the inflate resource on close as it might still be needed
  [HttpClient] Fix CurlHttpClient memory leak
  [Form] Add Bosnian (bs) validators translation
  [Form] Add missing Serbian (latn & cyrl) validators translation
  [Cache] skip igbinary < 3.1.6
  [Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3
  [Form] [Validator] added pt_BR translations
  Estonian update
  [PhpUnitBridge] fix running parallel tests with phpunit 9
  [VarDumper] fix truncating big arrays
This commit is contained in:
Nicolas Grekas 2020-10-12 13:21:05 +02:00
commit a1616a76eb
23 changed files with 700 additions and 50 deletions

View File

@ -225,7 +225,7 @@ install:
export SYMFONY_DEPRECATIONS_HELPER=weak &&
cp composer.json composer.json.orig &&
echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json &&
php .github/build-packages.php HEAD^ $(find src/Symfony -mindepth 3 -type f -name composer.json -printf '%h\n' | sort) &&
php .github/build-packages.php HEAD^ $(find src/Symfony -mindepth 2 -type f -name composer.json -printf '%h\n' | sort) &&
mv composer.json composer.json.phpunit &&
mv composer.json.orig composer.json
fi
@ -249,7 +249,7 @@ install:
- |
# Skip the phpunit-bridge on bugfix-only branches when $deps is empty
if [[ ! $deps && ! $TRAVIS_BRANCH = *.x ]]; then
export COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -printf '%h\n' | sort)
export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -printf '%h\n' | sort)
fi
- |

View File

@ -24,5 +24,8 @@ if (!getenv('SYMFONY_PHPUNIT_VERSION')) {
if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
putenv('SYMFONY_PATCH_TYPE_DECLARATIONS=deprecations=1');
}
if (getcwd() === realpath(__DIR__.'/src/Symfony/Bridge/PhpUnit')) {
putenv('SYMFONY_DEPRECATIONS_HELPER=disabled');
}
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
require __DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit';

View File

@ -265,11 +265,11 @@ if (!class_exists('SymfonyExcludeListPhpunit', false)) {
if (method_exists('PHPUnit\Util\ExcludeList', 'addDirectory')) {
(new PHPUnit\Util\Excludelist())->getExcludedDirectories();
PHPUnit\Util\ExcludeList::addDirectory(\dirname((new \ReflectionClass('SymfonyExcludeListPhpunit'))->getFileName()));
PHPUnit\Util\ExcludeList::addDirectory(\dirname((new \ReflectionClass('SymfonyExcludeListSimplePhpunit'))->getFileName()));
class_exists('SymfonyExcludeListSimplePhpunit', false) && PHPUnit\Util\ExcludeList::addDirectory(\dirname((new \ReflectionClass('SymfonyExcludeListSimplePhpunit'))->getFileName()));
} elseif (method_exists('PHPUnit\Util\Blacklist', 'addDirectory')) {
(new PHPUnit\Util\BlackList())->getBlacklistedDirectories();
PHPUnit\Util\Blacklist::addDirectory(\dirname((new \ReflectionClass('SymfonyExcludeListPhpunit'))->getFileName()));
PHPUnit\Util\Blacklist::addDirectory(\dirname((new \ReflectionClass('SymfonyExcludeListSimplePhpunit'))->getFileName()));
class_exists('SymfonyExcludeListSimplePhpunit', false) && PHPUnit\Util\Blacklist::addDirectory(\dirname((new \ReflectionClass('SymfonyExcludeListSimplePhpunit'))->getFileName()));
} else {
PHPUnit\Util\Blacklist::$blacklistedClassNames['SymfonyExcludeListPhpunit'] = 1;
PHPUnit\Util\Blacklist::$blacklistedClassNames['SymfonyExcludeListSimplePhpunit'] = 1;

View File

@ -25,9 +25,9 @@ class DefaultMarshaller implements MarshallerInterface
public function __construct(bool $useIgbinarySerialize = null)
{
if (null === $useIgbinarySerialize) {
$useIgbinarySerialize = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.0', phpversion('igbinary'), '<='));
} elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')))) {
throw new CacheException(\extension_loaded('igbinary') && \PHP_VERSION_ID >= 70400 ? 'Please upgrade the "igbinary" PHP extension to v3.1 or higher.' : 'The "igbinary" PHP extension is not loaded.');
$useIgbinarySerialize = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.6', phpversion('igbinary'), '<='));
} elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')))) {
throw new CacheException(\extension_loaded('igbinary') && \PHP_VERSION_ID >= 70400 ? 'Please upgrade the "igbinary" PHP extension to v3.1.6 or higher.' : 'The "igbinary" PHP extension is not loaded.');
}
$this->useIgbinarySerialize = $useIgbinarySerialize;
}
@ -66,7 +66,7 @@ class DefaultMarshaller implements MarshallerInterface
return null;
}
static $igbinaryNull;
if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.0', phpversion('igbinary'), '<=')) ? igbinary_serialize(null) : false)) {
if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') ? igbinary_serialize(null) : false)) {
return null;
}
$unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');

View File

@ -24,7 +24,7 @@ class DefaultMarshallerTest extends TestCase
'b' => function () {},
];
$expected = ['a' => \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.0', phpversion('igbinary'), '<=')) ? igbinary_serialize(123) : serialize(123)];
$expected = ['a' => \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.6', phpversion('igbinary'), '<=')) ? igbinary_serialize(123) : serialize(123)];
$this->assertSame($expected, $marshaller->marshall($values, $failed));
$this->assertSame(['b'], $failed);
}
@ -43,7 +43,7 @@ class DefaultMarshallerTest extends TestCase
*/
public function testIgbinaryUnserialize()
{
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')) {
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')) {
$this->markTestSkipped('igbinary is not compatible with PHP 7.4.');
}
@ -67,7 +67,7 @@ class DefaultMarshallerTest extends TestCase
*/
public function testIgbinaryUnserializeNotFoundClass()
{
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')) {
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')) {
$this->markTestSkipped('igbinary is not compatible with PHP 7.4.');
}
@ -95,7 +95,7 @@ class DefaultMarshallerTest extends TestCase
*/
public function testIgbinaryUnserializeInvalid()
{
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')) {
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')) {
$this->markTestSkipped('igbinary is not compatible with PHP 7.4.');
}

View File

@ -0,0 +1,119 @@
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="28">
<source>This form should not contain extra fields.</source>
<target>Ovaj obrazac ne bi trebalo da sadrži dodatna polja.</target>
</trans-unit>
<trans-unit id="29">
<source>The uploaded file was too large. Please try to upload a smaller file.</source>
<target>Prenijeta (uploaded) datoteka je prevelika. Molim pokušajte prenijeti manju datoteku.</target>
</trans-unit>
<trans-unit id="30">
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
<target>CSRF vrijednost nije ispravna. Molim pokušajte ponovo da pošaljete obrazac.</target>
</trans-unit>
<trans-unit id="99">
<source>This value is not a valid HTML5 color.</source>
<target>Ova vrijednost nije ispravna HTML5 boja.</target>
</trans-unit>
<trans-unit id="100">
<source>Please enter a valid birthdate.</source>
<target>Molim upišite ispravan datum rođenja.</target>
</trans-unit>
<trans-unit id="101">
<source>The selected choice is invalid.</source>
<target>Odabrani izbor nije ispravan.</target>
</trans-unit>
<trans-unit id="102">
<source>The collection is invalid.</source>
<target>Ova kolekcija nije ispravna.</target>
</trans-unit>
<trans-unit id="103">
<source>Please select a valid color.</source>
<target>Molim izaberite ispravnu boju.</target>
</trans-unit>
<trans-unit id="104">
<source>Please select a valid country.</source>
<target>Molim izaberite ispravnu državu.</target>
</trans-unit>
<trans-unit id="105">
<source>Please select a valid currency.</source>
<target>Molim izaberite ispravnu valutu.</target>
</trans-unit>
<trans-unit id="106">
<source>Please choose a valid date interval.</source>
<target>Molim izaberite ispravan datumski interval.</target>
</trans-unit>
<trans-unit id="107">
<source>Please enter a valid date and time.</source>
<target>Molim upišite ispravan datum i vrijeme.</target>
</trans-unit>
<trans-unit id="108">
<source>Please enter a valid date.</source>
<target>Molim upišite ispravan datum.</target>
</trans-unit>
<trans-unit id="109">
<source>Please select a valid file.</source>
<target>Molim izaberite ispravnu datoteku.</target>
</trans-unit>
<trans-unit id="110">
<source>The hidden field is invalid.</source>
<target>Skriveno polje nije ispravno.</target>
</trans-unit>
<trans-unit id="111">
<source>Please enter an integer.</source>
<target>Molim upišite cijeli broj (integer).</target>
</trans-unit>
<trans-unit id="112">
<source>Please select a valid language.</source>
<target>Molim izaberite ispravan jezik.</target>
</trans-unit>
<trans-unit id="113">
<source>Please select a valid locale.</source>
<target>Molim izaberite ispravnu lokalizaciju.</target>
</trans-unit>
<trans-unit id="114">
<source>Please enter a valid money amount.</source>
<target>Molim upišite ispravnu količinu novca.</target>
</trans-unit>
<trans-unit id="115">
<source>Please enter a number.</source>
<target>Molim upišite broj.</target>
</trans-unit>
<trans-unit id="116">
<source>The password is invalid.</source>
<target>Ova lozinka nije ispravna.</target>
</trans-unit>
<trans-unit id="117">
<source>Please enter a percentage value.</source>
<target>Molim upišite procentualnu vrijednost.</target>
</trans-unit>
<trans-unit id="118">
<source>The values do not match.</source>
<target>Date vrijednosti se ne poklapaju.</target>
</trans-unit>
<trans-unit id="119">
<source>Please enter a valid time.</source>
<target>Molim upišite ispravno vrijeme.</target>
</trans-unit>
<trans-unit id="120">
<source>Please select a valid timezone.</source>
<target>Molim izaberite ispravnu vremensku zonu.</target>
</trans-unit>
<trans-unit id="121">
<source>Please enter a valid URL.</source>
<target>Molim upišite ispravan URL.</target>
</trans-unit>
<trans-unit id="122">
<source>Please enter a valid search term.</source>
<target>Molim upišite ispravan termin za pretragu.</target>
</trans-unit>
<trans-unit id="123">
<source>Please provide a valid phone number.</source>
<target>Molim navedite ispravan broj telefona.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -14,6 +14,106 @@
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
<target>O token CSRF é inválido. Por favor, tente reenviar o formulário.</target>
</trans-unit>
<trans-unit id="99">
<source>This value is not a valid HTML5 color.</source>
<target>Este valor não é uma cor HTML5 válida.</target>
</trans-unit>
<trans-unit id="100">
<source>Please enter a valid birthdate.</source>
<target>Por favor, informe uma data de nascimento válida.</target>
</trans-unit>
<trans-unit id="101">
<source>The selected choice is invalid.</source>
<target>A escolha selecionada é inválida.</target>
</trans-unit>
<trans-unit id="102">
<source>The collection is invalid.</source>
<target>A coleção é inválida.</target>
</trans-unit>
<trans-unit id="103">
<source>Please select a valid color.</source>
<target>Por favor, selecione uma cor válida.</target>
</trans-unit>
<trans-unit id="104">
<source>Please select a valid country.</source>
<target>Por favor, selecione um país válido.</target>
</trans-unit>
<trans-unit id="105">
<source>Please select a valid currency.</source>
<target>Por favor, selecione uma moeda válida.</target>
</trans-unit>
<trans-unit id="106">
<source>Please choose a valid date interval.</source>
<target>Por favor, escolha um intervalo de datas válido.</target>
</trans-unit>
<trans-unit id="107">
<source>Please enter a valid date and time.</source>
<target>Por favor, informe uma data e horário válidos.</target>
</trans-unit>
<trans-unit id="108">
<source>Please enter a valid date.</source>
<target>Por favor, informe uma data válida.</target>
</trans-unit>
<trans-unit id="109">
<source>Please select a valid file.</source>
<target>Por favor, selecione um arquivo válido.</target>
</trans-unit>
<trans-unit id="110">
<source>The hidden field is invalid.</source>
<target>O campo oculto é inválido.</target>
</trans-unit>
<trans-unit id="111">
<source>Please enter an integer.</source>
<target>Por favor, informe um número inteiro.</target>
</trans-unit>
<trans-unit id="112">
<source>Please select a valid language.</source>
<target>Por favor, selecione um idioma válido.</target>
</trans-unit>
<trans-unit id="113">
<source>Please select a valid locale.</source>
<target>Por favor, selecione uma configuração de local válida.</target>
</trans-unit>
<trans-unit id="114">
<source>Please enter a valid money amount.</source>
<target>Por favor, informe um valor monetário válido.</target>
</trans-unit>
<trans-unit id="115">
<source>Please enter a number.</source>
<target>Por favor, informe um número.</target>
</trans-unit>
<trans-unit id="116">
<source>The password is invalid.</source>
<target>A senha é inválida.</target>
</trans-unit>
<trans-unit id="117">
<source>Please enter a percentage value.</source>
<target>Por favor, informe um valor percentual.</target>
</trans-unit>
<trans-unit id="118">
<source>The values do not match.</source>
<target>Os valores não conferem.</target>
</trans-unit>
<trans-unit id="119">
<source>Please enter a valid time.</source>
<target>Por favor, informe um horário válido.</target>
</trans-unit>
<trans-unit id="120">
<source>Please select a valid timezone.</source>
<target>Por favor, selecione um fuso horário válido.</target>
</trans-unit>
<trans-unit id="121">
<source>Please enter a valid URL.</source>
<target>Por favor, informe uma URL válida.</target>
</trans-unit>
<trans-unit id="122">
<source>Please enter a valid search term.</source>
<target>Por favor, informe um termo de busca válido.</target>
</trans-unit>
<trans-unit id="123">
<source>Please provide a valid phone number.</source>
<target>Por favor, informe um telefone válido.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -12,7 +12,107 @@
</trans-unit>
<trans-unit id="30">
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
<target>CSRF вредност је невалидна. Покушајте поново.</target>
<target>CSRF вредност није исправна. Покушајте поново.</target>
</trans-unit>
<trans-unit id="99">
<source>This value is not a valid HTML5 color.</source>
<target>Ова вредност није исправна HTML5 боја.</target>
</trans-unit>
<trans-unit id="100">
<source>Please enter a valid birthdate.</source>
<target>Молим упишите исправан датум рођења.</target>
</trans-unit>
<trans-unit id="101">
<source>The selected choice is invalid.</source>
<target>Одабрани избор није исправан.</target>
</trans-unit>
<trans-unit id="102">
<source>The collection is invalid.</source>
<target>Ова колекција није исправна.</target>
</trans-unit>
<trans-unit id="103">
<source>Please select a valid color.</source>
<target>Молим изаберите исправну боју.</target>
</trans-unit>
<trans-unit id="104">
<source>Please select a valid country.</source>
<target>Молим изаберите исправну државу.</target>
</trans-unit>
<trans-unit id="105">
<source>Please select a valid currency.</source>
<target>Молим изаберите исправну валуту.</target>
</trans-unit>
<trans-unit id="106">
<source>Please choose a valid date interval.</source>
<target>Молим изаберите исправан датумски интервал.</target>
</trans-unit>
<trans-unit id="107">
<source>Please enter a valid date and time.</source>
<target>Молим упишите исправан датум и време.</target>
</trans-unit>
<trans-unit id="108">
<source>Please enter a valid date.</source>
<target>Молим упишите исправан датум.</target>
</trans-unit>
<trans-unit id="109">
<source>Please select a valid file.</source>
<target>Молим изаберите исправну датотеку.</target>
</trans-unit>
<trans-unit id="110">
<source>The hidden field is invalid.</source>
<target>Скривено поље није исправно.</target>
</trans-unit>
<trans-unit id="111">
<source>Please enter an integer.</source>
<target>Молим упишите цео број (integer).</target>
</trans-unit>
<trans-unit id="112">
<source>Please select a valid language.</source>
<target>Молим изаберите исправан језик.</target>
</trans-unit>
<trans-unit id="113">
<source>Please select a valid locale.</source>
<target>Молим изаберите исправну локализацију.</target>
</trans-unit>
<trans-unit id="114">
<source>Please enter a valid money amount.</source>
<target>Молим упишите исправну количину новца.</target>
</trans-unit>
<trans-unit id="115">
<source>Please enter a number.</source>
<target>Молим упишите број.</target>
</trans-unit>
<trans-unit id="116">
<source>The password is invalid.</source>
<target>Ова лозинка није исправна.</target>
</trans-unit>
<trans-unit id="117">
<source>Please enter a percentage value.</source>
<target>Молим упишите процентуалну вредност.</target>
</trans-unit>
<trans-unit id="118">
<source>The values do not match.</source>
<target>Дате вредности се не поклапају.</target>
</trans-unit>
<trans-unit id="119">
<source>Please enter a valid time.</source>
<target>Молим упишите исправно време.</target>
</trans-unit>
<trans-unit id="120">
<source>Please select a valid timezone.</source>
<target>Молим изаберите исправну временску зону.</target>
</trans-unit>
<trans-unit id="121">
<source>Please enter a valid URL.</source>
<target>Молим упишите исправан URL.</target>
</trans-unit>
<trans-unit id="122">
<source>Please enter a valid search term.</source>
<target>Молим упишите исправан термин за претрагу.</target>
</trans-unit>
<trans-unit id="123">
<source>Please provide a valid phone number.</source>
<target>Молим наведите исправан број телефона.</target>
</trans-unit>
</body>
</file>

View File

@ -12,7 +12,107 @@
</trans-unit>
<trans-unit id="30">
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
<target>CSRF vrednost je nevalidna. Pokušajte ponovo.</target>
<target>CSRF vrednost nije ispravna. Pokušajte ponovo.</target>
</trans-unit>
<trans-unit id="99">
<source>This value is not a valid HTML5 color.</source>
<target>Ova vrednost nije ispravna HTML5 boja.</target>
</trans-unit>
<trans-unit id="100">
<source>Please enter a valid birthdate.</source>
<target>Molim upišite ispravan datum rođenja.</target>
</trans-unit>
<trans-unit id="101">
<source>The selected choice is invalid.</source>
<target>Odabrani izbor nije ispravan.</target>
</trans-unit>
<trans-unit id="102">
<source>The collection is invalid.</source>
<target>Ova kolekcija nije ispravna.</target>
</trans-unit>
<trans-unit id="103">
<source>Please select a valid color.</source>
<target>Molim izaberite ispravnu boju.</target>
</trans-unit>
<trans-unit id="104">
<source>Please select a valid country.</source>
<target>Molim izaberite ispravnu državu.</target>
</trans-unit>
<trans-unit id="105">
<source>Please select a valid currency.</source>
<target>Molim izaberite ispravnu valutu.</target>
</trans-unit>
<trans-unit id="106">
<source>Please choose a valid date interval.</source>
<target>Molim izaberite ispravan datumski interval.</target>
</trans-unit>
<trans-unit id="107">
<source>Please enter a valid date and time.</source>
<target>Molim upišite ispravan datum i vreme.</target>
</trans-unit>
<trans-unit id="108">
<source>Please enter a valid date.</source>
<target>Molim upišite ispravan datum.</target>
</trans-unit>
<trans-unit id="109">
<source>Please select a valid file.</source>
<target>Molim izaberite ispravnu datoteku.</target>
</trans-unit>
<trans-unit id="110">
<source>The hidden field is invalid.</source>
<target>Skriveno polje nije ispravno.</target>
</trans-unit>
<trans-unit id="111">
<source>Please enter an integer.</source>
<target>Molim upišite ceo broj (integer).</target>
</trans-unit>
<trans-unit id="112">
<source>Please select a valid language.</source>
<target>Molim izaberite ispravan jezik.</target>
</trans-unit>
<trans-unit id="113">
<source>Please select a valid locale.</source>
<target>Molim izaberite ispravnu lokalizaciju.</target>
</trans-unit>
<trans-unit id="114">
<source>Please enter a valid money amount.</source>
<target>Molim upišite ispravnu količinu novca.</target>
</trans-unit>
<trans-unit id="115">
<source>Please enter a number.</source>
<target>Molim upišite broj.</target>
</trans-unit>
<trans-unit id="116">
<source>The password is invalid.</source>
<target>Ova lozinka nije ispravna.</target>
</trans-unit>
<trans-unit id="117">
<source>Please enter a percentage value.</source>
<target>Molim upišite procentualnu vrednost.</target>
</trans-unit>
<trans-unit id="118">
<source>The values do not match.</source>
<target>Date vrednosti se ne poklapaju.</target>
</trans-unit>
<trans-unit id="119">
<source>Please enter a valid time.</source>
<target>Molim upišite ispravno vreme.</target>
</trans-unit>
<trans-unit id="120">
<source>Please select a valid timezone.</source>
<target>Molim izaberite ispravnu vremensku zonu.</target>
</trans-unit>
<trans-unit id="121">
<source>Please enter a valid URL.</source>
<target>Molim upišite ispravan URL.</target>
</trans-unit>
<trans-unit id="122">
<source>Please enter a valid search term.</source>
<target>Molim upišite ispravan termin za pretragu.</target>
</trans-unit>
<trans-unit id="123">
<source>Please provide a valid phone number.</source>
<target>Molim navedite ispravan broj telefona.</target>
</trans-unit>
</body>
</file>

View File

@ -17,7 +17,6 @@ use Symfony\Component\HttpClient\Chunk\InformationalChunk;
use Symfony\Component\HttpClient\Exception\TransportException;
use Symfony\Component\HttpClient\Internal\ClientState;
use Symfony\Component\HttpClient\Internal\CurlClientState;
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
/**
@ -205,14 +204,9 @@ final class CurlResponse implements ResponseInterface
return; // Unused pushed response
}
$e = null;
$this->doDestruct();
} catch (HttpExceptionInterface $e) {
throw $e;
} finally {
if ($e ?? false) {
throw $e;
}
$multi = clone $this->multi;
$this->close();
@ -221,6 +215,8 @@ final class CurlResponse implements ResponseInterface
$this->multi->dnsCache->evictions = $this->multi->dnsCache->evictions ?: $this->multi->dnsCache->removals;
$this->multi->dnsCache->removals = $this->multi->dnsCache->hostnames = [];
}
$this->multi = $multi;
}
}
@ -229,7 +225,6 @@ final class CurlResponse implements ResponseInterface
*/
private function close(): void
{
$this->inflate = null;
unset($this->multi->openHandles[$this->id], $this->multi->handlesActivity[$this->id]);
curl_setopt($this->handle, \CURLOPT_PRIVATE, '_0');

View File

@ -16,7 +16,6 @@ use Symfony\Component\HttpClient\Chunk\FirstChunk;
use Symfony\Component\HttpClient\Exception\TransportException;
use Symfony\Component\HttpClient\Internal\ClientState;
use Symfony\Component\HttpClient\Internal\NativeClientState;
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
/**
@ -87,14 +86,9 @@ final class NativeResponse implements ResponseInterface
public function __destruct()
{
try {
$e = null;
$this->doDestruct();
} catch (HttpExceptionInterface $e) {
throw $e;
} finally {
if ($e ?? false) {
throw $e;
}
$multi = clone $this->multi;
$this->close();
@ -103,6 +97,8 @@ final class NativeResponse implements ResponseInterface
$this->multi->responseCount = 0;
$this->multi->dnsCache = [];
}
$this->multi = $multi;
}
}
@ -197,7 +193,7 @@ final class NativeResponse implements ResponseInterface
private function close(): void
{
unset($this->multi->openHandles[$this->id], $this->multi->handlesActivity[$this->id]);
$this->handle = $this->buffer = $this->inflate = $this->onProgress = null;
$this->handle = $this->buffer = $this->onProgress = null;
}
/**

View File

@ -12,9 +12,11 @@
namespace Symfony\Component\HttpClient\Tests;
use Symfony\Component\HttpClient\Exception\ClientException;
use Symfony\Component\HttpClient\Internal\ClientState;
use Symfony\Component\HttpClient\Response\StreamWrapper;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\Test\HttpClientTestCase as BaseHttpClientTestCase;
@ -246,4 +248,26 @@ abstract class HttpClientTestCase extends BaseHttpClientTestCase
self::$vulcainStarted = true;
}
public function testHandleIsRemovedOnException()
{
$client = $this->getHttpClient(__FUNCTION__);
try {
$client->request('GET', 'http://localhost:8057/304');
$this->fail(RedirectionExceptionInterface::class.' expected');
} catch (RedirectionExceptionInterface $e) {
// The response content-type mustn't be json as that calls getContent
// @see src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php:58
$this->assertStringNotContainsString('json', $e->getResponse()->getHeaders(false)['content-type'][0] ?? '');
$r = new \ReflectionProperty($client, 'multi');
$r->setAccessible(true);
/** @var ClientState $clientState */
$clientState = $r->getValue($client);
$this->assertCount(0, $clientState->handlesActivity);
$this->assertCount(0, $clientState->openHandles);
}
}
}

View File

@ -240,6 +240,10 @@ class MockHttpClientTest extends HttpClientTestCase
$this->markTestSkipped("MockHttpClient doesn't timeout on destruct");
break;
case 'testHandleIsRemovedOnException':
$this->markTestSkipped("MockHttpClient doesn't cache handles");
break;
case 'testGetRequest':
array_unshift($headers, 'HTTP/1.1 200 OK');
$responses[] = new MockResponse($body, ['response_headers' => $headers]);

View File

@ -30,6 +30,9 @@ class Query extends AbstractQuery
/** @var resource[] */
private $results;
/** @var array */
private $serverctrls = [];
public function __construct(Connection $connection, string $dn, string $query, array $options = [])
{
parent::__construct($connection, $dn, $query, $options);
@ -97,22 +100,13 @@ class Query extends AbstractQuery
$cookie = '';
do {
if ($pageControl) {
ldap_control_paged_result($con, $pageSize, true, $cookie);
$this->controlPagedResult($con, $pageSize, $cookie);
}
$sizeLimit = $itemsLeft;
if ($pageSize > 0 && $sizeLimit >= $pageSize) {
$sizeLimit = 0;
}
$search = @$func(
$con,
$this->dn,
$this->query,
$this->options['filter'],
$this->options['attrsOnly'],
$sizeLimit,
$this->options['timeout'],
$this->options['deref']
);
$search = $this->callSearchFunction($con, $func, $sizeLimit);
if (false === $search) {
$ldapError = '';
@ -133,7 +127,7 @@ class Query extends AbstractQuery
break;
}
if ($pageControl) {
ldap_control_paged_result_response($con, $search, $cookie);
$cookie = $this->controlPagedResultResponse($con, $search, $cookie);
}
} while (null !== $cookie && '' !== $cookie);
@ -180,7 +174,8 @@ class Query extends AbstractQuery
private function resetPagination()
{
$con = $this->connection->getResource();
ldap_control_paged_result($con, 0);
$this->controlPagedResultResponse($con, 0, '');
$this->serverctrls = [];
// This is a workaround for a bit of a bug in the above invocation
// of ldap_control_paged_result. Instead of indicating to extldap that
@ -203,4 +198,62 @@ class Query extends AbstractQuery
ldap_set_option($con, \LDAP_OPT_SERVER_CONTROLS, $ctl);
}
}
/**
* Sets LDAP pagination controls.
*
* @param resource $con
*/
private function controlPagedResult($con, int $pageSize, string $cookie): bool
{
if (\PHP_VERSION_ID < 70300) {
return ldap_control_paged_result($con, $pageSize, true, $cookie);
}
$this->serverctrls = [
[
'oid' => \LDAP_CONTROL_PAGEDRESULTS,
'isCritical' => true,
'value' => [
'size' => $pageSize,
'cookie' => $cookie,
],
],
];
return true;
}
/**
* Retrieve LDAP pagination cookie.
*
* @param resource $con
* @param resource $result
*/
private function controlPagedResultResponse($con, $result, string $cookie = ''): string
{
if (\PHP_VERSION_ID < 70300) {
ldap_control_paged_result_response($con, $result, $cookie);
return $cookie;
}
ldap_parse_result($con, $result, $errcode, $matcheddn, $errmsg, $referrals, $controls);
return $controls[\LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';
}
/**
* Calls actual LDAP search function with the prepared options and parameters.
*
* @param resource $con
*
* @return resource
*/
private function callSearchFunction($con, string $func, int $sizeLimit)
{
if (\PHP_VERSION_ID < 70300) {
return @$func($con, $this->dn, $this->query, $this->options['filter'], $this->options['attrsOnly'], $sizeLimit, $this->options['timeout'], $this->options['deref']);
}
return @$func($con, $this->dn, $this->query, $this->options['filter'], $this->options['attrsOnly'], $sizeLimit, $this->options['timeout'], $this->options['deref'], $this->serverctrls);
}
}

View File

@ -489,7 +489,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
foreach ($reflectionType instanceof \ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType] as $type) {
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type;
if ('null' === $phpTypeOrClass) {
if ('null' === $phpTypeOrClass || 'mixed' === $phpTypeOrClass) {
continue;
}

View File

@ -240,6 +240,8 @@ class ReflectionExtractorTest extends TestCase
['timeout', [new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_FLOAT)]],
['optional', [new Type(Type::BUILTIN_TYPE_INT, true), new Type(Type::BUILTIN_TYPE_FLOAT, true)]],
['string', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Stringable'), new Type(Type::BUILTIN_TYPE_STRING)]],
['payload', null],
['data', null],
];
}

View File

@ -23,4 +23,12 @@ class Php80Dummy
public function setString(string|\Stringable $string)
{
}
public function setPayload(mixed $payload)
{
}
public function getData(): mixed
{
}
}

View File

@ -290,6 +290,82 @@
<source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
<target>Pilt on ruudukujuline ({{ width }}x{{ height }}px). Ruudukujulised pildid pole lubatud.</target>
</trans-unit>
<trans-unit id="76">
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
<target>Pilt on horisontaalselt orienteeritud ({{ width }}x{{ height }}px). Maastikulised pildid pole lubatud.</target>
</trans-unit>
<trans-unit id="77">
<source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
<target>Pilt on vertikaalselt orienteeritud ({{ width }}x{{ height }}px). Portreepildid pole lubatud.</target>
</trans-unit>
<trans-unit id="78">
<source>An empty file is not allowed.</source>
<target>Tühi fail pole lubatud.</target>
</trans-unit>
<trans-unit id="79">
<source>The host could not be resolved.</source>
<target>Peremeest ei õnnestunud lahendada.</target>
</trans-unit>
<trans-unit id="80">
<source>This value does not match the expected {{ charset }} charset.</source>
<target>See väärtus ei ühti eeldatava tähemärgiga {{ charset }}.</target>
</trans-unit>
<trans-unit id="81">
<source>This is not a valid Business Identifier Code (BIC).</source>
<target>See ei ole kehtiv ettevõtte identifitseerimiskood (BIC).</target>
</trans-unit>
<trans-unit id="82">
<source>Error</source>
<target>Viga</target>
</trans-unit>
<trans-unit id="83">
<source>This is not a valid UUID.</source>
<target>See pole kehtiv UUID.</target>
</trans-unit>
<trans-unit id="84">
<source>This value should be a multiple of {{ compared_value }}.</source>
<target>See väärtus peaks olema väärtuse {{ compared_value }} kordne.</target>
</trans-unit>
<trans-unit id="85">
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
<target>See ettevõtte identifitseerimiskood (BIC) ei ole seotud IBAN-iga {{ iban }}.</target>
</trans-unit>
<trans-unit id="86">
<source>This value should be valid JSON.</source>
<target>See väärtus peaks olema kehtiv JSON.</target>
</trans-unit>
<trans-unit id="87">
<source>This collection should contain only unique elements.</source>
<target>See kogu peaks sisaldama ainult unikaalseid elemente.</target>
</trans-unit>
<trans-unit id="88">
<source>This value should be positive.</source>
<target>See väärtus peaks olema positiivne.</target>
</trans-unit>
<trans-unit id="89">
<source>This value should be either positive or zero.</source>
<target>See väärtus peaks olema kas positiivne või null.</target>
</trans-unit>
<trans-unit id="90">
<source>This value should be negative.</source>
<target>See väärtus peaks olema negatiivne.</target>
</trans-unit>
<trans-unit id="91">
<source>This value should be either negative or zero.</source>
<target>See väärtus peaks olema kas negatiivne või null.</target>
</trans-unit>
<trans-unit id="92">
<source>This value is not a valid timezone.</source>
<target>See väärtus pole kehtiv ajavöönd.</target>
</trans-unit>
<trans-unit id="93">
<source>This password has been leaked in a data breach, it must not be used. Please use another password.</source>
<target>See parool on lekkinud andmerikkumise korral, seda ei tohi kasutada. Palun kasutage muud parooli.</target>
</trans-unit>
<trans-unit id="94">
<source>This value should be between {{ min }} and {{ max }}.</source>
<target>See väärtus peaks olema vahemikus {{ min }} kuni {{ max }}.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -334,6 +334,58 @@
<source>This value should be valid JSON.</source>
<target>Este valor deve ser um JSON válido.</target>
</trans-unit>
<trans-unit id="87">
<source>This collection should contain only unique elements.</source>
<target>Esta coleção deve conter somente elementos únicos.</target>
</trans-unit>
<trans-unit id="88">
<source>This value should be positive.</source>
<target>Este valor deve ser positivo.</target>
</trans-unit>
<trans-unit id="89">
<source>This value should be either positive or zero.</source>
<target>Este valor deve ser positivo ou zero.</target>
</trans-unit>
<trans-unit id="90">
<source>This value should be negative.</source>
<target>Este valor deve ser negativo.</target>
</trans-unit>
<trans-unit id="91">
<source>This value should be either negative or zero.</source>
<target>Este valor deve ser negativo ou zero.</target>
</trans-unit>
<trans-unit id="92">
<source>This value is not a valid timezone.</source>
<target>Este valor não representa um fuso horário válido.</target>
</trans-unit>
<trans-unit id="93">
<source>This password has been leaked in a data breach, it must not be used. Please use another password.</source>
<target>Esta senha foi divulgada num vazamento de dados e não deve ser utilizada. Por favor, utilize outra senha.</target>
</trans-unit>
<trans-unit id="94">
<source>This value should be between {{ min }} and {{ max }}.</source>
<target>Este valor deve estar entre {{ min }} e {{ max }}.</target>
</trans-unit>
<trans-unit id="95">
<source>This value is not a valid hostname.</source>
<target>Este valor não é um nome de host válido.</target>
</trans-unit>
<trans-unit id="96">
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>O número de elementos desta coleção deve ser um múltiplo de {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Este valor deve satisfazer pelo menos uma das seguintes restrições:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>Cada elemento desta coleção deve satisfazer seu próprio grupo de restrições.</target>
</trans-unit>
<trans-unit id="99">
<source>This value is not a valid International Securities Identification Number (ISIN).</source>
<target>Este valor não é um Número de Identificação de Títulos Internacionais (ISIN) válido.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -222,7 +222,7 @@ class VarCloner extends AbstractCloner
$stub->position = $len++;
} elseif ($pos < $maxItems) {
if ($maxItems < $pos += \count($a)) {
$a = \array_slice($a, 0, $maxItems - $pos);
$a = \array_slice($a, 0, $maxItems - $pos, true);
if ($stub->cut >= 0) {
$stub->cut += $pos - $maxItems;
}

View File

@ -170,7 +170,7 @@ EOTXT;
'Level 3 Item 3',
],
[
'Level 3 Item 4',
999 => 'Level 3 Item 4',
'Level 3 Item 5',
'Level 3 Item 6',
],
@ -250,7 +250,7 @@ Symfony\Component\VarDumper\Cloner\Data Object
[1] => Array
(
[0] => 2
[2] => 7
[1] => 7
)
[2] => Array
@ -307,7 +307,7 @@ Symfony\Component\VarDumper\Cloner\Data Object
[7] => Array
(
[0] => Level 3 Item 4
[999] => Level 3 Item 4
)
)

View File

@ -63,6 +63,12 @@ switch ($vars['REQUEST_URI']) {
header('Content-Type: application/json', true, 404);
break;
case '/404-gzipped':
header('Content-Type: text/plain', true, 404);
ob_start('ob_gzhandler');
echo 'some text';
exit;
case '/301':
if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) {
header('Location: http://127.0.0.1:8057/302', true, 301);
@ -157,7 +163,7 @@ switch ($vars['REQUEST_URI']) {
exit;
case '/json':
header("Content-Type: application/json");
header('Content-Type: application/json');
echo json_encode([
'documents' => [
['id' => '/json/1'],
@ -170,7 +176,7 @@ switch ($vars['REQUEST_URI']) {
case '/json/1':
case '/json/2':
case '/json/3':
header("Content-Type: application/json");
header('Content-Type: application/json');
echo json_encode([
'title' => $vars['REQUEST_URI'],
]);

View File

@ -860,6 +860,18 @@ abstract class HttpClientTestCase extends TestCase
}
}
public function testGetEncodedContentAfterDestruct()
{
$client = $this->getHttpClient(__FUNCTION__);
try {
$client->request('GET', 'http://localhost:8057/404-gzipped');
$this->fail(ClientExceptionInterface::class.' expected');
} catch (ClientExceptionInterface $e) {
$this->assertSame('some text', $e->getResponse()->getContent(false));
}
}
public function testProxy()
{
$client = $this->getHttpClient(__FUNCTION__);