Problem

Replace

Original Goal

Allow a fork to state that it is compatible with another package's API so that packages depending on the original are satisfied by the fork as well. Users may intentionally pick the fork, or if the original is poorly maintained the fork may be picked automatically.

Issue

People publish potentially malicious forks that replace commonly used libraries/frameworks. Users construct dependencies which make it impossible to install the original correctly. The solver decides to install the potentially malicious fork instead - users do not expect nor understand this and may not check the results of the update process because they trust composer too much.

Provides

Original Goal

Allow packages depend on a virtual package - a name which is not an actual package but merely represents an interface. There may then be multiple packages which are all treated equally which provide implementations of the same interface. The user may either pick one of the implementations directly with a require, or he may imply which one is to be used through another dependency.

Issue

If no provider is directly specified or specified through dependencies, it is randomly selected. Users may be ok with the initial choice, but they do not expect a change when running composer update to a potentially malicious package which also provides the same virtual package.

Proposed Solution

Only packages which match a dependency _by name_ (ignoring replaces/providers) or a dependency of any potential dependency identified recursively _by name_ will be considered for installation. The error reporting should further query for alternative replacers/providers which the user can require in the root package to satisfy the dependency. This is related to the improved error reporting utility necessary as a consequence of #2661

Consequences

Positive

  • We should see fewer users confused by the packages composer picks
  • Less potential for malicious packages to be installed if users run update automatically on CI or production (_HINT: DO NOT RUN COMPOSER UPDATE IN ANY AUTOMATED FASHION_)
  • We may be able to reduce the composer memory footprint and complexity on packagist as we no longer need a list of all providers/replacers for installation but only for error reporting

Negative

  • There may be situations in which Composer will now not be able to update anymore without explicit specification of a dependency, but this should be easy to understand for users. And explicity may even be helpful.