Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9fb357d

Browse filesBrowse files
committed
Detect disabled EntityLoader
1 parent 4f6f4de commit 9fb357d
Copy full SHA for 9fb357d

File tree

5 files changed

+122
-13
lines changed
Filter options

5 files changed

+122
-13
lines changed

‎src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+37-4Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -634,17 +634,50 @@ public function validateSchema(\DOMDocument $dom)
634634
EOF
635635
;
636636

637-
$disableEntities = @libxml_disable_entity_loader(false);
638-
$valid = @$dom->schemaValidateSource($source);
639-
@libxml_disable_entity_loader($disableEntities);
640-
637+
if ($this->shouldEnableEntityLoader()) {
638+
$disableEntities = libxml_disable_entity_loader(false);
639+
$valid = @$dom->schemaValidateSource($source);
640+
libxml_disable_entity_loader($disableEntities);
641+
} else {
642+
$valid = @$dom->schemaValidateSource($source);
643+
}
641644
foreach ($tmpfiles as $tmpfile) {
642645
@unlink($tmpfile);
643646
}
644647

645648
return $valid;
646649
}
647650

651+
private function shouldEnableEntityLoader(): bool
652+
{
653+
// Version prior to 8.0 can be enabled without deprecation
654+
if (PHP_VERSION_ID < 80000) {
655+
return true;
656+
}
657+
658+
static $dom, $schema;
659+
if ($dom === null) {
660+
$dom = new \DOMDocument();
661+
$dom->loadXML('<?xml version="1.0"?><test/>');
662+
663+
$tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
664+
\register_shutdown_function(static function() use ($tmpfile) {
665+
@\unlink($tmpfile);
666+
});
667+
$schema = '<?xml version="1.0" encoding="utf-8"?>
668+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
669+
<xsd:include schemaLocation="file:///'.str_replace('\\', '/', $tmpfile).'" />
670+
</xsd:schema>';
671+
\file_put_contents($tmpfile, '<?xml version="1.0" encoding="utf-8"?>
672+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
673+
<xsd:element name="test" type="testType" />
674+
<xsd:complexType name="testType"/>
675+
</xsd:schema>');
676+
}
677+
678+
return !@$dom->schemaValidateSource($schema);
679+
}
680+
648681
private function validateAlias(\DOMElement $alias, string $file)
649682
{
650683
foreach ($alias->attributes as $name => $node) {

‎src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ public function testTranslationFileIsValid($filePath)
2929
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
3030
}
3131

32+
/**
33+
* @dataProvider provideTranslationFiles
34+
* @group Legacy
35+
*/
36+
public function testTranslationFileIsValidWithoutEntityLoader($filePath)
37+
{
38+
$document = new \DOMDocument();
39+
$document->loadXML(file_get_contents($filePath));
40+
libxml_disable_entity_loader(true);
41+
42+
$errors = XliffUtils::validateSchema($document);
43+
44+
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
45+
}
46+
3247
public function provideTranslationFiles()
3348
{
3449
return array_map(

‎src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ public function testTranslationFileIsValid($filePath)
2929
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
3030
}
3131

32+
/**
33+
* @dataProvider provideTranslationFiles
34+
*/
35+
public function testTranslationFileIsValidWithoutEntityLoader($filePath)
36+
{
37+
$document = new \DOMDocument();
38+
$document->loadXML(file_get_contents($filePath));
39+
libxml_disable_entity_loader(true);
40+
41+
$errors = XliffUtils::validateSchema($document);
42+
43+
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
44+
}
45+
3246
public function provideTranslationFiles()
3347
{
3448
return array_map(

‎src/Symfony/Component/Translation/Util/XliffUtils.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Translation/Util/XliffUtils.php
+42-9Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,19 @@ public static function validateSchema(\DOMDocument $dom): array
6161
{
6262
$xliffVersion = static::getVersionNumber($dom);
6363
$internalErrors = libxml_use_internal_errors(true);
64-
$disableEntities = @libxml_disable_entity_loader(false);
65-
66-
$isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
67-
if (!$isValid) {
68-
@libxml_disable_entity_loader($disableEntities);
69-
70-
return self::getXmlErrors($internalErrors);
64+
if ($shouldEnable = self::shouldEnableEntityLoader()) {
65+
$disableEntities = libxml_disable_entity_loader(false);
66+
}
67+
try {
68+
$isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
69+
if (!$isValid) {
70+
return self::getXmlErrors($internalErrors);
71+
}
72+
} finally {
73+
if ($shouldEnable) {
74+
libxml_disable_entity_loader($disableEntities);
75+
}
7176
}
72-
73-
@libxml_disable_entity_loader($disableEntities);
7477

7578
$dom->normalizeDocument();
7679

@@ -80,6 +83,36 @@ public static function validateSchema(\DOMDocument $dom): array
8083
return [];
8184
}
8285

86+
private static function shouldEnableEntityLoader(): bool
87+
{
88+
// Version prior to 8.0 can be enabled without deprecation
89+
if (PHP_VERSION_ID < 80000) {
90+
return true;
91+
}
92+
93+
static $dom, $schema;
94+
if ($dom === null) {
95+
$dom = new \DOMDocument();
96+
$dom->loadXML('<?xml version="1.0"?><test/>');
97+
98+
$tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
99+
\register_shutdown_function(static function() use ($tmpfile) {
100+
@\unlink($tmpfile);
101+
});
102+
$schema = '<?xml version="1.0" encoding="utf-8"?>
103+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
104+
<xsd:include schemaLocation="file:///'.str_replace('\\', '/', $tmpfile).'" />
105+
</xsd:schema>';
106+
\file_put_contents($tmpfile, '<?xml version="1.0" encoding="utf-8"?>
107+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
108+
<xsd:element name="test" type="testType" />
109+
<xsd:complexType name="testType"/>
110+
</xsd:schema>');
111+
}
112+
113+
return !@$dom->schemaValidateSource($schema);
114+
}
115+
83116
public static function getErrorsAsString(array $xmlErrors): string
84117
{
85118
$errorsAsString = '';

‎src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ public function testTranslationFileIsValid($filePath)
2929
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
3030
}
3131

32+
/**
33+
* @dataProvider provideTranslationFiles
34+
*/
35+
public function testTranslationFileIsValidWithoutEntityLoader($filePath)
36+
{
37+
$document = new \DOMDocument();
38+
$document->loadXML(file_get_contents($filePath));
39+
libxml_disable_entity_loader(true);
40+
41+
$errors = XliffUtils::validateSchema($document);
42+
43+
$this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message'))));
44+
}
45+
3246
public function provideTranslationFiles()
3347
{
3448
return array_map(

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.