From 017a66b5f9835b913f0260979b3cd3e126a0a4b7 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 28 Feb 2024 11:41:36 -0600 Subject: [PATCH 1/4] Fixes: #13722 - Correct range expansion code when a numeric set is used --- netbox/utilities/forms/utils.py | 2 +- netbox/utilities/tests/test_forms.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 689fbebbf52..005b8be85a2 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -60,7 +60,7 @@ def parse_alphanumeric_range(string): return [] except ValueError: begin, end = dash_range, dash_range - if begin.isdigit() and end.isdigit(): + if begin.isdigit() and end.isdigit() and not begin == end: if int(begin) >= int(end): raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) diff --git a/netbox/utilities/tests/test_forms.py b/netbox/utilities/tests/test_forms.py index d014d4bbd36..aab9af87022 100644 --- a/netbox/utilities/tests/test_forms.py +++ b/netbox/utilities/tests/test_forms.py @@ -191,7 +191,16 @@ def test_range_alpha(self): 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' output = sorted([ 'r1a', From 221e095f1d7e0b8e58b3c5bb52c4e7c62adf8ab2 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 28 Feb 2024 11:50:47 -0600 Subject: [PATCH 2/4] Correct to my own suggestion --- netbox/utilities/forms/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 005b8be85a2..1bd967b0667 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -60,7 +60,9 @@ def parse_alphanumeric_range(string): return [] except ValueError: begin, end = dash_range, dash_range - if begin.isdigit() and end.isdigit() and not begin == end: + if begin == end: + values.append(begin) + elif begin.isdigit() and end.isdigit(): if int(begin) >= int(end): raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) From 665ea402f68800e82a06eae352ddf31acf1fe45b Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 28 Feb 2024 11:59:21 -0600 Subject: [PATCH 3/4] Clean up logic --- netbox/utilities/forms/utils.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 1bd967b0667..6ea25b8e794 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -60,29 +60,28 @@ def parse_alphanumeric_range(string): return [] except ValueError: begin, end = dash_range, dash_range + + # Value-based if begin == end: values.append(begin) + # Numeric range-based elif begin.isdigit() and end.isdigit(): if int(begin) >= int(end): raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) for n in list(range(int(begin), int(end) + 1)): values.append(n) + # Range-based else: - # Value-based - if begin == end: - values.append(begin) - # Range-based - else: - # Not a valid range (more than a single character) - if not len(begin) == len(end) == 1: - 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)) + # Not a valid range (more than a single character) + if not len(begin) == len(end) == 1: + 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 From ad1298428fa013d80d9dcc034014509e78e0a2a5 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 11 Mar 2024 10:35:56 -0400 Subject: [PATCH 4/4] Simplify range detection --- netbox/utilities/forms/utils.py | 36 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 6ea25b8e794..0429fe5710e 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -51,37 +51,43 @@ def parse_alphanumeric_range(string): '0-3,a-d' => [0, 1, 2, 3, a, b, c, d] """ 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: - begin, end = dash_range.split('-') + begin, end = value.split('-') vals = begin + end # 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())): return [] except ValueError: - begin, end = dash_range, dash_range + raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value)) - # Value-based - if begin == end: - values.append(begin) - # Numeric range-based - elif begin.isdigit() and end.isdigit(): + # Numeric range + if begin.isdigit() and end.isdigit(): 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)): values.append(n) - # Range-based + + # Alphanumeric range else: # Not a valid range (more than a single character) if not len(begin) == len(end) == 1: - raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) - + raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value)) if ord(begin) >= ord(end): - raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) - + raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value)) for n in list(range(ord(begin), ord(end) + 1)): values.append(chr(n)) + return values