Skip to content

Commit 2961733

Browse files
committed
Validate version and alias names
1 parent 732a2de commit 2961733

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
- `mike alias` now checks for existing aliases to prevent erroneously setting an
2626
alias for two different versions
2727
- Replace `packaging` dependency with `verspec` for future stability
28+
- Validate version and alias names to ensure they're non-empty and don't
29+
contain a directory separator
2830

2931
[material-mike]: https://squidfunk.github.io/mkdocs-material/setup/setting-up-versioning/#versioning
3032

mike/versions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import re
23
from verspec.loose import LooseVersion as Version
34

45

@@ -14,13 +15,23 @@ def _version_pair(version):
1415

1516
class VersionInfo:
1617
def __init__(self, version, title=None, aliases=[]):
18+
self._check_version(str(version), 'version')
19+
for i in aliases:
20+
self._check_version(i, 'alias')
21+
1722
self.version, name = _version_pair(version)
1823
self.title = name if title is None else title
1924
self.aliases = set(aliases)
2025

2126
if name in self.aliases:
2227
raise ValueError('duplicated version and alias')
2328

29+
@staticmethod
30+
def _check_version(version, kind):
31+
if ( not version or version in ['.', '..'] or
32+
re.search(r'[\\/]', version) ):
33+
raise ValueError('{!r} is not a valid {}'.format(version, kind))
34+
2435
def __eq__(self, rhs):
2536
return (self.version == rhs.version and self.title == rhs.title and
2637
self.aliases == rhs.aliases)
@@ -39,6 +50,8 @@ def dumps(self):
3950
return json.dumps(self.to_json())
4051

4152
def update(self, title=None, aliases=[]):
53+
for i in aliases:
54+
self._check_version(i, 'alias')
4255
if title is not None:
4356
self.title = title
4457

test/unit/test_versions.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,27 @@ def test_create(self):
2727
self.assertEqual(v.title, '1.0')
2828
self.assertEqual(v.aliases, set())
2929

30-
with self.assertRaises(ValueError):
30+
with self.assertRaisesRegex(ValueError, "^'' is not a valid version$"):
31+
VersionInfo('')
32+
with self.assertRaisesRegex(ValueError,
33+
"^'..' is not a valid version$"):
34+
VersionInfo('..')
35+
with self.assertRaisesRegex(ValueError,
36+
"^'foo/bar' is not a valid version$"):
37+
VersionInfo('foo/bar')
38+
with self.assertRaisesRegex(ValueError,
39+
"^'foo/bar' is not a valid version$"):
40+
VersionInfo(Version('foo/bar'))
41+
42+
with self.assertRaisesRegex(ValueError, "^'' is not a valid alias$"):
43+
VersionInfo('1.0', aliases=['latest', ''])
44+
with self.assertRaisesRegex(ValueError, "^'..' is not a valid alias$"):
45+
VersionInfo('1.0', aliases=['..'])
46+
with self.assertRaisesRegex(ValueError,
47+
"^'foo/bar' is not a valid alias$"):
48+
VersionInfo('1.0', aliases=['foo/bar'])
49+
with self.assertRaisesRegex(ValueError,
50+
"^duplicated version and alias$"):
3151
VersionInfo('1.0', aliases=['1.0'])
3252

3353
def test_equality(self):
@@ -76,6 +96,14 @@ def test_update(self):
7696
'1.0', '1.0.1', ['latest', 'greatest']
7797
))
7898

99+
with self.assertRaisesRegex(ValueError, "^'' is not a valid alias$"):
100+
v.update(aliases=[''])
101+
with self.assertRaisesRegex(ValueError, "^'..' is not a valid alias$"):
102+
v.update(aliases=['..'])
103+
with self.assertRaisesRegex(ValueError,
104+
"^'foo/bar' is not a valid alias$"):
105+
v.update(aliases=['foo/bar'])
106+
79107

80108
class TestVersions(unittest.TestCase):
81109
def test_add(self):

0 commit comments

Comments
 (0)