diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 19566e9aa7..2ebdbda090 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -634,14 +634,13 @@ $imports
EOF
;
- if (\LIBXML_VERSION < 20900) {
+ if ($this->shouldEnableEntityLoader()) {
$disableEntities = libxml_disable_entity_loader(false);
$valid = @$dom->schemaValidateSource($source);
libxml_disable_entity_loader($disableEntities);
} else {
$valid = @$dom->schemaValidateSource($source);
}
-
foreach ($tmpfiles as $tmpfile) {
@unlink($tmpfile);
}
@@ -649,6 +648,36 @@ EOF
return $valid;
}
+ private function shouldEnableEntityLoader(): bool
+ {
+ // Version prior to 8.0 can be enabled without deprecation
+ if (\PHP_VERSION_ID < 80000) {
+ return true;
+ }
+
+ static $dom, $schema;
+ if (null === $dom) {
+ $dom = new \DOMDocument();
+ $dom->loadXML('');
+
+ $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+ register_shutdown_function(static function () use ($tmpfile) {
+ @unlink($tmpfile);
+ });
+ $schema = '
+
+
+';
+ file_put_contents($tmpfile, '
+
+
+
+');
+ }
+
+ return !@$dom->schemaValidateSource($schema);
+ }
+
private function validateAlias(\DOMElement $alias, string $file)
{
foreach ($alias->attributes as $name => $node) {
diff --git a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
index 53b2cee448..5a9669e92b 100644
--- a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
+++ b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
@@ -29,6 +29,21 @@ class TranslationFilesTest extends TestCase
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
}
+ /**
+ * @dataProvider provideTranslationFiles
+ * @group Legacy
+ */
+ public function testTranslationFileIsValidWithoutEntityLoader($filePath)
+ {
+ $document = new \DOMDocument();
+ $document->loadXML(file_get_contents($filePath));
+ libxml_disable_entity_loader(true);
+
+ $errors = XliffUtils::validateSchema($document);
+
+ $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
+ }
+
public function provideTranslationFiles()
{
return array_map(
diff --git a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
index 2402b01998..4255e91d92 100644
--- a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
+++ b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
@@ -29,6 +29,20 @@ class TranslationFilesTest extends TestCase
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
}
+ /**
+ * @dataProvider provideTranslationFiles
+ */
+ public function testTranslationFileIsValidWithoutEntityLoader($filePath)
+ {
+ $document = new \DOMDocument();
+ $document->loadXML(file_get_contents($filePath));
+ libxml_disable_entity_loader(true);
+
+ $errors = XliffUtils::validateSchema($document);
+
+ $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
+ }
+
public function provideTranslationFiles()
{
return array_map(
diff --git a/src/Symfony/Component/Translation/Util/XliffUtils.php b/src/Symfony/Component/Translation/Util/XliffUtils.php
index a8c05c2244..e4373a7d5b 100644
--- a/src/Symfony/Component/Translation/Util/XliffUtils.php
+++ b/src/Symfony/Component/Translation/Util/XliffUtils.php
@@ -61,21 +61,18 @@ class XliffUtils
{
$xliffVersion = static::getVersionNumber($dom);
$internalErrors = libxml_use_internal_errors(true);
- if (\LIBXML_VERSION < 20900) {
+ if ($shouldEnable = self::shouldEnableEntityLoader()) {
$disableEntities = libxml_disable_entity_loader(false);
}
-
- $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
- if (!$isValid) {
- if (\LIBXML_VERSION < 20900) {
+ try {
+ $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
+ if (!$isValid) {
+ return self::getXmlErrors($internalErrors);
+ }
+ } finally {
+ if ($shouldEnable) {
libxml_disable_entity_loader($disableEntities);
}
-
- return self::getXmlErrors($internalErrors);
- }
-
- if (\LIBXML_VERSION < 20900) {
- libxml_disable_entity_loader($disableEntities);
}
$dom->normalizeDocument();
@@ -86,6 +83,36 @@ class XliffUtils
return [];
}
+ private static function shouldEnableEntityLoader(): bool
+ {
+ // Version prior to 8.0 can be enabled without deprecation
+ if (\PHP_VERSION_ID < 80000) {
+ return true;
+ }
+
+ static $dom, $schema;
+ if (null === $dom) {
+ $dom = new \DOMDocument();
+ $dom->loadXML('');
+
+ $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+ register_shutdown_function(static function () use ($tmpfile) {
+ @unlink($tmpfile);
+ });
+ $schema = '
+
+
+';
+ file_put_contents($tmpfile, '
+
+
+
+');
+ }
+
+ return !@$dom->schemaValidateSource($schema);
+ }
+
public static function getErrorsAsString(array $xmlErrors): string
{
$errorsAsString = '';
diff --git a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php
index 894ae55f10..6e0620b517 100644
--- a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php
+++ b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php
@@ -29,6 +29,20 @@ class TranslationFilesTest extends TestCase
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
}
+ /**
+ * @dataProvider provideTranslationFiles
+ */
+ public function testTranslationFileIsValidWithoutEntityLoader($filePath)
+ {
+ $document = new \DOMDocument();
+ $document->loadXML(file_get_contents($filePath));
+ libxml_disable_entity_loader(true);
+
+ $errors = XliffUtils::validateSchema($document);
+
+ $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
+ }
+
public function provideTranslationFiles()
{
return array_map(