Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[6.2] [DI] Node Value ignored in XMLFileLoader #48445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BrandonlinU opened this issue Dec 2, 2022 · 4 comments
Closed

[6.2] [DI] Node Value ignored in XMLFileLoader #48445

BrandonlinU opened this issue Dec 2, 2022 · 4 comments

Comments

@BrandonlinU
Copy link
Contributor

BrandonlinU commented Dec 2, 2022

Symfony version(s) affected

6.2.0

Description

After update to Symfony 6.2, the new changes to support the array tag attributes introduced in #47364 throw an exception when it load a service tag with the name in the inner content of the tag.

How to reproduce

  1. Create a new project with symfony/dependency-injection and symfony/config dependencies.
  2. Create a index.php file with the following content:
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;

$containerBuilder = new ContainerBuilder();
$loader = new XmlFileLoader($containerBuilder, new FileLocator(__DIR__));
$loader->load('services.xml');
  1. Generate a service.xml with a service description with a tag, as the following.
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services">
    <services>
        <service id="dummy_service" class="App\Service\DummyService">
            <tag>dummy_tag</tag>
        </service>
    </services>
</container>
  1. Try to run the index.php script.

Possible Solution

It looks like that in the XmlFileLoader tries to extract the tagName incorrectly, because the $tag->hasChildNodes() return a boolean, and not an string, and when tries to extract the nodeValue, it extracts the attribute name instead, causing the error.

if ('' === $tagName = $tag->hasChildNodes() || '' === $tag->nodeValue ? $tag->getAttribute('name') : $tag->nodeValue) {
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', (string) $service->getAttribute('id'), $file));
}

I think that with the following code, that tries to extract the nodeValue and if it is not possible tries to get the attribute name from the XML tag, should solve the error.

if ('' === $tagName = $tag->nodeValue ?: $tag->getAttribute('name')) {
    throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', (string) $service->getAttribute('id'), $file));
}

Additional Context

The exception throw is the following:

Symfony\Component\DependencyInjection\Exception\InvalidArgumentException : The tag name for service "instacar.extra_filters.security_expression_value_provider" in "/home/bantonio/PhpstormProjects/FilterBundle/src/DependencyInjection/../Resources/config/security.xml" must be a non-empty string.
@BrandonlinU BrandonlinU added the Bug label Dec 2, 2022
@BrandonlinU BrandonlinU changed the title DI Node Value ignored in XMLFileLoader [DI] Node Value ignored in XMLFileLoader Dec 2, 2022
@BrandonlinU BrandonlinU changed the title [DI] Node Value ignored in XMLFileLoader [6.2] [DI] Node Value ignored in XMLFileLoader Dec 2, 2022
@stof
Copy link
Member

stof commented Dec 2, 2022

I guess that code misses parenthesis around the || in the condition of the ternary to have the right precedence.
And it probably also misses a test covering that case...

@nicolas-grekas
Copy link
Member

Can you please implement what @stof suggests @BrandonlinU and submit it as a PR on 6.2?

@BrandonlinU
Copy link
Contributor Author

Sure, give me a moment to make the pull request...

@BrandonlinU
Copy link
Contributor Author

BrandonlinU commented Dec 2, 2022

Well... I have bad news: After update the code with the following code

if ('' === $tagName = ($tag->hasChildNodes() || '' === $tag->nodeValue) ? $tag->getAttribute('name') : $tag->nodeValue) {
    throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', (string) $service->getAttribute('id'), $file));
}

still does not pass the tests, because hasChildNodes() return "true" if it is a text node or an attribute tag, returning the "name" attribute. I think that you tried to check if the childen are elements, and not text nodes, but I am not sure.

BrandonlinU added a commit to InstacarMX/ExtraFiltersBundle that referenced this issue Dec 7, 2022
nicolas-grekas added a commit that referenced this issue Dec 13, 2022
… (BrandonlinU)

This PR was squashed before being merged into the 6.2 branch.

Discussion
----------

[DependencyInjection] Fix bug when tag name is a text node

| Q             | A
| ------------- | ---
| Branch?       | 6.2
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #48445
| License       | MIT

Following the discussion in the ticket, I added a test for a tag without name attribute and content inside the tag for the name. I use `$tag->childElementCount !== 0` instead of `$tag->hasChildNode()` to detect if a `<attribute>` tag is present in the tag definition, or is only the name of the tag.

Commits
-------

b9337f1 [DependencyInjection] Fix bug when tag name is a text node
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants