Skip to content

Version compare does not work properly with 2.10.0 #930

Description

@av-commits

Describe the bug
The update checking mechanism inside the package triggers a false update loop when running version 2.10.0. Even though version 2.10.0 is the exact same release as the latest version, the API endpoint incorrectly evaluates 2.10 as lower than 2.10.0 and returns "update_available": true.

To Reproduce
Steps to reproduce the behavior:

  1. Update to or install package version 2.10.0.
  2. Query the endpoint /api/v2/system/restapi/version.
  3. See that the response payload incorrectly states that an update is available ("update_available": true).

Expected behavior
When the local version is 2.10.0 and the latest release is 2.10.0, the system should recognize them as identical and return "update_available": false.

Screenshots or Response
The broken endpoint payload without manual code modifications looks like this:

{
  "current_version": "v2.10.0",
  "latest_version": "v2.10.0",
  "latest_version_release_date": "2026-08-08T01:08:52Z",
  "update_available": true,
  "available_versions": [
    "v2.10.0",
    "v2.9.0",
    "v2.8.4"
  ]
}

pfSense Version & Package Version:

  • pfSense Version: 2.8.1
  • Package Version: v2.10.0

Affected Endpoints:

  • URL: /api/v2/system/restapi/version

Additional context
The root cause is located in pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/RESTAPIVersion.inc on line 130:

version = strlen(version) === 3 ? version . '.0' : version;

Why it breaks:

  • This logic assumes single-digit minor versions (like 2.9), which have a length of exactly 3 characters, padding them to 2.9.0.
  • For version 2.10, the string length is 4 characters (2, ., 1, 0). The condition fails, and the version skips padding entirely inside this model step.
  • When "2.10" (unpadded) is compared against "2.10.0" on modern PHP engines (like PHP 8.3/8.5 runtimes), version_compare("2.10", "2.10.0", '<') evaluates to true because the missing patch node is treated as lower. This is what flips "update_available" to true.

Recommended Solution:
Instead of checking string length (strlen), count the number of dots (segments) using substr_count(). This ensures that double-digit versions like 2.10 are safely padded:

// Check if the version string contains only 1 dot (e.g., '2.9' or '2.10')
$version = substr_count($version, '.') === 1 ? $version . '.0' : $version;

*Relate Issue
php version_compare: php/php-src#20706

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions