Fix app fetcher php comparison to allow wider ranges

When app app specifies php 7.4 as upper limit we have to allow the
installation on php>7.4.0. The previous version check didn't do that.
This adjusts the regexes to discard any irrelevant suffix after the
three version numbers so that we can use more fine granular checks than
php's version_compare can do out of the box, like for php 7.4 we only
compare the major and minor version numbers and ignore the patch level.

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2021-01-26 16:35:43 +01:00 committed by backportbot[bot]
parent fbe893016f
commit 9010937535
2 changed files with 23 additions and 10 deletions

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> * @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
* *
@ -24,12 +27,13 @@
namespace OC\App; namespace OC\App;
use InvalidArgumentException; use InvalidArgumentException;
use function explode;
class CompareVersion { class CompareVersion {
public const REGEX_MAJOR = '/^\d+$/'; private const REGEX_MAJOR = '/^\d+$/';
public const REGEX_MAJOR_MINOR = '/^\d+.\d+$/'; private const REGEX_MAJOR_MINOR = '/^\d+\.\d+$/';
public const REGEX_MAJOR_MINOR_PATCH = '/^\d+.\d+.\d+$/'; private const REGEX_MAJOR_MINOR_PATCH = '/^\d+\.\d+\.\d+(?!\.\d+)/';
public const REGEX_SERVER = '/^\d+.\d+.\d+(.\d+)?$/'; private const REGEX_ACTUAL = '/^\d+(\.\d+){1,2}/';
/** /**
* Checks if the given server version fulfills the given (app) version requirements. * Checks if the given server version fulfills the given (app) version requirements.
@ -45,18 +49,19 @@ class CompareVersion {
*/ */
public function isCompatible(string $actual, string $required, public function isCompatible(string $actual, string $required,
string $comparator = '>='): bool { string $comparator = '>='): bool {
if (!preg_match(self::REGEX_SERVER, $actual)) { if (!preg_match(self::REGEX_ACTUAL, $actual, $matches)) {
throw new InvalidArgumentException('server version is invalid'); throw new InvalidArgumentException("version specification $actual is invalid");
} }
$cleanActual = $matches[0];
if (preg_match(self::REGEX_MAJOR, $required) === 1) { if (preg_match(self::REGEX_MAJOR, $required) === 1) {
return $this->compareMajor($actual, $required, $comparator); return $this->compareMajor($cleanActual, $required, $comparator);
} elseif (preg_match(self::REGEX_MAJOR_MINOR, $required) === 1) { } elseif (preg_match(self::REGEX_MAJOR_MINOR, $required) === 1) {
return $this->compareMajorMinor($actual, $required, $comparator); return $this->compareMajorMinor($cleanActual, $required, $comparator);
} elseif (preg_match(self::REGEX_MAJOR_MINOR_PATCH, $required) === 1) { } elseif (preg_match(self::REGEX_MAJOR_MINOR_PATCH, $required) === 1) {
return $this->compareMajorMinorPatch($actual, $required, $comparator); return $this->compareMajorMinorPatch($cleanActual, $required, $comparator);
} else { } else {
throw new InvalidArgumentException('required version is invalid'); throw new InvalidArgumentException("required version $required is invalid");
} }
} }

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> * @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
* *
@ -49,11 +51,17 @@ class CompareVersionTest extends TestCase {
['13.0.0', '13', '>=', true], ['13.0.0', '13', '>=', true],
['13.0.1', '13', '>=', true], ['13.0.1', '13', '>=', true],
['13.0.1', '13', '<=', true], ['13.0.1', '13', '<=', true],
['13.0.1.9', '13', '<=', true],
['13.0.1-beta.1', '13', '<=', true],
['7.4.14', '7.4', '<=', true],
['7.4.14-ubuntu', '7.4', '<=', true],
['7.4.14-ubuntu', '7.4.15', '<=', true],
// Incompatible major versions // Incompatible major versions
['13.0.0.3', '13.0.0', '<', false], ['13.0.0.3', '13.0.0', '<', false],
['12.0.0', '13.0.0', '>=', false], ['12.0.0', '13.0.0', '>=', false],
['12.0.0', '13.0', '>=', false], ['12.0.0', '13.0', '>=', false],
['12.0.0', '13', '>=', false], ['12.0.0', '13', '>=', false],
['7.4.15-ubuntu', '7.4.15', '>=', true],
// Incompatible minor and patch versions // Incompatible minor and patch versions
['13.0.0', '13.0.1', '>=', false], ['13.0.0', '13.0.1', '>=', false],
['13.0.0', '13.1', '>=', false], ['13.0.0', '13.1', '>=', false],