From 9b8e961c0cf3efd71a83c4658cc32a64f9bbf9a4 Mon Sep 17 00:00:00 2001 From: Max Bittman Date: Fri, 22 Mar 2019 12:11:45 -0700 Subject: [PATCH] fix: Fix non-satisfiable ranges so they no longer intersect with anything --- semver.js | 22 ++++++++++++++++++++-- test/index.js | 8 ++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/semver.js b/semver.js index a0a96c1b..1c3c4f96 100644 --- a/semver.js +++ b/semver.js @@ -935,8 +935,8 @@ Range.prototype.intersects = function (range, options) { return this.set.some(function (thisComparators) { return range.set.some(function (rangeComparators) { - return thisComparators.every(function (thisComparator) { - return rangeComparators.every(function (rangeComparator) { + return isSatisfiable(thisComparators, options) && thisComparators.every(function (thisComparator) { + return isSatisfiable(rangeComparators, options) && rangeComparators.every(function (rangeComparator) { return thisComparator.intersects(rangeComparator, options) }) }) @@ -944,6 +944,24 @@ Range.prototype.intersects = function (range, options) { }) } +// take a set of comparators and determine whether there +// exists a version which can satisfy it +function isSatisfiable (comparators, options) { + var result = true + var remainingComparators = comparators.slice() + var testComparator = remainingComparators.pop() + + while (result && remainingComparators.length) { + result = remainingComparators.every(function (otherComparator) { + return testComparator.intersects(otherComparator, options) + }) + + testComparator = remainingComparators.pop() + } + + return result +} + // Mostly just for testing and legacy API reasons exports.toComparators = toComparators function toComparators (range, options) { diff --git a/test/index.js b/test/index.js index 56c13570..4922730d 100644 --- a/test/index.js +++ b/test/index.js @@ -875,7 +875,8 @@ test('missing comparator parameter in intersect comparators', function (t) { test('ranges intersect', function (t) { [ ['1.3.0 || <1.0.0 >2.0.0', '1.3.0 || <1.0.0 >2.0.0', true], - ['<1.0.0 >2.0.0', '>0.0.0', true], + ['<1.0.0 >2.0.0', '>0.0.0', false], + ['>0.0.0', '<1.0.0 >2.0.0', false], ['<1.0.0 >2.0.0', '>1.4.0 <1.6.0', false], ['<1.0.0 >2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false], ['>1.0.0 <=2.0.0', '2.0.0', true], @@ -883,7 +884,10 @@ test('ranges intersect', function (t) { ['<1.0.0 >=2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false], ['1.5.x', '<1.5.0 || >=1.6.0', false], ['<1.5.0 || >=1.6.0', '1.5.x', false], - ['<1.6.16 || >=1.7.0 <1.7.11 || >=1.8.0 <1.8.2', '>=1.6.16 <1.7.0 || >=1.7.11 <1.8.0 || >=1.8.2', false] + ['<1.6.16 || >=1.7.0 <1.7.11 || >=1.8.0 <1.8.2', '>=1.6.16 <1.7.0 || >=1.7.11 <1.8.0 || >=1.8.2', false], + ['<=1.6.16 || >=1.7.0 <1.7.11 || >=1.8.0 <1.8.2', '>=1.6.16 <1.7.0 || >=1.7.11 <1.8.0 || >=1.8.2', true], + ['>=1.0.0', '<=1.0.0', true], + ['>1.0.0 <1.0.0', '<=0.0.0', false] ].forEach(function (v) { var range1 = new Range(v[0]) var range2 = new Range(v[1])