Fixes: #13722 - Correct range expansion code when a numeric set is used (#15301)

* Fixes: #13722 - Correct range expansion code when a numeric set is used

* Correct to my own suggestion

* Clean up logic

* Simplify range detection

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Daniel Sheppard 2024-03-11 09:50:10 -05:00 committed by GitHub
parent f0e137133f
commit 1ff4e1287f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 19 deletions

View File

@ -51,36 +51,43 @@ def parse_alphanumeric_range(string):
'0-3,a-d' => [0, 1, 2, 3, a, b, c, d] '0-3,a-d' => [0, 1, 2, 3, a, b, c, d]
""" """
values = [] values = []
for dash_range in string.split(','): for value in string.split(','):
if '-' not in value:
# Item is not a range
values.append(value)
continue
# Find the range's beginning & end values
try: try:
begin, end = dash_range.split('-') begin, end = value.split('-')
vals = begin + end vals = begin + end
# Break out of loop if there's an invalid pattern to return an error # Break out of loop if there's an invalid pattern to return an error
if (not (vals.isdigit() or vals.isalpha())) or (vals.isalpha() and not (vals.isupper() or vals.islower())): if (not (vals.isdigit() or vals.isalpha())) or (vals.isalpha() and not (vals.isupper() or vals.islower())):
return [] return []
except ValueError: except ValueError:
begin, end = dash_range, dash_range raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value))
# Numeric range
if begin.isdigit() and end.isdigit(): if begin.isdigit() and end.isdigit():
if int(begin) >= int(end): if int(begin) >= int(end):
raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) raise forms.ValidationError(
_('Invalid range: Ending value ({end}) must be greater than beginning value ({begin}).').format(
begin=begin, end=end
)
)
for n in list(range(int(begin), int(end) + 1)): for n in list(range(int(begin), int(end) + 1)):
values.append(n) values.append(n)
# Alphanumeric range
else: else:
# Value-based # Not a valid range (more than a single character)
if begin == end: if not len(begin) == len(end) == 1:
values.append(begin) raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value))
# Range-based if ord(begin) >= ord(end):
else: raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value))
# Not a valid range (more than a single character) for n in list(range(ord(begin), ord(end) + 1)):
if not len(begin) == len(end) == 1: values.append(chr(n))
raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range))
if ord(begin) >= ord(end):
raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range))
for n in list(range(ord(begin), ord(end) + 1)):
values.append(chr(n))
return values return values

View File

@ -191,7 +191,16 @@ class ExpandAlphanumeric(TestCase):
self.assertEqual(sorted(expand_alphanumeric_pattern(input)), output) self.assertEqual(sorted(expand_alphanumeric_pattern(input)), output)
def test_set(self): def test_set_numeric(self):
input = 'r[1,2]a'
output = sorted([
'r1a',
'r2a',
])
self.assertEqual(sorted(expand_alphanumeric_pattern(input)), output)
def test_set_alpha(self):
input = '[r,t]1a' input = '[r,t]1a'
output = sorted([ output = sorted([
'r1a', 'r1a',