Skip to content
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

Make Magento compatible with composer ~1.3.0 #8638

Closed
wants to merge 1 commit into from

Conversation

AntonEvers
Copy link
Contributor

Fixes #8635

@maghamed maghamed self-requested a review February 21, 2017 17:53
@maghamed maghamed self-assigned this Feb 21, 2017
@maksek maksek mentioned this pull request Feb 28, 2017
@ktomk
Copy link
Contributor

ktomk commented Feb 28, 2017

It would be great to see a regression test looking for these values. DI itself does ltrim from top of my head, scanning over the files w/ xpath and starts-with could do it. Should also help extension authors to check their XMLs.

Small POC: https://gist.github.com/ktomk/a7690cc3353298eec609fdc1d76ad295

@orlangur
Copy link
Contributor

@ktomk, I remember leading backslash started to be trimmed at some point as such situation produced inconsistent behavior before that. As to me it would be better to be strict about that and simply disallow leading backslash.

As this is a BC break it could be done in two phases: first deprecate the ability to use leading backslash and then remove in some future release.

@ktomk
Copy link
Contributor

ktomk commented Feb 28, 2017

True, it makes sense to first deprecate this, I also thought about extension authors.

IMHO there is nothing wrong to fix the di.xmls within the repo first. Looks like this commit might miss the tests, my example counts more files (86) than in the changeset (65). The example I linked runs against Magento 2.1.2 Community so does not catch upstream changes since then.

@ktomk
Copy link
Contributor

ktomk commented Feb 28, 2017

And not to miss: Thanks for the initiative here, I had lost why it's not compatible with the stable composer version. ~~~That to say, a short explanation why this is necessary would be great to read~~~ /e: it's in the corresponding Magento Stackexchange answer.

@orlangur
Copy link
Contributor

Fixing this repo is an easiest part, there are even some existing tests reading all active di.xml, like https://github.com/magento/magento2/blob/develop/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php#L398 (not sure why it is skipped though).

