Skip to content

Commit 8a34bde

Browse files
authored
fix: add identifier validation to inc() (#754)
- Adds a check of the `identifier` parameter for `inc()` when trying to increase pre-releases. This prevents the creation of an invalid semver. - Removes side-effects of `inc()` when it is throwing (it was changing the version) Closes #349
1 parent 0864b3c commit 8a34bde

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

classes/semver.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,19 @@ class SemVer {
176176
// preminor will bump the version up to the next minor release, and immediately
177177
// down to pre-release. premajor and prepatch work the same way.
178178
inc (release, identifier, identifierBase) {
179+
if (release.startsWith('pre')) {
180+
if (!identifier && identifierBase === false) {
181+
throw new Error('invalid increment argument: identifier is empty')
182+
}
183+
// Avoid an invalid semver results
184+
if (identifier) {
185+
const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE])
186+
if (!match || match[1] !== identifier) {
187+
throw new Error(`invalid identifier: ${identifier}`)
188+
}
189+
}
190+
}
191+
179192
switch (release) {
180193
case 'premajor':
181194
this.prerelease.length = 0
@@ -255,10 +268,6 @@ class SemVer {
255268
case 'pre': {
256269
const base = Number(identifierBase) ? 1 : 0
257270

258-
if (!identifier && identifierBase === false) {
259-
throw new Error('invalid increment argument: identifier is empty')
260-
}
261-
262271
if (this.prerelease.length === 0) {
263272
this.prerelease = [base]
264273
} else {

test/classes/semver.js

+28
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,34 @@ test('incrementing', t => {
106106
}))
107107
})
108108

109+
test('invalid increments', (t) => {
110+
t.throws(
111+
() => new SemVer('1.2.3').inc('prerelease', '', false),
112+
Error('invalid increment argument: identifier is empty')
113+
)
114+
t.throws(
115+
() => new SemVer('1.2.3-dev').inc('prerelease', 'dev', false),
116+
Error('invalid increment argument: identifier already exists')
117+
)
118+
t.throws(
119+
() => new SemVer('1.2.3').inc('prerelease', 'invalid/preid'),
120+
Error('invalid identifier: invalid/preid')
121+
)
122+
123+
t.end()
124+
})
125+
126+
test('increment side-effects', (t) => {
127+
const v = new SemVer('1.0.0')
128+
try {
129+
v.inc('prerelease', 'hot/mess')
130+
} catch (er) {
131+
// ignore but check that the version has not changed
132+
}
133+
t.equal(v.toString(), '1.0.0')
134+
t.end()
135+
})
136+
109137
test('compare main vs pre', (t) => {
110138
const s = new SemVer('1.2.3')
111139
t.equal(s.compareMain('2.3.4'), -1)

test/fixtures/increments.js

+3
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,7 @@ module.exports = [
129129
['1.2.0-dev', 'prepatch', '1.2.1-dev', false, 'dev', false],
130130
['1.2.0', 'prerelease', null, false, '', false],
131131
['1.0.0-rc.1+build.4', 'prerelease', '1.0.0-rc.2', 'rc', false],
132+
['1.2.0', 'prerelease', null, false, 'invalid/preid'],
133+
['1.2.0', 'prerelease', null, false, 'invalid+build'],
134+
['1.2.0beta', 'prerelease', null, { loose: true }, 'invalid/preid'],
132135
]

0 commit comments

Comments
 (0)