Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 0 additions & 68 deletions src/CheckVersionVulnerability.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@

declare(strict_types=1);

namespace Patchstack\VersionCompare;
namespace Patchstack\VersionCompare\Comparators;

final class NormalizeVersionPair
use Patchstack\VersionCompare\Contracts\VersionComparator;

/**
* Compares versions by treating each dot-separated segment as a decimal number.
*
* PHP's version_compare treats "3.5" < "3.41" (string comparison: "5" < "41").
* This comparator right-pads segments so "3.5" becomes "3.50", making 3.50 > 3.41.
*/
final class DecimalComparator implements VersionComparator
{
public function compare(string $version1, string $version2, string $operator): bool
{
[$version1, $version2] = $this->padSegments($version1, $version2);

return version_compare($version1, $version2, $operator);
}

/**
* Normalize two version strings by right-padding numeric segments to equal length.
*
* This ensures decimal-style versioning compares correctly:
* e.g., "3.5" vs "3.41" becomes "3.50" vs "3.41".
*
* @return array{string, string}
*/
public function execute(string $version1, string $version2): array
private function padSegments(string $version1, string $version2): array
{
$segments1 = explode('.', $version1);
$segments2 = explode('.', $version2);
Expand Down
15 changes: 15 additions & 0 deletions src/Comparators/StandardComparator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Patchstack\VersionCompare\Comparators;

use Patchstack\VersionCompare\Contracts\VersionComparator;

final class StandardComparator implements VersionComparator
{
public function compare(string $version1, string $version2, string $operator): bool
{
return version_compare($version1, $version2, $operator);
}
}
19 changes: 0 additions & 19 deletions src/CompareVersions.php

This file was deleted.

10 changes: 10 additions & 0 deletions src/Contracts/VersionComparator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Patchstack\VersionCompare\Contracts;

interface VersionComparator
{
public function compare(string $version1, string $version2, string $operator): bool;
}
21 changes: 21 additions & 0 deletions src/Contracts/VersionNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Patchstack\VersionCompare\Contracts;

interface VersionNormalizer
{
/**
* Clean a version string for comparison (strip prefixes, lowercase, trim).
*/
public function normalize(string $version): string;

/**
* Check if two versions can be meaningfully compared.
*
* For example, Drupal versions with different major prefixes (8.x vs 9.x)
* are never vulnerable to each other. Called with raw (pre-normalized) strings.
*/
public function areCompatible(string $version1, string $version2): bool;
}
81 changes: 0 additions & 81 deletions src/Drupal/CheckDrupalVersionVulnerability.php

This file was deleted.

39 changes: 0 additions & 39 deletions src/Drupal/DrupalVersionNormalizer.php

This file was deleted.

40 changes: 40 additions & 0 deletions src/Normalizers/DrupalNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Patchstack\VersionCompare\Normalizers;

use Patchstack\VersionCompare\Contracts\VersionNormalizer;

final class DrupalNormalizer implements VersionNormalizer
{
public function normalize(string $version): string
{
$version = strtolower(trim($version));

if (str_starts_with($version, 'v')) {
$version = substr($version, 1);
}

return preg_replace('/([0-9]*\.x)-/m', '', $version);
}

/**
* Drupal versions with different major prefixes (8.x vs 9.x) are incompatible.
*/
public function areCompatible(string $version1, string $version2): bool
{
if (stripos($version1, 'x') === false || stripos($version2, 'x') === false) {
return true;
}

preg_match_all('/([0-9]*\.x)-/m', $version1, $matches1);
preg_match_all('/([0-9]*\.x)-/m', $version2, $matches2);

if (count($matches1[0]) > 0 && count($matches2[0]) > 0 && $matches1[1][0] !== $matches2[1][0]) {
return false;
}

return true;
}
}
26 changes: 26 additions & 0 deletions src/Normalizers/GenericNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Patchstack\VersionCompare\Normalizers;

use Patchstack\VersionCompare\Contracts\VersionNormalizer;

final class GenericNormalizer implements VersionNormalizer
{
public function normalize(string $version): string
{
$version = strtolower(trim($version));

if (str_starts_with($version, 'v')) {
$version = substr($version, 1);
}

return $version;
}

public function areCompatible(string $version1, string $version2): bool
{
return true;
}
}
12 changes: 12 additions & 0 deletions src/VersionStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace Patchstack\VersionCompare;

use Patchstack\VersionCompare\Comparators\DecimalComparator;
use Patchstack\VersionCompare\Comparators\StandardComparator;
use Patchstack\VersionCompare\Contracts\VersionComparator;

enum VersionStrategy: string
{
case Standard = 'standard';
Expand All @@ -15,4 +19,12 @@ public static function fromAbnormalFlag(bool $abnormalVersion): self
? self::DecimalNormalized
: self::Standard;
}

public function comparator(): VersionComparator
{
return match ($this) {
self::Standard => new StandardComparator(),
self::DecimalNormalized => new DecimalComparator(),
};
}
}
Loading
Loading