Skip to content

[BUG] range.bnf incomplete regarding whitespace and "spermies"Β #392

Open
@gnattishness

Description

What / Why

There are some discrepancies between what ranges are valid according to the BNF definition and the implementation.
As far as I'm aware, this implementation (or the BNF) is the "canonical" definition for NPM version ranges.

Every range abiding by the BNF is valid according to the implementation, but the implementation also accepts ranges as valid that are not in the BNF.

Where

How

Current Behavior

Implementation allows for whitespace within a "simple" range expression at the start of a "partial", but this does not abide by the BNF grammar.

Steps to Reproduce

Using latest release:

const semver = require('semver')

console.log(semver.validRange('>= 1.2.3 < 1.6.0', {loose: false} )) // >=1.2.3 <1.6.0
console.log(semver.validRange('^ 1.2.3 || ^ 2.4.6', {loose: false})) // >=1.2.3 <1.6.0

And tests involving

['> 1.0.0', '>1.0.0'],
['> 1.0.0', '>1.0.0'],
['<= 2.0.0', '<=2.0.0'],
['<= 2.0.0', '<=2.0.0'],
['<= 2.0.0', '<=2.0.0'],
['< 2.0.0', '<2.0.0'],
['<\t2.0.0', '<2.0.0'],

and
['~>1', '>=1.0.0 <2.0.0-0'],
['~> 1', '>=1.0.0 <2.0.0-0'],
['~1.0', '>=1.0.0 <1.1.0-0'],
['~ 1.0', '>=1.0.0 <1.1.0-0'],

pass, but are not valid according to the BNF.

In particular, there is no whitespace defined between comparison operators and the number:

node-semver/range.bnf

Lines 6 to 9 in e79ac3a

primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr ::= 'x' | 'X' | '*' | nr
nr ::= '0' | [1-9] ( [0-9] ) *

and the tilde definition does not allow for >:
tilde ::= '~' partial

Expected Behavior

Either:

  1. The BNF definition is expanded to allow whitespace between

  2. The implementation is restricted to match the BNF (e.g. only accept the ranges as valid when "loose"?)

    (this obviously has backwards compatibility issues)

  3. Document clearly that the implementation can parse and accept ranges outside of those defined in the BNF. (Though, perhaps will only ever return canonical ranges that comply with the BNF?)

If updating the grammar, the following change to be sufficient:

partial    ::= ( ' ' )* xr ( '.' xr ( '.' xr qualifier ? )? )?
...
tilde      ::= '~' ('>')? partial

Though the range definition could probably also be updated to reflect how multiple spaces are allowed:

range      ::= hyphen | simple ( ( ' ' )+ simple ) * | ''

Metadata

Assignees

No one assigned

    Labels

    Bugthing that needs fixing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions