1
0
Fork 0

Merge pull request #9312 from naderman/fix-solver-9012

Solver: Prevent infinite recursion in analyzeUnsolvableRule
pull/9317/head
Jordi Boggiano 2020-10-21 18:36:10 +02:00 committed by GitHub
commit 7cfb6dadf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 342 additions and 15 deletions

View File

@ -514,19 +514,19 @@ class Solver
return array($learnedLiterals[0], $ruleLevel, $newRule, $why);
}
/**
* @param Problem $problem
* @param Rule $conflictRule
*/
private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule)
private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule, array &$ruleSeen)
{
$why = spl_object_hash($conflictRule);
$ruleSeen[$why] = true;
if ($conflictRule->getType() == RuleSet::TYPE_LEARNED) {
$why = spl_object_hash($conflictRule);
$learnedWhy = $this->learnedWhy[$why];
$problemRules = $this->learnedPool[$learnedWhy];
foreach ($problemRules as $problemRule) {
$this->analyzeUnsolvableRule($problem, $problemRule);
if (!isset($ruleSeen[spl_object_hash($problemRule)])) {
$this->analyzeUnsolvableRule($problem, $problemRule, $ruleSeen);
}
}
return;
@ -550,7 +550,9 @@ class Solver
$problem = new Problem();
$problem->addRule($conflictRule);
$this->analyzeUnsolvableRule($problem, $conflictRule);
$ruleSeen = array();
$this->analyzeUnsolvableRule($problem, $conflictRule, $ruleSeen);
$this->problems[] = $problem;
@ -576,7 +578,7 @@ class Solver
$why = $decision[Decisions::DECISION_REASON];
$problem->addRule($why);
$this->analyzeUnsolvableRule($problem, $why);
$this->analyzeUnsolvableRule($problem, $why, $ruleSeen);
$literals = $why->getLiterals();

View File

@ -116,13 +116,13 @@ Your requirements could not be resolved to an installable set of packages.
Problem 1
- Conclusion: don't install friendsofphp/php-cs-fixer v2.10.5 (conflict analysis result)
- Conclusion: don't install symfony/console v3.4.29 (conflict analysis result)
- Conclusion: don't install symfony/console v2.8.8 (conflict analysis result)
- Conclusion: don't install symfony/console v3.4.28 (conflict analysis result)
- Root composer.json requires friendsofphp/php-cs-fixer * -> satisfiable by friendsofphp/php-cs-fixer[v2.10.4, v2.10.5].
- illuminate/queue v5.2.0 requires illuminate/console 5.2.* -> satisfiable by illuminate/console[v5.2.25, v5.2.26].
- illuminate/console v5.2.26 requires symfony/console 2.8.* -> satisfiable by symfony/console[v2.8.7, v2.8.8].
- Conclusion: don't install symfony/console v2.8.7 (conflict analysis result)
- Root composer.json requires friendsofphp/php-cs-fixer * -> satisfiable by friendsofphp/php-cs-fixer[v2.10.4, v2.10.5].
- Conclusion: don't install symfony/console v3.4.28 (conflict analysis result)
- Conclusion: don't install symfony/console v2.8.8 (conflict analysis result)
- Conclusion: don't install symfony/console v3.4.29 (conflict analysis result)
- Root composer.json requires illuminate/queue * -> satisfiable by illuminate/queue[v5.2.0].
- friendsofphp/php-cs-fixer v2.10.4 requires symfony/console ^3.2 || ^4.0 -> satisfiable by symfony/console[v3.2.13, ..., v3.4.29].
- You can only install one version of a package, so only one of these can be installed: symfony/console[v2.8.7, v2.8.8, v3.1.9, ..., v3.4.29].

View File

@ -0,0 +1,325 @@
--TEST--
See Github issue #9012 ( https://github.com/composer/composer/issues/9012 and https://gist.github.com/Seldaek/4e2dbc2cea4b4fd7a8207bb310ec8e34).
Recursive analysis of the same learnt rules can lead to infinite recursion in solver.
--COMPOSER--
{
"require": {
"php": ">=7.1.7",
"laravel/framework": "^6.0",
"nunomaduro/collision": "^4.0"
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true,
"process-timeout": 0
},
"repositories": {
"laravel/framework": {
"type": "package",
"package": [
{
"name": "laravel/framework",
"version": "v6.0.0",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.x-dev"
}
},
"require": {
"symfony/console": "^4.3.4"
}
}
]
},
"nunomaduro/collision": {
"type": "package",
"package": [
{
"name": "nunomaduro/collision",
"version": "v4.2.0",
"type": "library",
"extra": {
"laravel": {
"providers": [
"NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider"
]
}
},
"require": {
"symfony/console": "^5.0"
}
}
]
},
"symfony/console": {
"type": "package",
"package": [
{
"name": "symfony/console",
"version": "v5.1.7",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.6",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.5",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.4",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.3",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.2",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.0",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.0-RC2",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.0-RC1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.1.0-BETA1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.11",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.10",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.9",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.8",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.7",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.6",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.5",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.4",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.3",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.2",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v5.0.0",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.15",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.14",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.13",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.12",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.11",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.10",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.9",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.8",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.7",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.6",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.5",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.4",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.3",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.2",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.0",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.0-RC1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.0-BETA2",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.4.0-BETA1",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.11",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.10",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.9",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.8",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.7",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.6",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.5",
"type": "library"
},
{
"name": "symfony/console",
"version": "v4.3.4",
"type": "library"
}
]
}
}
}
--RUN--
update
--EXPECT--
--EXPECT-OUTPUT--
--EXPECT-EXIT-CODE--
2

View File

@ -37,9 +37,9 @@ Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Conclusion: don't install regular/pkg 1.0.3 (conflict analysis result)
- Conclusion: don't install regular/pkg 1.0.2 (conflict analysis result)
- Conclusion: don't install regular/pkg 1.0.1 (conflict analysis result)
- Conclusion: don't install regular/pkg 1.0.2 (conflict analysis result)
- Conclusion: don't install regular/pkg 1.0.3 (conflict analysis result)
- Only one of these can be installed: regular/pkg[1.0.0, 1.0.1, 1.0.2, 1.0.3], replacer/pkg[2.0.0, 2.0.1, 2.0.2, 2.0.3]. replacer/pkg replaces regular/pkg and thus cannot coexist with it.
- Root composer.json requires regular/pkg 1.* -> satisfiable by regular/pkg[1.0.0, 1.0.1, 1.0.2, 1.0.3].
- Root composer.json requires replacer/pkg 2.* -> satisfiable by replacer/pkg[2.0.0, 2.0.1, 2.0.2, 2.0.3].