GithubHelp home page GithubHelp logo

nexb / univers Goto Github PK

View Code? Open in Web Editor NEW
28.0 11.0 9.0 3.77 MB

Parse and compare all the package versions and all the ranges. From debian, npm, pypi, ruby and more. Process all the version range specs and expressions. This project is sponsored by an NLnet project https://nlnet.nl/project/vulnerabilitydatabase/ , the Google Summer of Code, nexB and others generous sponsors!

Batchfile 1.20% Python 96.60% Shell 1.49% Nix 0.42% Makefile 0.28%
purl package-url versioning package-manager dependencies dependency-resolver osv version vulnerabilities vulnerablecode

univers's Introduction

univers: mostly universal version and version ranges comparison and conversion

Build Status License Python 3.6+

univers was born out of the need for a mostly universal way to store version ranges and to compare two software package versions in VulnerableCode.

Package version ranges and version constraints are useful and essential:

  • When relating a known vulnerability or bug to a range of affected package versions. For instance a statement such as "vulnerability 123 affects package bar, version 3.1 and version 4.2 but not version 5" defines a range of bar versions affected by a vulnerability.
  • When resolving the dependencies of a package to express which subset of the versions are supported. For instance a dependency requirement statement such as "I require package foo, version 2.0 and later versions" defines a range of acceptable foo versions.

Version syntaxes and range notations are quite different across ecosystems, making it is difficult to process versions and version ranges across ecosystems in a consistent way.

Existing tools and libraries typically support a single algorithms to parse and compare versions with a single version range notation for a single package ecosystem.

univers is different:

  • It tracks each ecosystem versioning scheme and how two versions are compared.
  • It support a growing number of package ecosystems versioning in a single library.
  • It can parse version range strings using their native notation (such as an npm range) into the common "vers" notation and internal object model and can return back a native version range string rebuilt from a "vers" range.
  • It is designed to work with Package URLs (purl).

How does univers work ?

univers wraps, embeds and implements multiple version comparison libraries, each focused on a specific ecosystem versioning scheme.

For each scheme, univers provides an implementation for:

  • the version comparison procedure e.g, how to compare two versions,
  • parsing and converting from a native version range notation to the univers normalized and unified internal model,
  • converting a range back to its scheme-native range syntax and to the vers syntax.

univers implements vers, an experimental unified and mostly universal version range syntax. It can parse and convert an existing native version range strings to this unified syntax. For example, this means:

  • converting ">=1.2.3" as used in a Python package into vers:pypi/>=1.2.3,
  • or converting "^1.0.2" as used in an npm package dependency declaration into vers:npm/>=1.0.2|<2.0.0

The supported package ecosystems versioning schemes and underlying libraries include:

  • npm that use the "node-semver" ranges notation and the semver versions syntax This is supported in part by the semantic_version library.
  • pypi: handled by Python's packaging library and the standard packaging.version module.
  • Rubygems which use a semver-like but not-quite-semver scheme and there can be commonly more than three version segments. Gems also use a slightly different range notation from node-semver with different operators and slightly different semantics: for instance it uses "~>" as a pessimistic operator and supports exclusion with != and does not support "OR" between constraints (that it call requirements). Gem are handled by Python port of the Rubygems requirements and version handling code from the puppeteer tool
  • debian: handled by the debian-inspector library.
  • maven: handled by the embedded pymaven library.
  • rpm: handled by the embedded rpm_vercmp library.
  • golang (using semver)
  • PHP composer
  • ebuild/gentoo: handled by the embedded gentoo_vercmp module.
  • arch linux: handled by the embedded arch utility module borrowed from msys2.
  • Alpine linux: handled using the base Gentoo version support and extras specific to Alpine.

The level of support for each ecosystem may not be even for now and new schemes and support for more package types are implemented on a continuous basis.

Alternative

Rather than using ecosystem-specific version schemes and code, another approach is to use a single procedure for all the versions as implemented in libversion. libversion works in the most common case but may not work correctly when a task that demand precise version comparisons such as for dependency resolution and vulnerability lookup where a "good enough" comparison accuracy is not acceptable. libversion does not handle version range notations.

Installation

$ pip install univers

Examples

Compare two native Python versions:

from univers.versions import PypiVersion
assert PypiVersion("1.2.3") < PypiVersion("1.2.4")

Normalize a version range from an npm:

from univers.version_range import NpmVersionRange
range = NpmVersionRange.from_native("^1.0.2")
assert str(range) == "vers:npm/>=1.0.2|<2.0.0"

Test if a version is within or outside a version range:

from univers.versions import PypiVersion
from univers.version_range import VersionRange

range = VersionRange.from_string("vers:pypi/>=1.2.4")

assert PypiVersion("1.2.4") in range
assert PypiVersion("1.2.3") not in range

Development

Run these commands, starting from a git clone of https://github.com/nexB/univers

$ ./configure --dev
$ source venv/bin/active
$ pytest -vvs

We use the same development process as other AboutCode projects.

Visit https://github.com/nexB/univers and https://gitter.im/aboutcode-org/vulnerablecode and https://gitter.im/aboutcode-org/aboutcode for support and chat.

Primary license: Apache-2.0 SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause AND MIT

univers's People

Contributors

analogrelay avatar ayansinhamahapatra avatar bronzdoc avatar bundlerbot avatar chinyeungli avatar commod0re avatar deivid-rodriguez avatar drbrain avatar emgarten avatar evanphx avatar homu avatar hritik14 avatar hsbt avatar indirect avatar johnmhoran avatar jonoyang avatar keshav-space avatar lasote avatar memsharded avatar nobu avatar pmatilai avatar pombredanne avatar radhermit avatar sbs2001 avatar segiddins avatar steven-esser avatar tg1999 avatar wfscheper avatar xolox avatar zenspider avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

univers's Issues

Difference in GitHub and Gitlab version ranges

github and gitlab both provide different VulnerableRange format for Maven, While Github provides something like this >= 2.13.0, < 2.16.0 , Gitlab provides something like this (,1.7]
Other than that, our current GemVersionRange fails for the Gitlab format of gem vulnerableRanges >=3.0.0 <4.2.11.1||>=5.0.0 <5.0.7.2||>=5.1.0 <5.1.6.2||>=5.2.0 <5.2.2.1 , but it works fine with GitHub version Ranges

version string representation is missing type information

>>> from univers.versions import SemverVersion
>>> SemverVersion("2.0.0")
SemverVersion(string='2.0.0')
>>> str(SemverVersion("2.0.0"))
'2.0.0'

After converting a Version to string, it is impossible to switch back as the type (SemverVersion) information is lost. This will cause problems when saving and retrieving versions from a database.

One possible solution is to store the class name SemverVersion and the string representation both in the database.
Even so, would it make sense to have a vers like (but tiny) specification for versions ?
It could be something along the lines

ver:SemverVersion/2.0.0

I'm not even sure if this representation is required at all, comments please.

prerelease inside the build??

"scheme": "packagist",
"gitlab_native": "<2.0.12.1||>=2.0.13.0alpha,<2.0.13.2||>=2.0.14.0alpha,<2.0.15",
"expected_vers": "vers:composer/<2.0.12+1|>=2.0.13+0alpha|<2.0.13+2|>=2.0.14+0alpha|<2.0.15"

How did we end up with prerelease inside the build?
We are using Semver for Composer and 2.0.13+0alpha isn't Semver.
Am I missing something?

Cannot convert VersionSpecifier to canonical representation and back

The offending code is:

def __str__(self):
"""
Return the canonical representation.
"""
ranges = ",".join(self.ranges)
return f"{self.scheme}:{ranges}"

Further
self.ranges is a VersionRange object and is converted to str by the following block

def __str__(self):
return f"{self.operator}{self.version}"

the self.version is of type BaseVersion and is converted to str by

def __str__(self):
return f"{self.scheme}:{self.version_string}"

Which yields a string like
<=semver:1.20.0,>=semver:0.6.18 with multiple schemes which is incompatible to be converted back via

def from_version_spec_string(cls, version_spec_string):
"""
Return a VersionSpecifier built from a version spec string, prefixed by
a scheme such as "semver:1.2.3,>=2.0.0"
"""

Possible [dirty] fix:

        ranges = ",".join([f"{rng.operator}{rng.version.value}" for rng in self.version_specifier.ranges])
        return f"{self.scheme}:{ranges}"

VersionRange.constraints are not an iterable of an iterable

Commit 80b515a changes how constraints are populated.
This messes up with the assumption that constraints are an iterable of iterables (here, list, in future - tuple).

# A list of lists of VersionConstraint that are signposts on the versions
# timeline
constraints = attr.ib(type=list, default=attr.Factory(list))

Commit: 80b515a

-        # parse_constraints
-        version_constraints = []
-        for or_constraints in constraints.split("|"):
-            and_constraints = []
-            for constraint in or_constraints.split(","):
-                constraint = VersionConstraint.from_string(
-                    string=constraint,
-                    version_class=range_class.version_class,
-                )
-                and_constraints.append(constraint)
-            version_constraints.append(and_constraints)
+        # There is only one star: "*" must only occur once and alone in a range,
+        # without any other constraint or version.
+        if constraints.startswith("*"):
+            if constraints != "*":
+                raise ValueError(f"{vers!r} contains an invalid '*' constraint.")
+            return range_class([VersionConstraint.from_string(string="*", version_class=None)])
+
+        parsed_constraints = []
+
+        constraints = constraints.strip("|")
+        for const in constraints.split("|"):
+            constraint = VersionConstraint.from_string(
+                string=const,
+                version_class=version_class,
+            )
+            parsed_constraints.append(constraint)

Handle possible duplication of constraints in VersionRange

Eliminate the possibility of constraints duplication in VersionRange and add some tests to validate the same.

>>> from univers.version_range import NginxVersionRange
>>> range=NginxVersionRange.from_native("1.5.0+, 1.4.1+, 1.4.0+")
>>> str(range)
'vers:nginx/>=1.4.0|>=1.4.1|<1.5.0|<1.5.0|>=1.5.0'

Context: #42 (comment)

Semver 2.0 != 2.0.0 and 2.0.0.0 is valid

Code docs say

class SemverVersion(Version):
"""
Strict semver v2.0 with 3 segments.
"""

Even so, semver with more than 3 segments is treated as valid. This looks like an issue on the semantic_version side but we should not make false promises.

>>> from univers.versions import SemverVersion
>>> SemverVersion.is_valid("2")
True
>>> SemverVersion.is_valid("2.0")
True
>>> SemverVersion.is_valid("2.0.0")
True
>>> SemverVersion.is_valid("2.0.0.0")
True
>>> SemverVersion.is_valid("2.0.0.0.1")
True
>>> SemverVersion("2") == SemverVersion("2.0")
False
>>> SemverVersion("2.0.0") == SemverVersion("2.0")
False

Unsupported Alpine versions

From running VulnerableCode, we have some issues with these versions that should be supported:

'0.8.21.r2' is not a valid AlpineVersion InvalidVersion("'0.8.21.r2' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'10.2.22.r0' is not a valid AlpineVersion InvalidVersion("'10.2.22.r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'10.2.24.r0' is not a valid AlpineVersion InvalidVersion("'10.2.24.r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'1.0.4.-r0' is not a valid AlpineVersion InvalidVersion("'1.0.4.-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'1.11-20-r0' is not a valid AlpineVersion InvalidVersion("'1.11-20-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'1.18.-r2' is not a valid AlpineVersion InvalidVersion("'1.18.-r2' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'1.7.5.-r1' is not a valid AlpineVersion InvalidVersion("'1.7.5.-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'1.9.5p2-r0' is not a valid AlpineVersion InvalidVersion("'1.9.5p2-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'2.15.r-r1' is not a valid AlpineVersion InvalidVersion("'2.15.r-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'3.3.3p1-r3' is not a valid AlpineVersion InvalidVersion("'3.3.3p1-r3' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'4.10-1-r1' is not a valid AlpineVersion InvalidVersion("'4.10-1-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'4.8.0.-r1' is not a valid AlpineVersion InvalidVersion("'4.8.0.-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20200401-r0' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20200401-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r0' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r1' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r2' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r2' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r3' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r3' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r4' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r4' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r5' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r5' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20210510-r6' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20210510-r6' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211006-r0' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211006-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211006-r1' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211006-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211006-r3' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211006-r3' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211112-r0' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211112-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211112-r1' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211112-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211127-r0' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211127-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211127-r1' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211127-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211127-r2' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211127-r2' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211127-r3' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211127-r3' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20211127-r4' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20211127-r4' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'5.15.3_git20220121-r4' is not a valid AlpineVersion InvalidVersion("'5.15.3_git20220121-r4' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'57-1-r2' is not a valid AlpineVersion InvalidVersion("'57-1-r2' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'6.6.2p1-r0' is not a valid AlpineVersion InvalidVersion("'6.6.2p1-r0' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'6.6.4p1-r1' is not a valid AlpineVersion InvalidVersion("'6.6.4p1-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'6.6.4p1-r2' is not a valid AlpineVersion InvalidVersion("'6.6.4p1-r2' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")
'6.7.1p1-r1' is not a valid AlpineVersion InvalidVersion("'6.7.1p1-r1' is not a valid <class 'univers.versions.AlpineLinuxVersion'>")

`PyPiVersionRange.from_native` not working

def from_native(cls, string):
"""
Return a VersionRange built from a PyPI PEP440 version specifiers ``string``.
"""

and PEP 440 shows an example for version specifier as follows:

~= 0.9, >= 1.0, != 1.3.4.*, < 2.0

See: https://www.python.org/dev/peps/pep-0440/#version-specifiers

Let's try:

>>> from univers.version_range import PypiVersionRange
>>> rng_from_native = PypiVersionRange.from_native("~= 0.9, >= 1.0, != 1.3.4.*, < 2.0")
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-22-af3412ff72fa> in <module>
----> 1 rng_from_native = PypiVersionRange.from_native("~= 0.9, >= 1.0, != 1.3.4.*, < 2.0")

~/Contrib/univers/src/univers/version_range.py in from_native(cls, string)
    514             operator = spec.operator
    515             version = spec.version
--> 516             assert isinstance(version, cls.version_class)
    517             comparator = cls.vers_by_native_comparators[operator]
    518             constraint = VersionConstraint(comparator=comparator, version=version)

AssertionError:

Something is not right

`NpmVersionRange.from_native` isn't returning constraints as intended

Running the NpmVersionRange example mentioned in Readme.rst results in an error

>>> from univers.version_range import NpmVersionRange
>>> range = NpmVersionRange.from_native("^1.0.2")
>>> assert str(range) == "vers:npm/>=1.0.2|<2.0.0"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>>

Converting object to string gives:

>>> str(range)
"vers:npm/[VersionConstraint(comparator='>=', version=SemverVersion(string='1.0.2')), VersionConstraint(comparator='<', version=SemverVersion(string='2.0.0'))]"
>>>

Version in VerisonRange`"vers:nginx/*` crashes for every version

>>> SemverVersion("1.0.0") in VersionRange.from_string("vers:nginx/*")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-b59bd155f0a0> in <module>
----> 1 SemverVersion("1.0.0") in VersionRange.from_string("vers:nginx/*")

~/Contrib/univers/src/univers/version_range.py in __contains__(self, version)
    159                 f"{version!r} is not of expected type: {self.version_class!r}",
    160             )
--> 161         return contains_version(version, self.constraints)
    162
    163     contains = __contains__

~/Contrib/univers/src/univers/version_constraint.py in contains_version(version, constraints)
    443     # Check is finished.
    444     if len(constraints) == 1:
--> 445         return version in constraints[0]
    446
    447     # If the "tested version" is equal to the any of the constraint version where

~/Contrib/univers/src/univers/version_constraint.py in __contains__(self, version)
    213
    214         if not isinstance(version, self.version.__class__):
--> 215             raise ValueError(
    216                 f"Cannot compare {version.__class__!r} instance "
    217                 f"with {self.version.__class__!r} instance."

ValueError: Cannot compare <class 'univers.versions.SemverVersion'> instance with <class 'NoneType'> instance.

Naming: VersionSpecifier and VersionRange

Range resonates with the concept of interval which can be said to be

an interval is a group of numbers that includes all numbers between the beginning and the end

In my understanding, a VersionRange object does not contain both the bounds for a range

class VersionRange:
# one of <> >= =< or != or =
operator = ""
version = None

A VersionSpecifier does come with multiple VersionRanges and might work for upper-lower bounds but that would require to treat the ranges inside a VersionSpecifier with a mathematical intersection, which doesn't make a lot of sense right now.

For eg: An intersection of semver:1.2.3,>=2.0.0 doesn't quite make sense.
Their union, though, is useful but then we are left without any upper-lower bound range.

Please correct me if I am wrong. Also, it would greatly help if you could add documentation for the exposed classes (like VersionSpecifier, VersionRange etc)

Inconsistent use of `attr` parameter and `__eq__` in VersionConstraint

For __eq__ method to take effect, eq=False must be added as a attr parameter

def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return self.comparator == other.comparator and self.version == other.version

Something like this:

@attr.s(frozen=True, repr=True, str=False, order=False, eq=False, hash=True) 

Current attr paramaters:

@attr.s(frozen=True, repr=True, str=False, order=False, eq=True, hash=True)
class VersionConstraint:

NginxVersionRange from_native and from_string generating different VersionRange

>>> from univers.version_range import NginxVersionRange
>>> rng_from_native = NginxVersionRange.from_native("1.9.5-1.17.2")
>>> rng_from_string = NginxVersionRange.from_string(rng_from_native.to_string())
>>>
>>> assert rng_from_native == rng_from_string
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-65-c0fc3fe00843> in <module>
----> 1 assert rng_from_native == rng_from_string

AssertionError:
>>>
>>> rng_from_native.to_string()
'vers:nginx/>=1.9.5|<=1.17.2'
>>> rng_from_string.to_string()
'vers:nginx/>=1.9.5|<=1.17.2'


>>> rng_from_native
NginxVersionRange(constraints=(VersionConstraint(comparator='>=', version=Version('1.9.5')), VersionConstraint(comparator='<=', version=Version('1.17.2'))))

>>> rng_from_string
NginxVersionRange(constraints=(VersionConstraint(comparator='>=', version=SemverVersion(string='1.9.5')), VersionConstraint(comparator='<=', version=SemverVersion(string='1.17.2'))))
>>>

`VersionConstraint.version` is allowed to be `None`

Is is more of a design decision than an issue.

Let's consider that in a place far far away, someone writes a piece code to get versions from all the constraints:

>>> vr = VersionRange.from_string("vers:npm/1.1|2.2")
>>> range_versions = [c.version for c in vr.constraints]
>>> range_versions
[SemverVersion(string='1.1'), SemverVersion(string='2.2')]

Everything is nice and good until we meet vers:ANY/*

>>> vr = VersionRange.from_string("vers:npm/*")
>>> range_versions = [c.version for c in vr.constraints]
>>> range_versions
[None]

Suddenly, range_versions break all expectations and contains a value value of NoneType than Version
A possible fix would be to allow None versions, such as Version(None)

Introduced here:

version = attr.ib(type=Version, default=None)

Related:
#10
#19

Unsupported Gitlab version ranges

Provide support for following

  • rubygem
  • npm
  • pypi

rubygem

'<3.4.1||>=4.3.0 <4.3.1'
'>=4.0.0 <4.1.2'
'<3.4.0||>=4.0.0 <4.1.2'
'<3.4.0||>=4.0.0 <4.1.2'
'>=1.0.0-alpha0 <1.1.1'
'<1.4.3||>=2.0.0 <2.0.2'
'<=3.6.2||>=3.7.0 <=3.7.3||>=3.8.0 <=3.8.3'
'>=1.10.0a <1.10.1||>=1.11.0a <1.11.2||>=1.12.0a <1.12.0'
'<1.0.1||>=1.1.0.alpha0 <1.1.2||>=1.2.0.alpha0 <1.2.1.1||>=1.3.0.alpha0 <1.3.1||1.4.0.beta.1'
'<1.0.1||>=1.1.0 <1.1.2||1.2.0||1.3.0||1.4.0.beta.1'
'>=1.2.0.alpha0 <1.2.2||>=1.3.0.alpha0 <1.3.2'
'>=1.11.0a <1.11.4||>=1.12.0a <1.12.2||>=1.13.0a <1.13.12||>=2.0.0a <2.0.3||>=2.1.0a <2.1.2||>=2.2.0a <2.2.1'
'>=1.0.13 <=1.0.14||=0.1.4'
'>=0.7.0 <0.9.13'
'>=0.3.0 <0.3.1||>=0.2.0 <0.2.1||<0.1.1'
'<=0.1.0||>0.2.0 <0.3.1'
'>=0.1.0 <=0.3.0'
'>=1.2.6 <1.2.8'
'>=1.0.0 <1.1.4'
'<1.12.3||>2.0.0a <3.0.4'
'>=1.16.0 <2.2.16'
'>=5.0.0 <5.0.3||>=5.1.0 <5.1.1||>=5.2.0 <5.2.5||>=5.3.0 <5.3.2'
'>=2.1.0 <4.2.6'
'<1.4.1||>2.0.0a <2.0.0rc3'
'>2.0.0a <2.1.2||<1.4.2'
'>=1.19 <1.22'
'>=1.0.0 <2.5.4'
'>=0.14.0 <=0.14.1'
'>=0.12.0 <=0.14.1'
'>=2.3.0 <2.4.1'
'<=5.1.3||>=6.0.0 <=6.2.0'
'<5.2.10||>=6.0.0 <6.4.0'
'<1.3.2||>=2.0.1 <2.1.1'
'<1.3.2||>=2.0.1 <2.1.1'
'>=3.0.0a <3.0.0.beta.3||>=2.12.0a <2.12.3||>=2.11.0a <2.11.3||>=2.10.0a <2.10.2||>=2.9.0a <2.9.4||>=2.8.0a <2.8.3||>=2.7.0a <2.7.1||>=2.5.0a <2.5.1||>=2.4.0a <2.4.6||>=2.3.0a <2.3.3||>=2.2.0a <2.2.3||>=2.1.0a <2.1.4||>=2.0.0 <2.0.5'
'>=2.0.0 <=2.12.4||>=3.0.0 <=4.0.0.beta7'
'<2.8.6||>=2.9.0 <2.9.6||>=2.10.0 <2.10.2'
'<2.11.14||>=3.0.0 <3.0.5||>=3.1.0 <3.1.5'
'>=0.12.29 <=0.12.40'
'>=0.14.14 <=1.14.1'
'>=5.0.0.alpha <5.0.0.beta1.1||>=4.2.0.alpha <4.2.5.1||>=4.1.0.alpha <4.1.14.1'
'>=3.0.0 <3.1.11 || >=3.2.0 <3.2.12'
'>0.5.0 <1.0.4||>=1.1.0 <1.1.3||>=1.2.0 <1.2.5'
'>=3.0.0 <5.2.1'
'>=1.1.0 <4.6.3'
'<2.2.10||>=2.3.0a <2.3.8||>=3.0.0a <3.0.0.rc4||>=2.4.0a <2.4.5'
'>=1.0.0.rc1 <=1.3.2'
'<3.7.11||>=4.0.0 <4.0.4||>=4.1.0 <4.1.11'
'>=0.11.0 <=0.11.1||=0.30.0'
'>=3.7.0 <3.7.13||>=4.0.0 <4.0.5||>=4.1.0 <4.1.12'
'>2.2.9 <=2.5.0'
'>=2.6.0 <=3.0.2'
'>2.2.9 <=2.5.0'
'>2.2.9 <=2.5.0'
'>=2.6.0 <=3.0.2'
'>=2.6.0 <=3.0.2'
'>=2.0.0 <=2.6.13'
'>2.2.9 <=2.5.0'
'>2.2.9 <=2.5.0'
'>=2.6.0 <=3.0.2'
'>=0.8.11 <=0.9.0'
'>=2.6.0 <=3.0.2'
'>2.2.9 <=2.5.0'
'>=2.7.6 <=3.0.2'
'>2.2.9 <=2.5.0'
'<1.5.3||>2.0.0 <2.0.5'
'<1.5.5 || >=1.6.0 <1.6.8 || >=1.7.0 <1.7.7'
'>=2.0.0 <=2.0.1'
'>=7.0.0 <7.12.1||<6.25.1'
'>=3.1.0 <3.1.1||>=2.7.0 <2.7.21'
'<2.7.26||>=3.0.0 <3.6.2'
'>=6.0.0 <6.13.0'
'>=2.7.0 <2.7.23||>3.2.0 <3.2.4'
'<2.6.17||>=2.7.0 <2.7.18'
'>=7.0.0 <7.12.1||<6.25.1'
'>=2.7.0 <2.7.18'
'>=2.7.1 <2.7.13'
'<2.6.17||>=2.7.0 <2.7.18'
'>=2.7.0 <2.7.22||>=3.2.0 <3.2.2'
'>=2.0.0 <2.2.5 || >=3.0.0 <3.0.1'
'>=1.4.0 <1.5.4 || >=1.6 <2.0.5 || >=2.1.0 <2.1.3 || >=2.2.0 <2.2.3'
'>=3.0.0 <3.2.15'
'>=1.4.0 <1.5.4'
'>=2.3.0 <2.8.0'
'>=0.0.1 <=2.6.0'
'>=0.1.7 <=2.6.0'
'>=2.0.1 <=2.6.0'
'>=2.1.2.0 <=2.6.0'
'>=0.119.0 <=0.125.1'
'<3.0.17 || >=3.1.0 <3.1.8 || >=3.2.0 <3.2.8'
'>=3.0.0 <3.1.12 || >=3.2.0 <3.2.13'
'<2.3.16 || >=2.4.0 <3.0.20'
'<5.2.4.3||>=6.0.0 <6.0.3.1'
'>=4.1.0a <4.1.11||>=4.2.0a <4.2.2'
'>=3.0.0 <3.0.12||>=3.1.0 <3.1.4||>=3.2.0 <3.2.2'
'<3.2.22||>=4.0.0a <4.1.11||>=4.2.0a <4.2.2'
'>=2.0.0 <2.3.13||>=3.0.0 <3.0.10'
'>=5.0.10 <5.1.11'
'>=4.0.5 <4.0.33'
'>=5.3.0 <5.3.2'
'>=3.0.0 <3.0.21 || >=4.0.0 <4.0.5'
'>=5.3.0 <5.3.2'
'=4.0.0||=1.0'
'>=3.0.0 <5.3.2'
'>=5.3.0 <5.3.2'
'>=4.0.0a <4.0.60||>=5.0.0a <5.0.22'
'>=2.0.2 <=3.1.1'
'>=0.2.0 <0.2.2||>=0.4.0 <0.4.2'
'>=0.4.0 <=0.5.2'
'>=2.0.0 <2.0.13||>=2.1.0 <2.1.11||>=2.2.0 <2.2.5||>=2.3.0 <2.3.10||>=2.4.0 <2.4.11||>=2.5.0 <2.5.3||>=2.6.0 <2.6.3||>=2.7.0 <2.7.8||>=2.8.0 <2.8.2||>=2.9.0 <2.9.2||>=2.10.0 <2.10.4||>=2.11.0 <2.11.2'
'<2.5.5.rc1||>=2.6.0.alpha0 <2.6.6.rc1||>=2.7.0.alpha0 <2.7.0.rc1'
'>=2.3.2 <=2.4.3'
'>=2.3.2 <=2.4.1'
'>=2.0.0.rc3 <2.0.2'
'<2.0.1||>=3.0.0 <3.0.2||>=3.1.0 <3.1.2||=3.2.0'
'>=0.119.0 <=0.125.1'
'>=0.5.0 <1.9.4'
'<1.0.3 || >=1.1.0 <1.1.4 || >=1.2.0 <2.0.2'
'>=0.1.33 <=1.1.2'
'>=0.5.0 <0.5.4'
'<2.8.6||>=2.9.0 <2.9.6||>=2.10.0 <2.10.2'
'<2.11.14||>=3.0.0 <3.0.5||>=3.1.0 <3.1.5'
'>=2.31.0 <2.31.2||>=2.32.0 <2.49.1'
'<3.9.0||>=5.0.0 <5.2.0||>=6.0.0 <6.3.0'
'<3.8.0||>=5.0.0 <5.1.0||>=6.0.0 <6.2.0'
'<1.5.5||>=2.0.0.beta1 <2.0.0'
'>=0.2.0 <=0.3.2'
'>0.11.0 <0.13.3'
'>=0.0.0 <0.12.1'
'>=0.0.0 <0.12.1'
'>=0.0.0 <0.12.1'
'<=0.14.1||>=0.15.0 <=0.15.1||>=0.16.0 <=0.16.3||>=0.17.0 <=0.17.2||=0.18.0'
'>=0.0.0 <0.12.1'
'>=3.7.0 <3.7.13||>=4.0.0 <4.0.5||>=4.1.0 <4.1.12'
'>=9.0.0.pre1 <9.2.5'
'>=8.0 <=9.2.4'
'>=8.0 <=9.2.4'
'>=3.0.0 <3.0.4'
'>=2.0.0 <2.3.13||>=3.0.0 <3.0.10'
'>=3.0.0.alpha <3.2.22.3'
'>=3.2.0a <3.2.20||>=4.0.0a <4.0.11||>=4.1.0a <4.1.7||>=4.2.0.a <4.2.0.beta3'
'>=4.0.0 <4.0.2'
'<2.3.18 || >=2.4.0 <3.1.12 || >=3.2.0 <3.2.13'
'<3.2.17||>=4.0 <4.0.3||>=4.1.0 <4.1.1'
'>=6.0.0 <=6.0.4||>=6.1.0 <=6.1.4'
'>=3.2.0.0.alpha <3.2.22.2||>=4.0.0.0.alpha <4.1.14.2||>=4.2.0.0.alpha <4.2.5.2'
'<2.3.15 || >=2.4.0 <3.0.19 || >=3.1.0 <3.1.10 || >=3.2.0 <3.2.11'
'>=6.0.0 <6.0.3.4'
'>=4.2.0.alpha <4.2.5.1||>=4.0.0.alpha <4.1.14.1'
'<3.2.16||>=4.0 <4.0.2'
'>=2.3.0.alpha0 <2.3.13'
'>=3.0.0 <3.0.16 || >=3.1.0 <3.1.7 || >=3.2.0 <3.2.7'
'<3.0.17 || >=3.1.0 <3.1.8 || >=3.2.0 <3.2.8'
'>=5.0.0.alpha <5.0.0.beta1.1||>=4.2.0.alpha <4.2.5.1||>=4.0.0.alpha <4.1.14.1||<3.2.22.1'
'>=3.0.0.alpha0 <3.0.12||>=3.1.0.alpha0 <3.1.4||>=3.2.0.alpha0 <3.2.2'
'<3.0.13||>=3.1.0 <3.1.5||>=3.2.0 <3.2.4'
'>=3.0.0 <3.0.10'
'>=3.2.0.0.alpha <3.2.22.2'
'>=6.0.0 <6.0.3.7||>=6.1.0 <6.1.0.2'
'>=3.2.0a <3.2.21||>=4.0.0a <4.0.11.1||>=4.1.0a <4.1.7.1'
'>=3.0.0.alpha0 <3.0.11||>=3.1.0.alpha0 <3.1.2'
'>=5.2.0.0 <5.2.4.6||>=6.0.0.0 <6.0.3.7||>=6.1.0.0 <6.1.3.1'
'>=2.3.0 <2.3.13'
'>=5.0.0.alpha <5.0.0.beta1.1||>=4.2.0.alpha <4.2.5.1||>=4.0.0.alpha <4.1.14.1||<3.2.22.1'
'>=6.0.0 <=6.0.4.1||>=6.1.0 <=6.1.4.1'
'>=3.0.6 <3.2.16||>=4.0.0.beta1 <4.0.2'
'<5.2.4.6||>=5.2.5 <5.2.6||>=6.0.0 <6.0.3.7||>=6.1.0 <6.1.3.2'
'<5.2.4.3||>=6.0.0 <6.0.3.1||=10.0'
'<2.3.18 || >=2.4.0 <3.1.12 || >=3.2.0 <3.2.13'
'<3.2.16||>=4.0.0 <4.0.5||>=4.1.0 <4.1.1'
'>=2.0.0 <3.2.16||>=4.0.0.beta1 <4.0.2'
'>=5.0.0.0 <=5.2.6.1||>=6.0.0.0 <=6.0.4.5||>=6.1.0.0 <=6.1.4.5||>=7.0.0.0 <=7.0.2.1'
'>=6.0.0 <6.0.3.5||>=6.1.0 <6.1.2.1||=33'
'>=3.0.0 <3.0.17 || >=3.1.0 <3.1.8 || >=3.2.0 <3.2.8'
'<3.0.14||>=3.1.0 <3.1.6||>=3.2.0 <3.2.6'
'<5.2.4.3||>=6.0.0 <6.0.3.1'
'<3.2.16||>=4.0.0 <4.0.2'
'>=0.3.0 <1.2'
'>=3.0.0 <3.12.6||>=4.0.0 <4.3.5'
'<=4.3.8||>=5.0.0 <=5.5.0'
'<4.3.8||>=5.0.0 <5.3.1'
'>=3.0.0 <3.12.6||>=4.0.0 <4.3.5'
'>=3.0.0 <3.12.2||>=4.0.0 <4.3.1'
'<4.3.11||>=5.0.0 <5.6.2'
'<=3.12.3||>=4.0.0 <=4.3.2'
'<4.3.12||>=5.0.0 <5.6.4'
'<=3.12.3||>=4.0.0 <=4.3.2'
'>=1.3.0 <1.3.1 || >=1.2.0 <1.2.2 || >=1.1.0 <1.1.1 || >=1.0.0 <1.0.4'
'>=1.1.0.rc1 <1.1.0.rc5'
'>=1.79.0 <13.3.9||>=13.4.0 <13.4.5||>=13.5.0 <13.5.2'
'>=2.1.0pre1 <2.1.1'
'<1.6.0||>=1.6.2 <1.6.3'
'<1.7.6||>=2.0.0 <2.0.2'
'>=0.4.0 <=0.4.1'
'>=0.119.0 <=0.125.1'
'<2.1.4||>=2.2.0 <2.2.3'
'<1.6.12||>1.6.12 <2.0.8'
'>=1.3.0 <=1.4.2'
'>=1.1.0 <1.1.6 || >=1.2.0 <1.2.8 || >=1.3.0 <1.3.10 || >=1.4.0 <1.4.5 || >=1.5.0 <1.5.2'
'>=0.4 <=1.4.1'
'>=1.4.0 <1.4.5 || >=1.5.0 <1.5.2'
'<1.1.3||>=1.2.0 <1.2.5||>=1.3.0.beta <1.3.6'
'<1.4.6||>=1.5.0a <1.5.4||>=1.6.0a <1.6.2'
'>=2.0.4 <=2.0.5'
'>=1.1.0 <=1.4.3'
'>=1.6.0 <1.6.11||>=2.0.0 <2.0.6'
'>=0.8.0 <0.8.7.1'
'>=4.0.0.alpha <4.2.7.1||>=5.0.0.alpha <5.0.0.1'
'>=3.0.0 <4.2.11.1||>=5.0.0 <5.0.7.2||>=5.1.0 <5.1.6.2||>=5.2.0 <5.2.2.1'
'>=4.0.0.0.alpha <4.1.14.2'
'>=5.0.0.alpha <5.0.0.beta1.1||>=4.2.0.alpha <4.2.5.1||<4.1.14.1'
'<5.2.4.2||>=6.0.0 <6.0.2.2'
'<5.2.4.4||>=6.0.0.0 <6.0.3.3'
'<4.2.11.1||>=5.0.0 <5.0.7.2||>=5.1.0 <5.1.6.2||>=5.2.0 <5.2.2.1'
'<0.26.6||>=0.27.0 <0.27.4'
'<0.21.3||>0.22a'
'=3.0.23||=3.0.28'
'>=2.0.4 <4.0.0.beta1'
'>=2.0 <2.7.7'
'<2.8.6||>=2.9.0 <2.9.6||>=2.10.0 <2.10.2'
'>=1.6.1 <1.8.0'
'>=1.6.10 <=1.6.13'
'<2.8.6||>=2.9.0 <2.9.6||>=2.10.0 <2.10.2'
'<2.11.14||>=3.0.0 <3.0.5||>=3.1.0 <3.1.5'
'<2.11.12||>=3.0.0 <3.0.3||>=3.1.0 <3.1.3'
'<2.11.13||>=3.0.0 <3.0.4||>=3.1.0 <3.1.4'
'>=5.2.0 <5.2.1.1'
'<5.2.4.2||>=6.0.0 <6.0.3.1'
'>=5.2.0 <=5.2.6.2||>=6.0.0 <=6.0.4.6||>=6.1.0 <=6.1.4.6||>=7.0.0 <=7.0.2.2'
'>=3.1.0 <=3.1.3'
'<3.1.3||>=4.0.0a <4.0.4'
'>=1.5 <1.5.11 || >=1.6 <1.6.1'
'>=1.6.0 <=1.6.7'
'<1.6.6.3||>=1.6.7.rc2 <1.6.7.rc4'
'>=1.5 <1.5.11 || >=1.6 <1.6.1'
'<1.6.6.4 ||>=1.6.7.rc2 <1.6.7.rc4'
'>=1.6.0.0a <1.6.7.2'
'<1.6.6.4||>=1.6.7.rc1 <1.6.7.rc4'
'>=1.6.0.rc1 <1.6.7.1'
'>=3.2.0 <3.5.2'
'>=3.0.0 <3.12.6||>=4.0.0 <4.3.5'
'<4.3.8||>=5.0.0 <5.3.1'
'>=3.0.0 <3.12.6||>=4.0.0 <4.3.5'
'>=3.0.0 <3.12.2||>=4.0.0 <4.3.1'
'*'
'<=3.12.3||>=4.0.0 <=4.3.2'
'<4.3.12||>=5.0.0 <5.6.4'
'<=3.12.3||>=4.0.0 <=4.3.2'
'<=4.0.1||>=4.1.0 <=4.4.1'
'>=5.1.0 <5.1.6.1||>=4.2.0 <4.2.11||>=5.0.0 <5.0.7.1||>=5.2.0 <5.2.1.1'
'>=2.0.0 <2.2.3||>=2.3.0 <2.3.4'
'<2.2.2||>=2.3.0 <2.3.5'
'>4.0.0.beta <4.0.3 || =4.1.0.beta1'
'<2.3.11||>=3.0.0 <3.0.4'
'>=6.1.0 <=6.1.3.2'
'>=5.2.0 <5.2.1.1'
'>=5.2.0 <5.2.2.1||>=6.0.0.beta1 <6.0.0'
'<5.2.4.3||>=6.0.0 <6.0.3.1'
'<3.2.17 || >=4.0.0.beta <4.0.3 || =4.1.0.beta1'
'>=6.0.0 <6.0.4.1||>=6.1.0 <6.1.4.1'
'>=4.0.0 <=4.2.5.1'
'>=6.0.0 <6.0.3.4'
'>=6.0.0 <6.0.3.2'
'>=4.2.0 <5.2.4.5||>=6.0.0 <6.0.3.5||>=6.1.0 <6.1.2.1'
'>=3.0.0 <3.2.16||>=4.0.0.beta1 <4.0.2'
'>=4.2.0 <=4.2.7'
'>=1.1.0 <1.1.6'
'<4.2.11.1||>=5.0.0 <5.0.7.2||>=5.1.0 <5.1.6.2||>=5.2.0 <5.2.2.1'
'<5.2.4.3||>=6.0.0 <6.0.3.1'
'>=2.0.0 <2.3.11||>=3.0.0 <3.0.7'
'<5.2.4.2||>=6.0.0 <6.0.3.1'
'>=2.1.0 <2.3.11||>=3.0.0 <3.0.4'
'>=2.1.0 <2.2.3||>=2.3.0 <2.3.4'
'<3.2.22.2||>=4.0.0.0 <4.1.14.2'
'>=6.0.0 <6.0.3.7||>=6.1.0 <6.1.0.2'
'>=4.0.0 <=5.0.0'
'>=3.0.0 <3.0.11||>=3.1.0 <3.1.2'
'>=5.2.0.0 <5.2.4.6||>=6.0.0.0 <6.0.3.7||>=6.1.0.0 <6.1.3.1'
'>=4.0.0 <=5.0.0'
'>=4.2.0 <4.2.11||>=5.0.0 <5.0.7.1||>=5.1.0 <5.1.6.1||>=5.2.0 <5.2.1.1'
'>=6.0.4.2 <=6.1.4.2||=7.0.0'
'<5.2.4.6||>=5.2.5 <5.2.6||>=6.0.0 <6.0.3.7||>=6.1.0 <6.1.3.2'
'<5.2.4.3||>=6.0.0 <6.0.3.1'
'>=4.1 <4.1.1 || >4.0 <4.0.5 || >=0.0 <3.2.18'
'>=1.1.0 <1.1.6'
'<4.2.11.1||>=5.0.0 <5.0.7.2||>=5.1.0 <5.1.6.2||>=5.2.0 <5.2.2.1'
'>=5.0.0 <5.2.6.2||>=6.0.0 <6.0.4.6||>=6.1.0 <6.1.4.6||>=7.0.0 <7.0.2.2'
'>=6.0.0 <6.0.3.5||>=6.1.0 <6.1.2.1'
'>=2.1.0 <2.1.3||>=2.2.0 <2.2.2'
'<5.2.4.3||>=6.0.0 <6.0.3.1'
'>=3.0.0.beta <3.2.17'
'>=2.3.9 <2.3.10||>=3.0.0 <3.0.1'
'>=1.0.0 <1.2.0'
'>=5.2.0 <5.2.2.1||>=6.0.0.beta1 <6.0.0'
'<2.3.18 || >=2.4.0 <3.0.0 || >=3.1.0 <3.1.12 || >=3.2.0 <3.2.13'
'>=3.2.0 <4.0.3'
'>=2.0.0 <2.3.13||>=3.0.0 <3.0.10'
'>=3.0.0 <3.0.13||>=3.1.0 <3.1.5||>=3.2.0 <3.2.4'
'>=4.2.0 <5.2.4.5||>=6.0.0 <6.0.3.5||>=6.1.0 <6.1.2.1'
'>=3.0.0 <3.0.18||>=3.1.0 <3.1.9||>=3.2.0 <3.2.10'
'>=4.0.0.alpha <4.2.7.1'
'>=3.0.0 <3.0.13||>=3.1.0 <3.1.5||>=3.2.0 <3.2.4'
'>4.0.0 <4.0.7||>4.1.0 <4.1.3'
'<2.3.17 || >=2.4.0 <3.1.0'
'>=5.0.0.alpha <5.0.0.beta1.1||>=4.2.0.alpha <4.2.5.1||>=4.0.0.alpha <4.1.14.1||>=3.1.0.alpha <3.2.22.1'
'>4.0.0 <4.0.9||>4.1.0 <4.1.5'
'>2.0.0 <3.2.19'
'<3.0.19 || >=3.1.0 <3.1.10 || >=3.2.0 <3.2.11'
'>=3.0.0 <3.0.4'
'<3.0.14||>=3.1.0 <3.1.6||>=3.2.0 <3.2.6'
'>0.0.0a <0.6.4||>0.7.0a <0.7.3'
'>=1.2 <3.5.0'
'>=3.11 <6.3.1'
'>=1.0.3 <3.5.0'
'>=2.3.0 <3.9.5 || >=3.10 <3.12 || >=4.0.0.preview2 <4.0.0.rc.2'
'>=4.2.2 <4.3.6'
'>=3.1.4 <5.2.0'
'<0.5.1||>=0.6.0 <0.6.6'

npm

'<4.2.0'
'<=3.3'
'>=0'
'>=0'
'>=0.0.0'
'<0.5.3'
'<=0.3.0'
'<0.3.1'
'<0.3.4'
'<3.1.0'
'>=0.0.0-alpha'
'<=0.0.1'
'<0.4.9'
'>=0'
'<=0.5.0'
'>=0'
'=1.0.0'
'>=0.0.0-alpha'
'>=0'
'<3.1.6'
'<=0.0.9'
'<=0.0.9'
'<=0.0.9'
'>=0'
'<1.1.0'
'=1.0.0'
'>=0.0.0-alpha'
'>=0.0.0-alpha'
'=1.0.0'
'>=0'
'<3.8.1'
'<3.8.1'
'>=0'
'>=0.0.0-alpha'
'<=2.48.0'
'<7.4.4'
'<1.10.0'
'<=2.5.0'
'>=0'
'<0.0.25'
'<=0.0.25'
'>=0.0.0-alpha'
'<=1.0.0'
'<8.31.2'
'=8.0.0'
'<39.1.0'
'>=0'
'>=0'
'=0.1.2'
'<13.0.8'
'>=0'
'<2.1.4||>=3.0.0 <6.0.6'
'<2.1.4||>=3.0.0 <6.0.6'
'<7.3.1'
'<1.1.0'
'=2.0.43'
'<0.1.7'
'0.5.0'
'<0.5.1'
'<1.0.0'
'>=0'
'=0.4.0'
'>=0'
'=1.1.7'
'<0.2.6'
'<3.4.6 || >=4.0.0 <4.0.5'
'<3.4.6||>=4.0.0 <4.0.5'
'<3.5.1||>=4.0.0 <=4.1.3||>=5.0.0 <=5.6.1||>=6.0.0 <=6.1.2'
'<0.5.2'
'<0.4.4'
'>=0'
'>=0.0.0-alpha'
'>=0.0.0-alpha'
'<=0.2.3'
'=1.0.3'
'<4.2.0'
'<3.0.5'
'< 2.11.2 || >= 3.0.0 < 3.6.4 ||  >= 4.0.0 < 4.5.7 || >= 5.0.0 < 5.2.1 || >= 6.0.0 < 6.0.5 || >= 6.1.0 < 6.1.6 || >= 6.2.0 < 6.2.5 || >= 6.3.0 < 6.3.3 || >= 6.4.0 < 6.4.2 || >= 7.0.0 < 7.0.2 || >= 7.1.0 < 7.1.2'
'<=0.0.1'
'<=0.0.3'
'>=0.0.0-alpha'
'<11.0.4'
'>=0.0.0-alpha'
'=1.0.0'
'>=0'
'>=0'
'=1.0.6'
'>=0'
'<=0.2.4'
'<2.0.3'
'<0.2.2'
'=8.0.8'
'<0.1.1'
'<=1.0'
'<1.14'
'<1.11.10||>=1.12.0 <1.12.8||>=1.13.0 <1.13.7||>=1.14.0 <1.14.6||>=1.15.0 <1.15.3||>=1.16.0 <1.16.2'
'<1.2.0'
'<1.17.0'
'=1.13.0'
'=1.13.0||>=1.12.0 <1.12.4||>=1.11.0 <1.11.6||>=1.10.0 <1.10.10'
'<=1.13.0'
'<3.0.3'
'<3.0.1'
'<3.0.1'
'<=0.1.1'
'<5.2.1'
'=0.7.29||=0.8.0||=1.0.0'
'<0.7.22'
'<0.7.23'
'>=0'
'=0.1.1'
'>=0.0.0-alpha'
'>=0'
'=0.1.1'
'>=0'
'=0.1.8'
'>=0.0.0-alpha'
'<=0.1.1'
'>=0'
'=1.0.2'
'<=2.0.0'
'<=5.80.0'
'=1.0.0'
'>=0.0.0-alpha'
'=2.3.21'
'<5.0.2'
'>=0'
'>=0'
'<20190301.0.0'
'<20200315'
'<=3.2.0'
'<=1.0.0'
'<4.0.1'
'<=1.0.8'
'<2.1.0'
'<3.0.0'
'<2.0.0'
'<3.3.0'
'<3.4.2'
'<3.3.0'
'<2.0.1'
'>=0.0.0-alpha'
'=1.0.0'
'>=0'
'<3.4.0||>=4.0.0 <4.1.2'
'<3.4.0'
'<3.4.0||>=4.0.0 <4.1.2'
'<3.4.0'
'<4.10.7'
'<3.6.0'
'<4.1.0'
'<4.10.3'
'<4.5.0'
'<4.10.4'
'<3.4.1'
'<=4.3.0'
'<4.5.1'
'<=0.3.13'
'<=0.3.13'
'>=0.0.0-alpha'
'<=0.9.1'
'<=3.0.0'
'>=0.0.0-alpha'
'>=0'
'<1.7.9'
'<1.6.3'
'<1.8.0'
'<1.6.9'
'<1.6.0'
'<1.6.3'
'<1.6.5'
'<1.2.30'
'<1.8.0'
'<1.5.9'
'<=1.4.14'
'>=0'
'<=0.2.1'
'>=0.0.0-alpha'
'<2.0.1||>=3.0.0 <4.0.1'
'<2.0.1||>=3.0.0 <3.0.1'
'<3.2.1'
'>=0'
'>=0.0.0-alpha'
'<=1.1.0'
'<=0.2.0'
'>=0'
'>=0'
'>=0.0.0-alpha'
'<0.0.19'
'>=0'
'>=0'
'>=0'
'=4.0.11'
'>=0.0.0'
'<= 0.0.1'
'<6.0.0'
'>=0.0.0-alpha'
'>=0'
'<=0.0.2'
'<0.0.3'
'>=0.0.0-alpha'
'<2015.4.18-a'
'<4.80.0'
'<4.80.0'
'<4.79.0'
'<4.72.2'
'<4.73.1'
'<3.1.3'
'>=0'
'<9.1.0'
'>=0'
'<0.4.0'
'>=0'
'<0.9.7'
'>=0'
'<2.1.1'
'<=0.5.0'
'>=0.0.0-alpha'
'<=0.0.11'
'=1.0.0'
'>=0'
'>=0'
'>=0.0.0-alpha'
'<=0.0.1'
'>=0.0.0-alpha'
'<=0.29.0'
'<=0.29.0'
'=1.1.6'
'<=0.0.2'
'>=0.0.0-alpha'
'>=0.0.0-alpha'
'>=0'
'<=0.0.4'
'>=0.0.0-alpha'
'>=0'
'=0.1.1'
'<3.0.0'
'<3.0.0'
'<5.65.7'
'<0.35.0'
'=0.42.0'
'<1.3.4||>2.0.0 <2.0.4'
'<0.6.1'
'>=0.0.0-alpha'
'>=0'
'>=0.0.0-alpha'
'<=3.9.1||=3.10.0'
'<6.1.0'
'<6.1.0'
'>=0.0.0-alpha'
'<=1.0.0'
'<=1.1.3'
'<=1.1.3'
'>=0'
'>=0'
'<1.0.2'
'<1.2.4'
'<1.2.4'
'>=0'
'>=0.0.0-alpha'
'=0.1.0'
'>=0.0.0-alpha'
'<=2.8.17-beta.6'
'>=0'
'>=0.0.0-alpha'
'>=0'
'<=5.84.0'
'>=0.0.0-alpha'
'<6.2.6'
'<3.0.0'
'<3.0.0'
'<6.1.0'
'<7.2.2||>=8.0.0 <8.1.1'
'<9.0.0'
'>=0'
'<1.0.0'
'<=0.9.1'
'>=0'
'>=0.0.0-alpha'
'=0.2.0'
'<1.2.6'
'<1.2.2'
'<1.0.3'
'<0.4.0'
'<0.45.3'
'<0.8.0'
'<=0.12.0'
'<0.8.2'
'<2.4.2'
'<2.4.2'
'<4.1.3'
'<4.1.3'
'<=0.1.9'
'>=0.0.0-alpha'
'<=5.4.0'
'<2.0.1'
'<1.1.82'
'<1.1.82'
'<=1.2.1'
'>=0.0.0'
'>=0'
'=0.2.0'
'<0.2.3'
'<=0.2.3'
'>=0'
'<2.0.3'
'>=0.0.0-alpha'
'>=1.0.0 <=1.0.1||=1.1.0'
'<16.8.2||>=17.0.0 <17.9.2||>=18.0.0 <18.4.1||>=19.0.0 <19.1.1'
'<2.1.1'
'=5.1.1'
'<5.1.2'
'<5.1.1'
'>=0.0.0-alpha'
'>=0'
'>=0'
'>=0'
'=3.0.0'
'<0.3.16'
'<0.3.16'
'<=4.0.0'
'<1.0.2'
'<4.0.0'
'<=0.3.22||=4.0.0'
'<4.0.0'
'>=0'
'>=0.0.0-alpha'
'<=3.3.1'
'<2.14.2'
'<=0.0.5'
'<0.2.1'
'>=0.0.0-alpha'
'<=0.8.6'
'>=0'
'<3.15.7'
'<3.15.7'
'<=5.2.1'
'<5.2.2'
'<0.26.0'
'<2.2.7'
'<2.2.0'
'<6.11.4'
'<0.0.18'
'<0.0.18'
'=1.0.3'
'<1.0.3'
'>=0.0.0-alpha'
'<=1.4.0'
'>=0.0.0-alpha'
'<=0.0.1'
'>=0'
'=1.1.0'
'<=1.0.2||<2.3.10'
'<2.3.10'
'=2.8.1'
'<=3.0.0'
'<2.1.2'
'<2.1.1'
'=1.1.8'
'=0.1.0'
'>=0.0.0-alpha'
'<=1.0.3'
'<1.0.4'
'<1.14.6'
'<=1.0.0'
'>=0'
'<1.1.7||>=2.0.0 <2.0.2'
'<=1.4.3'
'<1.5.1'
'<1.0.5'
'=1.7.5'
'>=0'
'>=0.0.0-alpha'
'<=0.9.0'
'>=0'
'<1.1.3'
'=1.3.3'
'=1.4.14'
'<1.4.15'
'>=0'
'<3.0.0'
'<3.2.5'
'<=3.0.0-beta.17.7'
'<3.2.5'
'<=1.6.4||=3.0.0'
'<4.1.0'
'<3.0.2'
'<=3.6.0'
'<3.2.5'
'<3.0.0-beta.17.8'
'>=0'
'<4.7.0'
'<=1.0.54'
'>=0.0.0'
'<=0.1.1'
'<1.4.1'
'<1.4.2'
'<1.4.2'
'<4.4.6'
'<=2.4.2'
'>=0.0.0'
'>=0'
'>=0.0.0-alpha'
'<=0.1.1'
'<5.0.0'
'<=2.2.0'
'<0.125.0'
'<=3.1.1'
'=0.2.1'
'<8.13.8'
'<8.2.3'
'<8.2.3'
'<8.11.0'
'<2.0.0'
'>=0'
'<1.2.3'
'<5.0.0'
'>=0'
'>=3.0.0 <3.10.0||=3.10.2'
'>=0'
'<6.15.1'
'>=0'
'<1.0.12'
'<3.24.0'
'>=0'
'>=0'
'<1.1.4'
'>=0'
'>=0'
'>=0.0.0-alpha'
'>=0'
'<3.1.1'
'<1.5.2'
'=8.4.3'
'<2.19.6||>=3.0.0 <3.1.2||>=4.0.0 <4.3.4'
'<4.4.0'
'<2.0.1'
'<2.0.0'
'<=2.3.0'
'>=0'
'>=0.0.0-alpha'
'<=0.0.3'
'=0.0.3'
'<2.10.0'
'>=0'
'<0.4.0'
'>=0'
'<=1.0.1'
'>=0.0.0-alpha'
'<=0.1.8'
'>=0.0.0-alpha'
'<=1.3.1'
'<2.2.4'
'>=0'
'<1.7.0'
'<0.4.2'
'>=0'
'<=0.7.0'
'<1.0.0'
'<1.0.0'
'>=0'
'<2.0.3'
'<3.2.5'
'=5.0.1'
'=5.0.2'
'<=1.0.0'
'>=0.0.0-alpha'
'<2.0.1'
'>=0'
'>=0'
'<1.0.1'
'<1.0.1'
'>=0'
'<=0.9.73'
'=1.0.0'
'>=0.0.0-alpha'
'>=0.0.0-alpha'
'<=2.0.0'
'<1.5.1'
'<1.6.0'
'<1.5.3'
'<1.5.3'
'>=0'
'>=0'
'>=0'
'<1.4.1'
'<1.5.8'
'<1.2.0'
'>=0'
'<1.2.1'
'>=0'
'>=0'
'>=0'
'>=0'
'<=2.1.1'
'<0.26.0'
'>=0'
'<4.0.3||>=4.1.0 <4.1.3||>=4.2.0 <4.2.1||>=4.3.0 <4.3.1'
'<=1.0.1'
'>=0.0.0-alpha'
'<=2.0.11'
'<2.0.15'
'<2.0.12'
'>=0.0.0-alpha'
'<=1.0.0'
'>=0'
'=1.2.6'
'>=0.0.0-alpha'
'<=0.1.11'
'>=0.0.0-alpha'
'<1.0.8'
'<1.2.6'
'<4.0.5||>=5.0.0 <8.1.1'
'>=0.0.0-alpha'
'=0.1.1'
'>=0'
'<=3.2.0'
'<=3.2.0'
'>=0.0.0-alpha'
'<1.4.0'
'<=0.2.4'
'<0.2.4'
'<0.2.4'
'<1.4.1'
'>=0'
'<1.0.12'
'<3.1.0'
'<3.0.0'
'>=0.0.0'
'<=0.0.10-2014-03-24-17-36-27'
'<2.0.2'
'=2.3.2'
'<1.16.2'
'<3.1.13'

pypi

'>=1.0a1,<1.0.5||>=1.1b1,<1.1.1'
'>=5.0.0,<5.0.12||>=6.0.0,<6.0.5||>=6.1.0,<6.2.2'
'>=5.0.0,<5.0.12||>=6.0.0,<6.0.5||>=6.1.0,<6.2.2'
'>=4.0,<4.3||>=5.0,<5.2'
'>=4.0,<4.3||>=5.0,<5.2'
'>=1.10.0,<=1.10.15||>=2.0.0,<2.2.0'
'>=1.0.0,<1.10.15||>=2.0.0,<2.0.2'
'>0.11.0,<0.11.7 || >0.12.0,<0.12.6'
'>=2.12.0,<2.12.19||>=2.13.0,<2.13.8'
'<2.12.21||>=2.13.0,<2.13.11'
'>=2.8.0,<2.8.12||>=2.9.0,<2.9.12||>=2.10.0,<2.10.11||>=2.11.0,<
'<21.2.3||>=22.0.0,<22.2.3||>=23.0.0,<23.0.3'
'>=2.4.0,<2.4.5||>=3.0.0,<3.1.1'
'<1.9.0||>=2.0.0,<2.2.0'
'<1.8.0||>=2.0.0,<2.1.0'
'>=0.6.0,<=0.6.1||>=0.7.0,<=0.7.2'
'<=3.4.6.27||>=4.0.0.21,<=4.1.0.25'
'<=3.4.6.27||>=4.0.0.21,<=4.1.0.25'
'<1.2.21||>=2.0.0,<2.2.10||>=2.3.0,<2.3.2||>=3.0.0,<3.0.17||>=
'==2.3.0||==3.0.0'
'<15.0.1||>=16.0.0.0rc1,<16.0.0'
'<1.3.1||>=2.0.0,<=3.0.0'
'<=1.7.0||>=2.0.0,<2.4.0'
'<1.8.6||>=1.9.0alpha,<1.10.5||>=2.0.0alpha,<2.0.2'
'<0.7.6||==0.8.0'
'<=1.2.17||==1.3.0'
'<1.3.2||==2.0.0||==2.0.0b1'
'>=3.0.0,<=3.0.17||>=3.2.0,<=3.2.17||>=3.4.0,<=3.4.17 ||>=3.6.0,<=
'>=4.2,<4.2.21||>=4.4,<4.4.19||>=4.6,<4.6.14||>=4.8,<4.8.10||>=
'==4.4.1||==4.10'
'==5.3.0||==6.1.0||==7.2.0'
'<2019.2.4||>=3000,<3000.2'
'<=2015.8.12||>=2016.3.0,<=2016.3.4||>=2016.11.0,<=2016.11.2'
'<=2016.3.7||>=2016.11,<=2016.11.7||>=2017.7.0,<=2017.7.1'
'<2015.8.13||>=2016.3.0,<2016.3.8||>=2016.11.0,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2015.8.13||>=2016.3.0,<2016.3.8||>=2016.11.0,<2016.11.10|| >=2017.5.0,<2017.7.8
'>=3002,<3002.8||>=3003,<3003.4||>=3004,<3004.1'
'<=2016.11.6||==2017.7.0'
'>=3002,<3002.8||>=3003,<3003.4||>=3004,<3004.1'
'<=2016.3.7||>=2016.11,<=2016.11.7||>=2017.7.0,<=2017.7.1'
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10||>=2017.5.0,<2017.7.8 ||>=
'>=3002,<3002.8||>=3003,<3003.4||>=3004,<3004.1'
'<=2015.8.12||>=2016.3.0,<=2016.3.4||>=2016.11.0,<=2016.11.2'
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10||>=2017.5.0,<2017.7.8||
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2019.2.4||>=3000,<3000.2'
'<2017.7.8||>=2018.3.0,<2018.3.3'
'<2015.8.13||>=2016.3.0,<2016.3.8||>=2016.11.0,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2017.7.8||>=2018.3.0,<2018.3.3'
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10 ||>=2017.5.0,<2017.7.8||>=
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'>=3002,<3002.8||>=3003,<3003.4||>=3004,<3004.1'
'<2015.8.13||>=2016.3.0,<2016.11.5||>=2016.11.7,<2016.11.10|| >=2017.5.0,<2017.7.8
'<5.7.11||>=6.0.0,<6.4.1'
'>=5.7.0,<5.7.11||==6.4.0'
'<1.1.2||==2.0.0rc1'
'<16.4.1||>=17.0.0,<17.1.3||==18.0.0'
'>=11.0.0,<11.0.7||>=12.0.0,<12.0.6||>=13.0.0,<13.0.3'
'>=7.0.0,<7.2.1||>=8.0.0,<8.3.1||>=9.0.0,<9.3.2|>=10.0.0,<
'>=11.0.0,<=11.0.5||>=12.0.0,<=12.0.3||==13.0.0.0'
'<15.3.3||>=16.0.0,<16.3.1||>=17.0.0,<17.1.1'
'<16.4.1||>=17.0.0,<17.2.1||>=18.0.0,<18.1.1'
'>=7.0.0,<=11.0.4||>=12.0.0,<=12.0.2||==13.0.0'
'<16.4.1||>=17.0.0,<17.2.1||>=18.0.0,<18.1.1'
'<10.0.8||>=11.0.0,<11.0.7||>=12.0.0,<12.0.6||>=13.0.0,<13.0.3'
'<6.2.3||==7.0.0'
'<6.2.3||==7.0.0'
'<6.2.3||==7.0.0'
'>=2.3.0,<2.3.2||>=2.5.0,<2.5.2'
'>=1.0,<=1.1.7||>=1.2,<=8.2.0'
'<4.6.1||>=5.0.0,<5.2.1'
'>=4.0,<4.6.3||>=5.0,<5.3'
'<4.6||>=5.0,<5.2'
'<0.13.7||>=0.14.0,<0.14.6'
'<7.5.7||>=8.0.0,<8.1.0'
'<=5.10.0||>=6.0.0,<7.16.3||>=7.17.0,<7.31.1||>=8.0.0,<8.0.1'
'>=3.4.0,<3.4.7||>=3.5.0,<3.5.4||>=3.6.0,<3.6.1||>=3.7.0,<
'<=3.4.6.27||>=4.0.0.21,<=4.1.0.25'
'<=3.4.6.27||>=4.0.0.21,<=4.1.0.25'
'<1.9.0||>=2.0.0,<2.2.0'
'>=1.0.0,<1.1.1||>=2.0.0,<2.1.1||>=3.0.0,<=3.1.1'
'<1.8.2||>=2.0.0,<2.3.1'
'==3.1||>=4.0.0,<=4.0.2'
'>=2.1,<2.1.15||>=2.2,<2.2.8'
'>=1.4,<1.4.11||>=1.5,<1.5.6||>=1.6,<1.6.3'
'>=1.8.0a,<1.8.10||>=1.9.0a,<1.9.3'
'>=1.2.0,<1.2.7||>=1.3.0,<1.3.1'
'>=2.2,<2.2.26||>=3.2,<3.2.11||>=4.0,<4.0.1'
'>=1.11.8,<=1.11.9||>=2.0,<=2.0.1'
'>=2.2,<2.2.16||>=3.0,<3.0.10||>=3.1,<3.1.1'
'>=1.3.0,<1.3.1||>=1.2.0,<1.2.7'
'>=1.1.0,<1.1.4||>=1.2.0,<1.2.5'
'>=2.2,<2.2.27||>=3.2,<3.2.12||>=4.0,<4.0.2'
'>=1.11,<1.11.15||>=2.0,<2.0.8'
'>=2.2,<2.2.26||>=3.2,<3.2.11||>=4.0,<4.0.1'
'>=1.11.0,<1.11.19||>=2.0.0,<2.0.11||>=2.1.0,<2.1.6'
'>=1.11alpha,<1.11||>=1.10.0alpha,<1.10.7||>=1.9.0alpha,<1.9.13||<1.8.18'
'>=1.4,<1.4.13||>=1.5,<1.5.8||>=1.6,<1.6.5||>=1.7.b1,<1.7b3'
'>=1.4,<1.4.11||>=1.5,<1.5.6||>=1.6,<1.6.3'
'>=1.11,<1.11.21||>=2.1,<2.1.9||>=2.2,<2.2.2'
'>=1.8.0a,<1.8.10||>=1.9.0a,<1.9.3'
'<1.11.27||>=2.2,<2.2.9||==3.0'
'>=1.8.0a,<1.8.3||>=1.7.0a,<1.7.9||>=1.4.0a,<1.4.21'
'>=1.10.0alpha,<1.10.3||>=1.9.0alpha,<1.9.11||<1.8.16'
'>=1.8.0a,<1.8.4||>=1.7.0a,<1.7.10||>=1.4.0a,<1.4.22'
'>=2.2,<2.2.13||>=3.0,<3.0.7'
'>=1.11,<1.11.23||>=2.1,<2.1.11||>=2.2,<2.2.4'
'>=2.2,<2.2.25||>=3.1,<3.1.14||>=3.2,<3.2.10'
'>=1.11,<1.11.22||>=2.1,<2.1.10||>=2.2,<2.2.3'
'>=1.8,<1.8.19||>=1.11,<1.11.11||>=2.0,<2.0.3'
'>=2.2,<2.2.19||>=3.0,<3.0.13||>=3.1,<3.1.7'
'<2.2.24||>=3.0.0,<3.1.12||>=3.2.0,<3.2.4'
'<1.2.7||>=1.3.0,<1.3.1'
'>=1.1.0,<1.1.4||>=1.2.0,<1.2.5'
'>=2.2,<2.2.26||>=3.2,<3.2.11||>=4.0,<4.0.1'
'>=1.10.0,<=1.10.7||>=1.11.0,<=1.11.4'
'>=1.1.0,<1.1.4||>=1.2.0,<1.2.5'
'>=1.9.0alpha,<1.9.10||<1.8.15'

Unsupported Pypi versions

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2019-120' InvalidVersion("'2.2.0-dev' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2019-6' InvalidVersion("'0.7.10p1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2008-3' InvalidVersion("'2.0.0-final' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2006-1' InvalidVersion("'2.0.0-final' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2020-230' InvalidVersion("'0.1.0-dev' is not a valid <class 'univers.versions.PypiVersion'>")
Invalid Version - PypiVersion - 'PYSEC-2021-371' - '0.2.0-n653'
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2021-428' InvalidVersion("'0.1.0.dev' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2021-356' InvalidVersion("'2.0.1rc2-git' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2019-106' InvalidVersion("'2.0.1rc2-git' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2022-5' InvalidVersion("'2.0.1rc2-git' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2021-859' InvalidVersion("'2.0.1rc2-git' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2017-41' InvalidVersion("'a3' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2019-126' InvalidVersion("'a3' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2019-102' InvalidVersion("'2013-01-21T20:33:09+0100' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2018-19' InvalidVersion("'0.1-bulbasaur' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2022-166' InvalidVersion("'0.1-bulbasaur' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2008-8' InvalidVersion("'0.1-bulbasaur' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2020-341' InvalidVersion("'-class.-jw.util.version.Version-' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2017-103' InvalidVersion("'1.0beta6.1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2017-47' InvalidVersion("'0.7.1.fix1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2022-12' InvalidVersion("'0.7.1.fix1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2017-46' InvalidVersion("'0.7.1.fix1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2015-24' InvalidVersion("'0.7.1.fix1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2015-25' InvalidVersion("'0.7.1.fix1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2022-34' InvalidVersion("'0.2.4dev' is not a valid <class 'univers.versions.PypiVersion'>")
NotImplementedError GIT Version - 'PYSEC-2022-34' - '65ab7d5caaaf2f95e61f9dd65441801c2ddee38b'
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2019-23' InvalidVersion("'0.2.4dev' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2022-167' InvalidVersion("'0.2.4dev' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2018-114' InvalidVersion("'0.3.1-p1' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2018-115' InvalidVersion("'0.3.1-p1' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2021-97' InvalidVersion("'1dev' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2021-338' InvalidVersion("'4.11-final' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2018-100' InvalidVersion("'0.3m1' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2021-121' InvalidVersion("'trunk' is not a valid <class 'univers.versions.PypiVersion'>")

InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2020-216' InvalidVersion("'1.3.1dev' is not a valid <class 'univers.versions.PypiVersion'>")
InvalidVersionRange affected_pkg_version_range Error - 'PYSEC-2012-1' InvalidVersion("'1.3.1dev' is not a valid <class 'univers.versions.PypiVersion'>")

https://github.com/pypa/advisory-database

NpmVersionRange.from_native not working

>>> from univers.version_range import NpmVersionRange
>>> NpmVersionRange.from_native(">=6.1.3")
Traceback (most recent call last):
  File "/home/ziad/Desktop/open_source/vulnerablecode/venv/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3553, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-6-7be7de982c98>", line 1, in <module>
    NpmVersionRange.from_native(">=6.1.3")
  File "/home/ziad/Desktop/open_source/vulnerablecode/venv/lib/python3.7/site-packages/univers/version_range.py", line 251, in from_native
    assert isinstance(clause, (AnyOf, AllOf))
AssertionError

VersionRange objects are unhashable

Is this by design ? It doesn't seem like it because of hash=True in

@attr.s(frozen=True, order=False, eq=True, hash=True)

>>> vr = NginxVersionRange.from_string("vers:nginx/3")
>>> X = set()
>>> X.add(vr)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-25340b8f0bdf> in <module>
----> 1 X.add(vr)

<attrs generated hash univers.version_range.VersionRange> in __hash__(self)
      1 def __hash__(self):
----> 2         return hash((
      3                 938370967647186531,
      4                 self.constraints,
      5             ))
TypeError: unhashable type: 'list'

NuGet isn't strictly SemVer

Similar to #5 (thank you so much for fixing it!!), it looks like NuGet is also assumed to be SemVer:

class NugetVersion(SemverVersion):

However, NuGet's documentation shows list important differences:

NuGetVersion supports a 4th version segment, Revision, to be compatible with, or a superset of, System.Version. Therefore, excluding prerelease and metadata labels, a version string is Major.Minor.Patch.Revision. As per version normalization described above, if Revision is zero, it is omit from the normalized version string.

NuGetVersion only requires the major segment to be defined. All others are optional, and are equivalent to zero. This means that 1, 1.0, 1.0.0, and 1.0.0.0 are all accepted and equal.

NuGetVersion uses case insenstive string comparisons for pre-release components. This means that 1.0.0-alpha and 1.0.0-Alpha are equal.

The current implementation does not follow these rules:

> NugetVersion('1.0.0.0') < 'NugetVersion('1.0.0.1')
> False 
>>> NugetVersion('1.0.0-Alpha') == NugetVersion('1.0.0-alpha')
False

Nuget's implementation appears to be here: https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Versioning/NuGetVersion.cs

Cannot parse `vers:nginx/*`

>>> VersionRange.from_string("vers:nginx/*")
---------------------------------------------------------------------------
InvalidVersion                            Traceback (most recent call last)
<ipython-input-17-2f9540ab85ba> in <module>
----> 1 VersionRange.from_string("vers:nginx/*")

~/Contrib/vulnerablecode/venv/lib/python3.10/site-packages/univers/version_range.py in from_string(cls, vers)
     84             and_constraints = []
     85             for constraint in or_constraints.split(","):
---> 86                 constraint = VersionConstraint.from_string(
     87                     string=constraint,
     88                     version_class=range_class.version_class,

~/Contrib/vulnerablecode/venv/lib/python3.10/site-packages/univers/version_constraint.py in from_string(cls, string, version_class)
     97             raise ValueError("Empty version")
     98
---> 99         version = version_class(version)
    100         return cls(comparator, version)
    101

~/Contrib/vulnerablecode/venv/lib/python3.10/site-packages/univers/versions.py in __init__(self, string, normalized_string, value)
      5     _inst_dict['normalized_string'] = normalized_string
      6     _inst_dict['value'] = value
----> 7     self.__attrs_post_init__()

~/Contrib/vulnerablecode/venv/lib/python3.10/site-packages/univers/versions.py in __attrs_post_init__(self)
     57         normalized_string = self.normalize(self.string)
     58         if not self.is_valid(normalized_string):
---> 59             raise InvalidVersion(f"{self.string!r} is not a valid {self.__class__!r}")
     60
     61         # See https://www.attrs.org/en/stable/init.html?#post-init

InvalidVersion: '' is not a valid <class 'univers.versions.SemverVersion'>

This happens because there's no version information available for * version constraint and yet creation of a version is attempted:

version = version_class(version)
return cls(comparator, version)

This can be solved by accepting #10

Univers decides to explode when truth is violated

>>> from univers.version_range import NginxVersionRange
>>> rng = NginxVersionRange.from_string('vers:nginx/>=1.9.5|<=1.17.2')
>>> SemverVersion("1.9.8") in rng
True
>>> SemverVersion("1.9.5") in rng
True
>>> SemverVersion("1.9.4") in rng
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-92-15259a3594cd> in <module>
----> 1 SemverVersion("1.9.4") in rng

~/Contrib/univers/src/univers/version_range.py in __contains__(self, version)
    159                 f"{version!r} is not of expected type: {self.version_class!r}",
    160             )
--> 161         return contains_version(version, self.constraints)
    162
    163     contains = __contains__

~/Contrib/univers/src/univers/version_constraint.py in contains_version(version, constraints)
    503         else:
    504             # this should never happen as the constraints must be valid going in
--> 505             raise Exception(f"Invalid constraints sequence: {constraints }")
    506
    507     # If this is the last iteration and next comparator is ">" or >="

Exception: Invalid constraints sequence: [VersionConstraint(comparator='>=', version=SemverVersion(string='1.9.5')), VersionConstraint(comparator='<=', version=SemverVersion(string='1.17.2'))]

Last statement should have just returned False

rubygems is not semver

e.g. rails: https://rubygems.org/gems/rails/versions/6.1.3.2

I see you try to coerce this into a semver:

object.__setattr__(self, "value", semantic_version.Version.coerce(version_string))

but this isn't correct, because it gets coerced to "6.1.3+2". and the "+2" part is not considered for ordering purposes per https://semver.org/spec/v2.0.0.html#spec-item-11

>>> SemverVersion('6.1.3.2') < SemverVersion('6.1.3.3')
False

See also https://snyk.io/blog/differences-in-version-handling-gems-and-npm/ for more issues with trying to handle ruby versions as semver.

Other ecosystems may have similar problems. E.g. composer recommends following semver, but it also doesn't enforce it: https://getcomposer.org/doc/articles/versions.md

Failure to recognize a valid Debian version

>>> from univers.debian import Version
>>> v = Version.from_string("1:1.12_1.12.6-1+deb9u1build0.18.04.1" )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pombreda/w421/vulnerablecode/venv/lib/python3.8/site-packages/univers/debian.py", line 130, in from_string
    raise ValueError('Invalid version string: "{}"'.format(version))
ValueError: Invalid version string: "1:1.12_1.12.6-1+deb9u1build0.18.04.1"
>>> 

This was found in https://ubuntu.com/security/CVE-2018-1999023 for https://tracker.debian.org/pkg/wesnoth-1.12

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.