Bug #80758 [Com]: version_compare does not behave as documented (or even consistently)
| From: | rtrtrtrtrt at dfdfdfdf dot dfd | Date: | Sun, 23 May 2021 07:04:13 +0000 |
| Subject: | Bug #80758 [Com]: version_compare does not behave as documented (or even consistently) | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-233991@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80758&edit=1
ID: 80758
Comment by: rtrtrtrtrt at dfdfdfdf dot dfd
Reported by: brad dot jorsch at automattic dot com
Summary: version_compare does not behave as documented (or
even consistently)
Status: Wont fix
Type: Bug
Package: *General Issues
Operating System: Linux
PHP Version: 8.0Git-2021-02-16 (Git)
Block user comment: N
Private report: N
New Comment:
at least the php ivory tower in that context is consistent with what counts as security bug :-)
Previous Comments:
------------------------------------------------------------------------
[2021-05-23 05:13:41] krakjoe@php.net
Does it sound right to you that because people mis-use a function, we should change how it works to
accommodate that misuse ?
We've been using the same versioning scheme forever, version_compare is intended to compare PHP
versions and nothing else.
There's no generally applicable version of this function that could work for everyone, and that
is not what we are trying to provide.
If version_compare doesn't work for your project, it's because it's not PHP, and
doesn't use PHP standardized strings.
------------------------------------------------------------------------
[2021-02-16 19:14:17] brad dot jorsch at automattic dot com
The following patch has been added/updated:
Patch Name: patch
Revision: 1613502857
URL: https://bugs.php.net/patch-display.php?bug=80758&patch=patch&revision=1613502857
------------------------------------------------------------------------
[2021-02-16 19:13:14] brad dot jorsch at automattic dot com
Description:
------------
While I marked the version as 8.0.2, this seems to exist in many versions, in some forms back to
4.3.0 or earlier.
The documentation for version_compare says that "any string not found in this list" comes
before various recognized strings, including numbers. But certain strings do not follow this
behavior.
1. Any non-alphanumeric character has that character treated as a
. rather than it
being included in the string to be compared. For example, "1.0-alpha 1" <
"1.0-alpha 2" because the space is considered a ., even though as documented
this should not be the case.
2. Exception: If that non-alphanumeric character comes directly after a number, it is not considered
as a .. So "1.0 alpha" == "1.0 beta" because neither "
alpha" nor " beta" are recognized as special strings. (see #75805)
3. Strings beginning with "a", "b", or other recognized strings are considered
as being those recognized strings. (see #75806)
4. An empty string as the last component compares as less than itself. This can combine with item 1
in unexpected ways. (see #69268, and https://stackoverflow.com/a/65118939)
IMO, item 1 makes sense and should be documented as such. Items 2 and 4 make no sense and should be
fixed. Item 3 could go either way, but since the documentation calls out "a" being the
same as "alpha" and so on that implies that "apple" should not be.
The attached patch fixes 2 and 4, and 3 with the interpretation that "apple" should not be
the same as "alpha". I'll leave documentation updates to you, since that's done
outside of the main repo.
P.S. I see cmb@php.net has a habit of closing reports like these as "not a bug" with the
justification that a "PHP-standardized version string" has some sort of meaning that
excludes these inputs. If you really want to continue considering this sort of thing "not a
bug", you should actually document a "PHP-standardized version string" as only
containing alphanumerics plus ., -, _, and +
somewhere, as currently that is not defined anywhere. You should also reject invalid strings with an
Error instead of silently handling them unexpectedly.
But IMO restricting this to only "PHP-standardized version strings" is going against how
most people actually use the method.
Test script:
---------------
var_dump( version_compare( "1.0 alpha", "1.0 beta" ) );
var_dump( version_compare( "1.0.apple", "1.0.coconut" ) );
var_dump( version_compare( "1.0.", "1.0." ) );
var_dump( version_compare( "1.0.*", "1.0.*" ) );
Expected result:
----------------
int(-1)
int(0)
int(0)
int(0)
Actual result:
--------------
int(0)
int(1)
int(-1)
int(-1)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80758&edit=1