semver 6.3.0 → 6.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +19 -9
  2. package/semver.js +71 -24
  3. package/CHANGELOG.md +0 -70
package/package.json CHANGED
@@ -1,19 +1,26 @@
1
1
  {
2
2
  "name": "semver",
3
- "version": "6.3.0",
3
+ "version": "6.3.1",
4
4
  "description": "The semantic version parser used by npm.",
5
5
  "main": "semver.js",
6
6
  "scripts": {
7
- "test": "tap",
8
- "preversion": "npm test",
9
- "postversion": "npm publish",
10
- "postpublish": "git push origin --follow-tags"
7
+ "test": "tap test/ --100 --timeout=30",
8
+ "lint": "echo linting disabled",
9
+ "postlint": "template-oss-check",
10
+ "template-oss-apply": "template-oss-apply --force",
11
+ "lintfix": "npm run lint -- --fix",
12
+ "snap": "tap test/ --100 --timeout=30",
13
+ "posttest": "npm run lint"
11
14
  },
12
15
  "devDependencies": {
13
- "tap": "^14.3.1"
16
+ "@npmcli/template-oss": "4.17.0",
17
+ "tap": "^12.7.0"
14
18
  },
15
19
  "license": "ISC",
16
- "repository": "https://github.com/npm/node-semver",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/npm/node-semver.git"
23
+ },
17
24
  "bin": {
18
25
  "semver": "./bin/semver.js"
19
26
  },
@@ -22,7 +29,10 @@
22
29
  "range.bnf",
23
30
  "semver.js"
24
31
  ],
25
- "tap": {
26
- "check-coverage": true
32
+ "author": "GitHub Inc.",
33
+ "templateOSS": {
34
+ "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
35
+ "content": "./scripts/template-oss",
36
+ "version": "4.17.0"
27
37
  }
28
38
  }
package/semver.js CHANGED
@@ -26,8 +26,11 @@ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
26
26
  // Max safe segment length for coercion.
27
27
  var MAX_SAFE_COMPONENT_LENGTH = 16
28
28
 
29
+ var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6
30
+
29
31
  // The actual regexps go on exports.re
30
32
  var re = exports.re = []
33
+ var safeRe = exports.safeRe = []
31
34
  var src = exports.src = []
32
35
  var t = exports.tokens = {}
33
36
  var R = 0
@@ -36,6 +39,31 @@ function tok (n) {
36
39
  t[n] = R++
37
40
  }
38
41
 
42
+ var LETTERDASHNUMBER = '[a-zA-Z0-9-]'
43
+
44
+ // Replace some greedy regex tokens to prevent regex dos issues. These regex are
45
+ // used internally via the safeRe object since all inputs in this library get
46
+ // normalized first to trim and collapse all extra whitespace. The original
47
+ // regexes are exported for userland consumption and lower level usage. A
48
+ // future breaking change could export the safer regex only with a note that
49
+ // all input should have extra whitespace removed.
50
+ var safeRegexReplacements = [
51
+ ['\\s', 1],
52
+ ['\\d', MAX_LENGTH],
53
+ [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
54
+ ]
55
+
56
+ function makeSafeRe (value) {
57
+ for (var i = 0; i < safeRegexReplacements.length; i++) {
58
+ var token = safeRegexReplacements[i][0]
59
+ var max = safeRegexReplacements[i][1]
60
+ value = value
61
+ .split(token + '*').join(token + '{0,' + max + '}')
62
+ .split(token + '+').join(token + '{1,' + max + '}')
63
+ }
64
+ return value
65
+ }
66
+
39
67
  // The following Regular Expressions can be used for tokenizing,
40
68
  // validating, and parsing SemVer version strings.
41
69
 
@@ -45,14 +73,14 @@ function tok (n) {
45
73
  tok('NUMERICIDENTIFIER')
46
74
  src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*'
47
75
  tok('NUMERICIDENTIFIERLOOSE')
48
- src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+'
76
+ src[t.NUMERICIDENTIFIERLOOSE] = '\\d+'
49
77
 
50
78
  // ## Non-numeric Identifier
51
79
  // Zero or more digits, followed by a letter or hyphen, and then zero or
52
80
  // more letters, digits, or hyphens.
53
81
 
54
82
  tok('NONNUMERICIDENTIFIER')
55
- src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'
83
+ src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*'
56
84
 
57
85
  // ## Main Version
58
86
  // Three dot-separated numeric identifiers.
@@ -94,7 +122,7 @@ src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] +
94
122
  // Any combination of digits, letters, or hyphens.
95
123
 
96
124
  tok('BUILDIDENTIFIER')
97
- src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+'
125
+ src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+'
98
126
 
99
127
  // ## Build Metadata
100
128
  // Plus sign, followed by one or more period-separated build metadata
@@ -174,6 +202,7 @@ src[t.COERCE] = '(^|[^\\d])' +
174
202
  '(?:$|[^\\d])'
175
203
  tok('COERCERTL')
176
204
  re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g')
205
+ safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g')
177
206
 
178
207
  // Tilde ranges.
179
208
  // Meaning is "reasonably at or greater than"
@@ -183,6 +212,7 @@ src[t.LONETILDE] = '(?:~>?)'
183
212
  tok('TILDETRIM')
184
213
  src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+'
185
214
  re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g')
215
+ safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g')
186
216
  var tildeTrimReplace = '$1~'
187
217
 
188
218
  tok('TILDE')
@@ -198,6 +228,7 @@ src[t.LONECARET] = '(?:\\^)'
198
228
  tok('CARETTRIM')
199
229
  src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+'
200
230
  re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g')
231
+ safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g')
201
232
  var caretTrimReplace = '$1^'
202
233
 
203
234
  tok('CARET')
@@ -219,6 +250,7 @@ src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] +
219
250
 
220
251
  // this one has to use the /g flag
221
252
  re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g')
253
+ safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g')
222
254
  var comparatorTrimReplace = '$1$2$3'
223
255
 
224
256
  // Something like `1.2.3 - 1.2.4`
@@ -247,6 +279,14 @@ for (var i = 0; i < R; i++) {
247
279
  debug(i, src[i])
248
280
  if (!re[i]) {
249
281
  re[i] = new RegExp(src[i])
282
+
283
+ // Replace all greedy whitespace to prevent regex dos issues. These regex are
284
+ // used internally via the safeRe object since all inputs in this library get
285
+ // normalized first to trim and collapse all extra whitespace. The original
286
+ // regexes are exported for userland consumption and lower level usage. A
287
+ // future breaking change could export the safer regex only with a note that
288
+ // all input should have extra whitespace removed.
289
+ safeRe[i] = new RegExp(makeSafeRe(src[i]))
250
290
  }
251
291
  }
252
292
 
@@ -271,7 +311,7 @@ function parse (version, options) {
271
311
  return null
272
312
  }
273
313
 
274
- var r = options.loose ? re[t.LOOSE] : re[t.FULL]
314
+ var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]
275
315
  if (!r.test(version)) {
276
316
  return null
277
317
  }
@@ -326,7 +366,7 @@ function SemVer (version, options) {
326
366
  this.options = options
327
367
  this.loose = !!options.loose
328
368
 
329
- var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
369
+ var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL])
330
370
 
331
371
  if (!m) {
332
372
  throw new TypeError('Invalid Version: ' + version)
@@ -771,6 +811,7 @@ function Comparator (comp, options) {
771
811
  return new Comparator(comp, options)
772
812
  }
773
813
 
814
+ comp = comp.trim().split(/\s+/).join(' ')
774
815
  debug('comparator', comp, options)
775
816
  this.options = options
776
817
  this.loose = !!options.loose
@@ -787,7 +828,7 @@ function Comparator (comp, options) {
787
828
 
788
829
  var ANY = {}
789
830
  Comparator.prototype.parse = function (comp) {
790
- var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
831
+ var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]
791
832
  var m = comp.match(r)
792
833
 
793
834
  if (!m) {
@@ -911,9 +952,16 @@ function Range (range, options) {
911
952
  this.loose = !!options.loose
912
953
  this.includePrerelease = !!options.includePrerelease
913
954
 
914
- // First, split based on boolean or ||
955
+ // First reduce all whitespace as much as possible so we do not have to rely
956
+ // on potentially slow regexes like \s*. This is then stored and used for
957
+ // future error messages as well.
915
958
  this.raw = range
916
- this.set = range.split(/\s*\|\|\s*/).map(function (range) {
959
+ .trim()
960
+ .split(/\s+/)
961
+ .join(' ')
962
+
963
+ // First, split based on boolean or ||
964
+ this.set = this.raw.split('||').map(function (range) {
917
965
  return this.parseRange(range.trim())
918
966
  }, this).filter(function (c) {
919
967
  // throw out any that are not relevant for whatever reason
@@ -921,7 +969,7 @@ function Range (range, options) {
921
969
  })
922
970
 
923
971
  if (!this.set.length) {
924
- throw new TypeError('Invalid SemVer Range: ' + range)
972
+ throw new TypeError('Invalid SemVer Range: ' + this.raw)
925
973
  }
926
974
 
927
975
  this.format()
@@ -940,20 +988,19 @@ Range.prototype.toString = function () {
940
988
 
941
989
  Range.prototype.parseRange = function (range) {
942
990
  var loose = this.options.loose
943
- range = range.trim()
944
991
  // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
945
- var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
992
+ var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE]
946
993
  range = range.replace(hr, hyphenReplace)
947
994
  debug('hyphen replace', range)
948
995
  // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
949
- range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
950
- debug('comparator trim', range, re[t.COMPARATORTRIM])
996
+ range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace)
997
+ debug('comparator trim', range, safeRe[t.COMPARATORTRIM])
951
998
 
952
999
  // `~ 1.2.3` => `~1.2.3`
953
- range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
1000
+ range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace)
954
1001
 
955
1002
  // `^ 1.2.3` => `^1.2.3`
956
- range = range.replace(re[t.CARETTRIM], caretTrimReplace)
1003
+ range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace)
957
1004
 
958
1005
  // normalize spaces
959
1006
  range = range.split(/\s+/).join(' ')
@@ -961,7 +1008,7 @@ Range.prototype.parseRange = function (range) {
961
1008
  // At this point, the range is completely trimmed and
962
1009
  // ready to be split into comparators.
963
1010
 
964
- var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
1011
+ var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]
965
1012
  var set = range.split(' ').map(function (comp) {
966
1013
  return parseComparator(comp, this.options)
967
1014
  }, this).join(' ').split(/\s+/)
@@ -1061,7 +1108,7 @@ function replaceTildes (comp, options) {
1061
1108
  }
1062
1109
 
1063
1110
  function replaceTilde (comp, options) {
1064
- var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
1111
+ var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE]
1065
1112
  return comp.replace(r, function (_, M, m, p, pr) {
1066
1113
  debug('tilde', comp, _, M, m, p, pr)
1067
1114
  var ret
@@ -1102,7 +1149,7 @@ function replaceCarets (comp, options) {
1102
1149
 
1103
1150
  function replaceCaret (comp, options) {
1104
1151
  debug('caret', comp, options)
1105
- var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]
1152
+ var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET]
1106
1153
  return comp.replace(r, function (_, M, m, p, pr) {
1107
1154
  debug('caret', comp, _, M, m, p, pr)
1108
1155
  var ret
@@ -1161,7 +1208,7 @@ function replaceXRanges (comp, options) {
1161
1208
 
1162
1209
  function replaceXRange (comp, options) {
1163
1210
  comp = comp.trim()
1164
- var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]
1211
+ var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE]
1165
1212
  return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
1166
1213
  debug('xRange', comp, ret, gtlt, M, m, p, pr)
1167
1214
  var xM = isX(M)
@@ -1236,7 +1283,7 @@ function replaceXRange (comp, options) {
1236
1283
  function replaceStars (comp, options) {
1237
1284
  debug('replaceStars', comp, options)
1238
1285
  // Looseness is ignored here. star is always as loose as it gets!
1239
- return comp.trim().replace(re[t.STAR], '')
1286
+ return comp.trim().replace(safeRe[t.STAR], '')
1240
1287
  }
1241
1288
 
1242
1289
  // This function is passed to string.replace(re[t.HYPHENRANGE])
@@ -1562,7 +1609,7 @@ function coerce (version, options) {
1562
1609
 
1563
1610
  var match = null
1564
1611
  if (!options.rtl) {
1565
- match = version.match(re[t.COERCE])
1612
+ match = version.match(safeRe[t.COERCE])
1566
1613
  } else {
1567
1614
  // Find the right-most coercible string that does not share
1568
1615
  // a terminus with a more left-ward coercible string.
@@ -1573,17 +1620,17 @@ function coerce (version, options) {
1573
1620
  // Stop when we get a match that ends at the string end, since no
1574
1621
  // coercible string can be more right-ward without the same terminus.
1575
1622
  var next
1576
- while ((next = re[t.COERCERTL].exec(version)) &&
1623
+ while ((next = safeRe[t.COERCERTL].exec(version)) &&
1577
1624
  (!match || match.index + match[0].length !== version.length)
1578
1625
  ) {
1579
1626
  if (!match ||
1580
1627
  next.index + next[0].length !== match.index + match[0].length) {
1581
1628
  match = next
1582
1629
  }
1583
- re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length
1630
+ safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length
1584
1631
  }
1585
1632
  // leave it in a clean state
1586
- re[t.COERCERTL].lastIndex = -1
1633
+ safeRe[t.COERCERTL].lastIndex = -1
1587
1634
  }
1588
1635
 
1589
1636
  if (match === null) {
package/CHANGELOG.md DELETED
@@ -1,70 +0,0 @@
1
- # changes log
2
-
3
- ## 6.2.0
4
-
5
- * Coerce numbers to strings when passed to semver.coerce()
6
- * Add `rtl` option to coerce from right to left
7
-
8
- ## 6.1.3
9
-
10
- * Handle X-ranges properly in includePrerelease mode
11
-
12
- ## 6.1.2
13
-
14
- * Do not throw when testing invalid version strings
15
-
16
- ## 6.1.1
17
-
18
- * Add options support for semver.coerce()
19
- * Handle undefined version passed to Range.test
20
-
21
- ## 6.1.0
22
-
23
- * Add semver.compareBuild function
24
- * Support `*` in semver.intersects
25
-
26
- ## 6.0
27
-
28
- * Fix `intersects` logic.
29
-
30
- This is technically a bug fix, but since it is also a change to behavior
31
- that may require users updating their code, it is marked as a major
32
- version increment.
33
-
34
- ## 5.7
35
-
36
- * Add `minVersion` method
37
-
38
- ## 5.6
39
-
40
- * Move boolean `loose` param to an options object, with
41
- backwards-compatibility protection.
42
- * Add ability to opt out of special prerelease version handling with
43
- the `includePrerelease` option flag.
44
-
45
- ## 5.5
46
-
47
- * Add version coercion capabilities
48
-
49
- ## 5.4
50
-
51
- * Add intersection checking
52
-
53
- ## 5.3
54
-
55
- * Add `minSatisfying` method
56
-
57
- ## 5.2
58
-
59
- * Add `prerelease(v)` that returns prerelease components
60
-
61
- ## 5.1
62
-
63
- * Add Backus-Naur for ranges
64
- * Remove excessively cute inspection methods
65
-
66
- ## 5.0
67
-
68
- * Remove AMD/Browserified build artifacts
69
- * Fix ltr and gtr when using the `*` range
70
- * Fix for range `*` with a prerelease identifier