Skip to content

[DependencyInjection] fixed ini file values conversion #20232

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

Merged
merged 1 commit into from
Nov 3, 2016

Conversation

fabpot
Copy link
Member

@fabpot fabpot commented Oct 18, 2016

Q A
Branch? master
Bug fix? yes
New feature? no
BC breaks? no-ish
Deprecations? no
Tests pass? yes
Fixed tickets n/a
License MIT
Doc PR n/a

When using the ini format to load parameters in the Container, the parameter values were converted by PHP directly ('true' => 1 for instance). But when using the YAML or XML format, the conversions are much broader and more precise ('true' => true for instance). This PR fixed fixes this discrepancy by using the same rules as XML (we could use INI_SCANNER_TYPED for recent versions of PHP but the rules are not exactly the same, so I prefer consistency here).

One might argue that this is a new feature and that this should be merged into master, which I can accept as well. In master, the XmlUtils::phpize() method should be deprecated and replaced by a more generic phpize class.

ping @symfony/deciders

@javiereguiluz
Copy link
Member

👍

It can be debatable to merge it in 2.7 or master ... but to me this is a bugfix, so it should stay in 2.7.

@dunglas
Copy link
Member

dunglas commented Oct 18, 2016

👍

@nicolas-grekas
Copy link
Member

👍 for 2.7 also

@fabpot fabpot force-pushed the ini-type-conversion-fix branch from db988f3 to ead4617 Compare October 18, 2016 15:44
'-10100.1' => -10100.1,
'-10,100.1' => '-10,100.1',
);
$this->assertEquals($expected, $this->container->getParameterBag()->all(), '->load() converts values to PHP types');
Copy link
Contributor

@Tobion Tobion Oct 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK assertEquals doesn't ensure correct types, e.g. '1' == 1. So the test is not really precise.

@fabpot fabpot force-pushed the ini-type-conversion-fix branch 3 times, most recently from f77cdda to 4110de6 Compare October 18, 2016 17:52
@ro0NL
Copy link
Contributor

ro0NL commented Oct 18, 2016

@fabpot can you test with on, off, yes, no... i think this can get problematic ;-) The BC break is real: https://3v4l.org/bW8P0

edit: also constants/nulls are affected

@fabpot
Copy link
Member Author

fabpot commented Oct 18, 2016

@ro0NL Not sure I understand your concern. Can you be more precise?

@ro0NL
Copy link
Contributor

ro0NL commented Oct 18, 2016

This breaks configuration like

[parameters]
   is_this_enabled = yes ; comment

right? AFAIK this is not covered by XmlUtils::phpize nor this PR...

Before string("1") => bool(true), after string("yes ")

edit: comments are just buggy with INI_SCANNER_RAW :) https://3v4l.org/7pV3u

@ro0NL
Copy link
Contributor

ro0NL commented Oct 18, 2016

@fabpot perhaps more serious, no escaping is applied: https://3v4l.org/oGJqj

@nicolas-grekas
Copy link
Member

@ro0NL is right, we need to polyfill INI_SCANNER_TYPED...

@@ -40,6 +33,34 @@ public function testIniFileCanBeLoaded()
}

/**
* @requires PHP 5.3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless, as we cannot run on PHP < 5.3 anyway

@ro0NL
Copy link
Contributor

ro0NL commented Nov 2, 2016

@nicolas-grekas we basically already doing that with INI_SCANNER_NORMAL + XmlUtils::phpize.

Imo a

more generic phpize class

would be sufficient.

or simply patch the current ini loader on numerics, etc.

@fabpot fabpot force-pushed the ini-type-conversion-fix branch 6 times, most recently from 4accc8f to 8a3e741 Compare November 3, 2016 20:03
("'" === $value[0] && "'" === $value[strlen($value) - 1]) ||
('"' === $value[0] && '"' === $value[strlen($value) - 1])
):
// quoted string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps throw if 1 === strlen($value) (invalid syntax)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the php.ini file would not be valid in that case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was fatal before :/ https://3v4l.org/VgDvJ

With SCANNER_RAW it parses though.. but that doesnt mean it's valid, it's raw :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@fabpot
Copy link
Member Author

fabpot commented Nov 3, 2016

I've updated this PR to take into account how the scanner type convert values, and added some more tests. As for the failure on PHP 7.1, not sure what changed. Is it better now?

@fabpot fabpot force-pushed the ini-type-conversion-fix branch from 8a3e741 to 5026d27 Compare November 3, 2016 20:50
@fabpot fabpot force-pushed the ini-type-conversion-fix branch from 5026d27 to 824520d Compare November 3, 2016 20:50
@fabpot
Copy link
Member Author

fabpot commented Nov 3, 2016

I propose to merge it into master instead of 2.7 as it's more complex than anticipated.

@nicolas-grekas
Copy link
Member

Using INI_SCANNER_TYPED when possible would be a great way to ensure the polyfill behaves as expected

@fabpot
Copy link
Member Author

fabpot commented Nov 3, 2016

@nicolas-grekas Not really possible as our behavior is not exactly the same (we must be as close as possible to it but also be closed to what XmlUtils does to be consistent with the other formats).

return true;
case 'no' === $value || 'off' === $value || 'none' === $value:
return false;
case isset($value[0]) && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose this patch:

--- a/src/Symfony/Component/DependencyInjection/Loader/IniFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/IniFileLoader.php
@@ -64,15 +64,16 @@ class IniFileLoader extends FileLoader
    {
        // trim on the right as a comment leaves the whitespaces in place
        $value = rtrim($value);
+        $lowercaseValue = strtolower($value);

        switch (true) {
            case defined($value):
                return constant($value);
-            case 'yes' === $value || 'on' === $value:
+            case 'yes' === $lowercaseValue || 'on' === $lowercaseValue:
                return true;
-            case 'no' === $value || 'off' === $value || 'none' === $value:
+            case 'no' === $lowercaseValue || 'off' === $lowercaseValue || 'none' === $lowercaseValue:
                return false;
-            case isset($value[0]) && (
+            case isset($value[1]) && (
                ("'" === $value[0] && "'" === $value[strlen($value) - 1]) ||
                ('"' === $value[0] && '"' === $value[strlen($value) - 1])
            ):
diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json
index 9c12d11..e24187f 100644
--- a/src/Symfony/Component/DependencyInjection/composer.json
+++ b/src/Symfony/Component/DependencyInjection/composer.json
@@ -20,7 +20,7 @@
    },
    "require-dev": {
        "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7",
-        "symfony/config": "~2.2",
+        "symfony/config": "~2.7",
        "symfony/expression-language": "~2.6"
    },
    "conflict": {

@fabpot fabpot force-pushed the ini-type-conversion-fix branch from 824520d to 7e315ac Compare November 3, 2016 23:16
@fabpot fabpot changed the base branch from 2.7 to master November 3, 2016 23:16
@fabpot fabpot force-pushed the ini-type-conversion-fix branch from 7e315ac to 61b4c4a Compare November 3, 2016 23:17
@fabpot
Copy link
Member Author

fabpot commented Nov 3, 2016

Rebased on master

@fabpot fabpot force-pushed the ini-type-conversion-fix branch from 61b4c4a to 4ccfce6 Compare November 3, 2016 23:43
@fabpot fabpot merged commit 4ccfce6 into symfony:master Nov 3, 2016
fabpot added a commit that referenced this pull request Nov 3, 2016
… (fabpot)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[DependencyInjection] fixed ini file values conversion

| Q | A |
| --- | --- |
| Branch? | master |
| Bug fix? | yes |
| New feature? | no |
| BC breaks? | no-ish |
| Deprecations? | no |
| Tests pass? | yes |
| Fixed tickets | n/a |
| License | MIT |
| Doc PR | n/a |

When using the ini format to load parameters in the Container, the parameter values were converted by PHP directly (`'true'` => `1` for instance). But when using the YAML or XML format, the conversions are much broader and more precise (`'true'` => `true` for instance). This PR fixed fixes this discrepancy by using the same rules as XML (we could use `INI_SCANNER_TYPED` for recent versions of PHP but the rules are not exactly the same, so I prefer consistency here).

One might argue that this is a new feature and that this should be merged into master, which I can accept as well. In master, the `XmlUtils::phpize()` method should be deprecated and replaced by a more generic phpize class.

ping @symfony/deciders

Commits
-------

4ccfce6 [DependencyInjection] fixed ini file values conversion
@fabpot fabpot mentioned this pull request Nov 17, 2016
@fabpot fabpot deleted the ini-type-conversion-fix branch January 7, 2017 00:34
wouterj added a commit to symfony/symfony-docs that referenced this pull request Sep 4, 2022
…Cat)

This PR was merged into the 4.4 branch.

Discussion
----------

[Config] Remove obsolete warning about INI files

Spotted thanks to #17232 (comment)

Since symfony/symfony#20232 the claim that “you can only set parameters to string values” is not valid anymore.

Commits
-------

7a67d8f Remove obsolete warning
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants