Repository: google/osv.dev

Issue:
Packagist version enumeration is incorrect
Since #675 was landed we're now seeing some false positives in `osv-detector` due to the `versions` field seemingly holding wrong versions.

Some examples that I've looked into specifically:
  * https://api.osv.dev/v1/vulns/GHSA-vxrc-68xx-x48g has all of the v2.x versions listed in `affected[0].versions`, even though that `affected` says its `fixed` in version `1.38.0`. (it's also missing `affected[1].versions` which doesn't seem right?
  * https://api.osv.dev/v1/vulns/GHSA-77mr-wc79-m8j3 has v6.5+ versions listed in `affected[0].versions`, even though that `affected` says `fixed` in version `6.5.0`.
  * https://api.osv.dev/v1/vulns/GHSA-q348-f93x-9gx4 has v2.2.11+ versions listed in `affected[0].versions`, even though that `affected` says `fixed` in version `2.2.11`.

And here are some outputs from `osv-detector` which have some more examples:
```
phpmailer/phpmailer@v6.6.3:
  GHSA-77mr-wc79-m8j3: A validation function with the same name as a built-in validator can be called (https://github.com/advisories/GHSA-77mr-wc79-m8j3)
  GHSA-7q44-r25x-wm4q: Remote Code Execution vulnerability in PHPMailer 6.4.1 running on Windows (https://github.com/advisories/GHSA-7q44-r25x-wm4q)
  GHSA-f7hx-fqxw-rvvj: Insufficient output escaping of attachment names in PHPMailer (https://github.com/advisories/GHSA-f7hx-fqxw-rvvj)
  GHSA-v5c9-mmw9-829q: PHPMailer susceptible to arbitrary code execution (https://github.com/advisories/GHSA-v5c9-mmw9-829q)

twig/twig@v2.15.1:
  GHSA-vxrc-68xx-x48g: Sandbox Information Disclosure (https://github.com/advisories/GHSA-vxrc-68xx-x48g)

zendesk/zendesk_api_client_php@v2.2.14:
  GHSA-q348-f93x-9gx4: Lack of Input Validation in zendesk_api_client_php for Zendesk Subdomain (https://github.com/advisories/GHSA-q348-f93x-9gx4)

laravel/framework@v8.83.17:
  GHSA-3p32-j457-pg5x: Query Binding Exploitation (https://github.com/advisories/GHSA-3p32-j457-pg5x)
  GHSA-4mg9-vhxq-vm7j: SQL Server LIMIT / OFFSET SQL Injection in laravel/framework and illuminate/database (https://github.com/advisories/GHSA-4mg9-vhxq-vm7j)
  GHSA-66hf-2p6w-jqfw: Laravel Framework XSS in Blade templating engine (https://github.com/advisories/GHSA-66hf-2p6w-jqfw)
  GHSA-w2pm-r78h-4m7v: OS Command Injection in Laravel Framework (https://github.com/advisories/GHSA-w2pm-r78h-4m7v)
  GHSA-w68r-5p45-5rqp: Improper Input Validation in Laravel (https://github.com/advisories/GHSA-w68r-5p45-5rqp)
  GHSA-x7p5-p2c9-phvg: Unexpected database bindings (https://github.com/advisories/GHSA-x7p5-p2c9-phvg)
```


Discussion:
Thanks for the report! @another-rex could you please take a look? 
Maybe this has something to do with comparing versions that are prefixed with a 'v' and versions that aren't. 

There's none in our testcases: https://github.com/google/osv.dev/blob/master/osv/testdata/packagist_test_cases.txt

The [spec](https://getcomposer.org/doc/articles/versions.md#tags) says:

> (Note that Composer automatically removes the 'v' prefix in the actual tagname to get a valid final version number.)

Resolving patch:
diff --git a/osv/packagist_version.py b/osv/packagist_version.py
--- a/osv/packagist_version.py
+++ b/osv/packagist_version.py
@@ -130,6 +130,8 @@ def php_canonicalize_version(version: str) -> str:
     Replaces special separators (`-`,`_`,`+`) with `.`, and inserts `.`
     between any digit and non-digit.
     """
+    if version.startswith('v'):
+      version = version[1:]
     replaced = re.sub('[-_+]', '.', version)
     replaced = re.sub(r'([^\d.])(\d)', r'\1.\2', replaced)
     replaced = re.sub(r'(\d)([^\d.])', r'\1.\2', replaced)


Test patch:
diff --git a/osv/testdata/packagist_test_cases.txt b/osv/testdata/packagist_test_cases.txt
--- a/osv/testdata/packagist_test_cases.txt
+++ b/osv/testdata/packagist_test_cases.txt
@@ -53,6 +53,27 @@
 1.0pl1 > 1.0
 1.0pl1 = 1.0pl1
 
+v1.0pl1 > 1.0-dev
+v1.0pl1 > 1.0a1
+v1.0pl1 > 1.0b1
+v1.0pl1 > 1.0RC1
+v1.0pl1 > 1.0rc1
+v1.0pl1 > 1.0
+v1.0pl1 = 1.0pl1
+
+v1.0pl1 > v1.0-dev
+v1.0pl1 > v1.0a1
+v1.0pl1 > v1.0b1
+v1.0pl1 > v1.0RC1
+v1.0pl1 > v1.0rc1
+v1.0pl1 > v1.0
+v1.0pl1 = v1.0pl1
+
+v1 < 2
+v10 > 2
+v1.0 < 1.1
+v1.2 > 1.0.1
+
 // From https://github.com/composer/semver/blob/main/tests/ComparatorTest.php
 1.25.0 < 1.26.0
 1.0.0 < 1.2-dev