And also if we bump composer version in composer.json it will test the leading backslash absence by design for all builds using DI pre-compilation (at least functional tests, don't remember about integration tests).

@okorshenko okorshenko added this to the March 2017 milestone Mar 1, 2017
@maghamed
Copy link
Contributor

maghamed commented Mar 1, 2017

looks like we need to introduce static test (intergrity) which will cover these changes and prevent us from new occurrences of leading backslashes appear.
@ajpevers could you please accompany these changes with a static test?

@ktomk
Copy link
Contributor

ktomk commented Mar 1, 2017

@maghamed If I may suggest to do these static checks already when validating the XML files with the schema, see #8743.

@maghamed
Copy link
Contributor

maghamed commented Mar 1, 2017

@ktomk yes, this proposal sounds reasonable

ktomk added a commit to ktomk/magento2 that referenced this pull request Mar 1, 2017
The preferenceType @for/@type attributes, the typeType @name attribute,
the virtualTypeType @type attribute and the pluginType @type attribute
contain class-names (FQCNs) which should not start with a leading
backslash (U+005C "\") and should not contain other invalid character
sequences that would represent an invalid PHP class-name.

Previously this was possible and these errors got unnoticed within di.xml
configuration file validation.

The ObjectManager - a user of these configurations - handles this common
error in user input in part so far by removing any trailing slashes with
multiple calls like:

        $type = ltrim($type, '\\');

This change has been introduced in 33ebc24 and could be classified as a
workaround for a quite common mistake when specifying an FQCN that despite
the varying notations in the PHP manual due to the contextual resolution
rules (and different to a file-systems absolute path in POSIX) must not
start with a leading separator as type or class-name.

When using a string-value as class-name (e.g. class_exists() calls) the
class name is always an FQCN as namespacing in PHP is contextual within
source-code for identifiers only and not for strings.

So relative class-names (like those with a leading backslash) do not
apply for strings. This is the case in configuration files like di.xml
files. The di.xml files use the

    urn:magento:framework:ObjectManager/etc/config.xsd

schema location which is resolved by UrnResolver (6379732) to

    lib/internal/Magento/Framework/ObjectManager/etc/config.xsd

That schema did validate class-name attribute values only against the
simple type of being strings (xs:string). As a class-name in PHP is a
valid string also if starting with the backslash character (and other
invalid names, like digits in front), this commit extends the schema
to validate against the regular expression provided by the PHP manual [1]:

    ^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$

by adding a new simple-type called "phpFqcn" that qualifies the string-
base-type with the from PHP manual translated pattern:

    [a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*

extended for namespaced class-names:

    ([a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*)(\\[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*)*

The change ensures that the said attribute values are validated and
invalid class-names are recognized during schema based validation.

This change prevents that configured PHP-types can be autoloaded when
used w/o smudging (see the ltrim() operation). It has been documented [2]
that the leading backslash prevents correct file-resolution when auto-
loading with the Composer autoloader, a component actively used by the
Magento application.

This change adheres to existing PR magento#8638 and relates to issue magento#8635.

Refs:

- magento#8635

- magento#8638

- [1] https://php.net/language.oop5.basic

- [2] http://magento.stackexchange.com/a/161010

- 33ebc24

- 6379732
ktomk added a commit to ktomk/magento2 that referenced this pull request Mar 2, 2017
The preferenceType @for/@type attributes, the typeType @name attribute,
the virtualTypeType @type attribute and the pluginType @type attribute
contain class-names (FQCNs) which should not start with a leading
backslash (U+005C "\") and should not contain other invalid character
sequences that would represent an invalid PHP class-name.

Previously this was possible and these errors got unnoticed within di.xml
configuration file validation.

The ObjectManager - a user of these configurations - handles this common
error in user input in part so far by removing any trailing slashes with
multiple calls like:

        $type = ltrim($type, '\\');

This change has been introduced in 33ebc24 and could be classified as a
workaround for a quite common mistake when specifying an FQCN that despite
the varying notations in the PHP manual due to the contextual resolution
rules (and different to a file-systems absolute path in POSIX) must not
start with a leading separator as type or class-name.

When using a string-value as class-name (e.g. class_exists() calls) the
class name is always an FQCN as namespacing in PHP is contextual within
source-code for identifiers only and not for strings.

So relative class-names (like those with a leading backslash) do not
apply for strings. This is the case in configuration files like di.xml
files. The di.xml files use the

    urn:magento:framework:ObjectManager/etc/config.xsd

schema location which is resolved by UrnResolver (6379732) to

    lib/internal/Magento/Framework/ObjectManager/etc/config.xsd

That schema did validate class-name attribute values only against the
simple type of being strings (xs:string). As a class-name in PHP is a
valid string also if starting with the backslash character (and other
invalid names, like digits in front), this commit extends the schema
to validate against the regular expression provided by the PHP manual [1]:

    ^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$

by adding a new simple-type called "phpClassName" that qualifies the string-
base-type with the from PHP manual translated pattern:

    [a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*

extended for namespaced class-names:

    ([a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*)(\\[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*)*

The change ensures that the said attribute values are validated and
invalid class-names are recognized during schema based validation.

This change verifies that configured PHP-types can be autoloaded when
used w/o smudging (see the ltrim() operation). It has been documented [2]
that the leading backslash prevents correct file-resolution when auto-
loading with the Composer autoloader, a component actively used by the
Magento application.

This change adheres to existing PR magento#8638 and relates to issue magento#8635.

Additionally this commit adds tests for the new phpClassName xsd type with
config xml material.

Refs:

- magento#8635

- magento#8638

- [1] https://php.net/language.oop5.basic

- [2] http://magento.stackexchange.com/a/161010

- 33ebc24

- 6379732
@maghamed
Copy link
Contributor

maghamed commented Mar 2, 2017

@ajpevers thanks for your contribution, I'll close current PR and continue processing #8743 which @ktomk referred to as it contains your changes and accompanies them with test

@maghamed maghamed closed this Mar 2, 2017
@orlangur
Copy link
Contributor

orlangur commented Mar 2, 2017

@maghamed will it become Merged after #8743 merged? :) If not, I propose to reopen this one so they both become Merged when changes delivered to mainline.

@ktomk
Copy link
Contributor

ktomk commented Mar 2, 2017

@orlangur Yes, due to your request, #8743 has 0b243b8 (as first commit, see https://github.com/magento/magento2/pull/8743/commits). I rebased it on this PR's branch. ;)

@orlangur
Copy link
Contributor

orlangur commented Mar 2, 2017

@ktomk yeah, I really appreciate this, I'm asking if #8638 will remain Closed or become Merged.

@ktomk
Copy link
Contributor

ktomk commented Mar 2, 2017

Ah, okay. I think Github marks it as merged but now that you ask ... ;)

@AntonEvers AntonEvers deleted the issue-8635-develop branch June 13, 2017 05:11
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.

5 participants