Reputation: 1587
Given that Composer can work with virtual packages in provide
section of composer.json
file, how are the versions managed of those virtual packages if no one holds the responsibility?
I mean if anyone can create "evil" package stating it provide
-s specific virtual package (for which there is no repo anywhere), than they can specify whatever version they like. This could perhaps collide with other "good" packages, right?
Upvotes: 1
Views: 1033
Reputation: 70863
From my experience, this "virtual package" feature hasn't been widely used, and it definitely has its drawbacks due to the way it is currently implemented.
If you take a look at this search result on Packagist, you'll see the three top packages being psr/log
(the real interface package), psr/log
(a virtual package used by two other real packages, but in the wrong way) and psr/log-implementation
(used by plenty of packages, including monolog/monolog
).
This example illustrates that people will misunderstand this feature and do the wrong thing. You cannot provide psr/log
because that is a real package that has a real interface definition. It makes even less sense to require psr/log
and at the same time also provide it.
You also correctly spotted that there is no central entity that decides which versions of a virtual package should exist, let alone which virtual package names should exist. Which isn't that much of a problem because deciding on the names of real packages is done the same way: One developer thinks of a name, and that's all. It's unlikely that this procedure creates involuntary conflicts because usually the Github account name is used as the vendor name, and Github has already made them unique. Malicious conflicts don't really exist in the real world, as Jordi has pointed out in his blog, due to the general structure Composer uses to name packages.
Back to the virtual package feature: There are two blog postings discussing it.
The first explains using this feature with the example of the virtual psr/log-implementation
package mentioned above. I won't replicate that tutorial-like text here.
The second (linked and replied to at the end of the first) discusses what's bad about the whole approach of virtual packages.
Some of the points:
1) Strictly speaking (as in, would the code compile), the code from the library itself doesn't need a package that provides
psr/log-implementation
. It just needs theLoggerInterface
(which happens to be in thepsr/log
package).4)
psr/log-implementation
, or any virtual package for that matter, is very problematic as a package. There is no definition of this virtual package. [...]5) Some day, someone may decide to introduce another virtual package, called
the-real-psr/log-implementation
(they can easily do that, right?). Such packages may be completely exchangeable with existingpsr/log-implementation
packages, but in order to be useful, every existing PSR-3 compliant logger package needs to mention that virtual package too in their provide section. [...]
With all these problems and uncertainties existing for good packages, it is no surprise that they do not really use this feature very much.
However, you cannot abuse it for bad things in the way you outline it in your question. Yes, any package can declare that it provides any other package. But just like it happened with psr/log
, having a package declaring that it provides another package will not magically make everyone download that package. The way it works is a package declares that it provides another package, and by requiring this package, the virtual package also gets included and will fulfill any dependencies of other packages onto the virtual package.
But not requiring the package providing stuff will leave everything in it out of the equation.
In order to include bad software someone has to require
it. This is best done as an indirect dependency of an innocent looking library, and requires the help of an unsuspecting developer that actively pulls this code without properly reviewing it.
Which probably is my central point for everything: If you pull in someones code into your own project, make sure you understand what that code does by reviewing it (which isn't only about malicious things, but also basic code quality, because some day you may be forced to debug a problem), or make sure you can trust that source enough to not do bad things to you. However, your own code base is not affected by packages you do not require (the last bug with such an effect was handling replace
information, but I don't find that issue right now).
Upvotes: 3