Resolves: rhbz#1331054 --- pyanaconda/regexes.py | 3 ++ pyanaconda/ui/tui/spokes/network.py | 12 +++++-- tests/regex_tests/netmask_test.py | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 tests/regex_tests/netmask_test.py
diff --git a/pyanaconda/regexes.py b/pyanaconda/regexes.py index 2235d89..b99670b 100644 --- a/pyanaconda/regexes.py +++ b/pyanaconda/regexes.py @@ -89,6 +89,9 @@ IPV6_PATTERN_WITHOUT_ANCHORS = r'(?:' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,6}(?:[0-9a-fA-F]{1,4}))?::)' + \ r')'
+# IPv4 dotted-quad netmask validation +IPV4_NETMASK_WITHOUT_ANCHORS = r'((128|192|224|240|248|252|254).0.0.0)|(255.(((0|128|192|224|240|248|252|254).0.0)|(255.(((0|128|192|224|240|248|252|254).0)|255.(0|128|192|224|240|248|252|254)))))' + # Hostname validation # A hostname consists of sections separated by periods. Each of these sections # must be between 1 and 63 characters, contain only alphanumeric characters or diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index 131a92a..8701598 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -30,7 +30,7 @@ from pyanaconda.i18n import N_, _ from pyanaconda import network from pyanaconda import nm
-from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS +from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS, IPV4_NETMASK_WITHOUT_ANCHORS from pyanaconda.constants_text import INPUT_PROCESSED
import logging @@ -304,7 +304,7 @@ class ConfigureNetworkSpoke(EditTUISpoke): edit_fields = [ Entry(N_('IPv4 address or %s for DHCP') % '"dhcp"', "ip", re.compile("^(?:" + IPV4_PATTERN_WITHOUT_ANCHORS + "|dhcp)$"), True), - Entry(N_("IPv4 netmask"), "netmask", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True), + Entry(N_("IPv4 netmask"), "netmask", re.compile("^" + IPV4_NETMASK_WITHOUT_ANCHORS + "$"), True), Entry(N_("IPv4 gateway"), "gateway", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True), Entry(N_('IPv6 address or %(auto)s for automatic, %(dhcp)s for DHCP, %(ignore)s to turn off') % {"auto": '"auto"', "dhcp": '"dhcp"', "ignore": '"ignore"'}, "ipv6", @@ -324,7 +324,6 @@ class ConfigureNetworkSpoke(EditTUISpoke): if self.args.noipv6: self.args.ipv6 = "ignore" self.args._apply = False - self.dialog.wrong_input_message = _("Bad format of the IP address")
def refresh(self, args=None): """ Refresh window. """ @@ -333,6 +332,13 @@ class ConfigureNetworkSpoke(EditTUISpoke): self._window += [TextWidget(message), ""] return True
+ def input(self, args, key): + if self.edit_fields[int(key)-1].attribute == "netmask": + self.dialog.wrong_input_message = _("Bad format of the netmask") + else: + self.dialog.wrong_input_message = _("Bad format of the IP address") + return EditTUISpoke.input(self, args, key) + @property def indirect(self): return True diff --git a/tests/regex_tests/netmask_test.py b/tests/regex_tests/netmask_test.py new file mode 100644 index 0000000..c166636 --- /dev/null +++ b/tests/regex_tests/netmask_test.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# vim:set fileencoding=utf-8 +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Radek Vykydal rvykydal@redhat.com +# +import unittest +import re + +from pyanaconda.regexes import IPV4_NETMASK_WITHOUT_ANCHORS + +def _run_tests(testcase, expression, goodlist, badlist): + got_error = False + for good in goodlist: + try: + testcase.assertIsNotNone(expression.match(good)) + except AssertionError: + got_error = True + print("Good string %s did not match expression" % good) + + for bad in badlist: + try: + testcase.assertIsNone(expression.match(bad)) + except AssertionError: + got_error = True + print("Bad string %s matched expression" % bad) + + if got_error: + testcase.fail() + +class IPv4NetmaskTestCase(unittest.TestCase): + def netmask_test(self): + good_tests = [ + '255.255.255.0', + '255.255.0.0', + '255.255.255.254', + '128.0.0.0', + ] + + bad_tests = [ + '255.254.255.0', + '24', + '255', + '255.0', + '255.255.0', + '192.168.1.1', + '256.0.0.0' + '255.b.255.0', + '...', + '255...' + ] + + netmask_re = re.compile('^(' + IPV4_NETMASK_WITHOUT_ANCHORS + ')$') + _run_tests(self, netmask_re, good_tests, bad_tests)
On Fri, 2016-04-29 at 13:03 +0200, Radek Vykydal wrote:
Resolves: rhbz#1331054
pyanaconda/regexes.py | 3 ++ pyanaconda/ui/tui/spokes/network.py | 12 +++++-- tests/regex_tests/netmask_test.py | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 tests/regex_tests/netmask_test.py
diff --git a/pyanaconda/regexes.py b/pyanaconda/regexes.py index 2235d89..b99670b 100644 --- a/pyanaconda/regexes.py +++ b/pyanaconda/regexes.py @@ -89,6 +89,9 @@ IPV6_PATTERN_WITHOUT_ANCHORS = r'(?:' + \ r'(?:(?:(?:[0-9a-fA- F]{1,4}:){,6}(?:[0-9a-fA-F]{1,4}))?::)' + \ r')' +# IPv4 dotted-quad netmask validation +IPV4_NETMASK_WITHOUT_ANCHORS = r'((128|192|224|240|248|252|254).0.0.0)|(255.(((0|128|192|224|240 |248|252|254).0.0)|(255.(((0|128|192|224|240|248|252|254).0)|255\ .(0|128|192|224|240|248|252|254)))))'
# Hostname validation # A hostname consists of sections separated by periods. Each of these sections # must be between 1 and 63 characters, contain only alphanumeric characters or diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index 131a92a..8701598 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -30,7 +30,7 @@ from pyanaconda.i18n import N_, _ from pyanaconda import network from pyanaconda import nm -from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS +from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS, IPV4_NETMASK_WITHOUT_ANCHORS from pyanaconda.constants_text import INPUT_PROCESSED import logging @@ -304,7 +304,7 @@ class ConfigureNetworkSpoke(EditTUISpoke): edit_fields = [ Entry(N_('IPv4 address or %s for DHCP') % '"dhcp"', "ip", re.compile("^(?:" + IPV4_PATTERN_WITHOUT_ANCHORS + "|dhcp)$"), True), - Entry(N_("IPv4 netmask"), "netmask", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True), + Entry(N_("IPv4 netmask"), "netmask", re.compile("^" + IPV4_NETMASK_WITHOUT_ANCHORS + "$"), True), Entry(N_("IPv4 gateway"), "gateway", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True), Entry(N_('IPv6 address or %(auto)s for automatic, %(dhcp)s for DHCP, %(ignore)s to turn off') % {"auto": '"auto"', "dhcp": '"dhcp"', "ignore": '"ignore"'}, "ipv6", @@ -324,7 +324,6 @@ class ConfigureNetworkSpoke(EditTUISpoke): if self.args.noipv6: self.args.ipv6 = "ignore" self.args._apply = False - self.dialog.wrong_input_message = _("Bad format of the IP address") def refresh(self, args=None): """ Refresh window. """ @@ -333,6 +332,13 @@ class ConfigureNetworkSpoke(EditTUISpoke): self._window += [TextWidget(message), ""] return True + def input(self, args, key): + if self.edit_fields[int(key)-1].attribute == "netmask": + self.dialog.wrong_input_message = _("Bad format of the netmask") + else: + self.dialog.wrong_input_message = _("Bad format of the IP address") + return EditTUISpoke.input(self, args, key)
@property def indirect(self): return True diff --git a/tests/regex_tests/netmask_test.py b/tests/regex_tests/netmask_test.py new file mode 100644 index 0000000..c166636 --- /dev/null +++ b/tests/regex_tests/netmask_test.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# vim:set fileencoding=utf-8 +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Radek Vykydal rvykydal@redhat.com +# +import unittest +import re
+from pyanaconda.regexes import IPV4_NETMASK_WITHOUT_ANCHORS
+def _run_tests(testcase, expression, goodlist, badlist): + got_error = False + for good in goodlist: + try: + testcase.assertIsNotNone(expression.match(good)) + except AssertionError: + got_error = True + print("Good string %s did not match expression" % good)
+ for bad in badlist: + try: + testcase.assertIsNone(expression.match(bad)) + except AssertionError: + got_error = True + print("Bad string %s matched expression" % bad)
+ if got_error: + testcase.fail()
+class IPv4NetmaskTestCase(unittest.TestCase): + def netmask_test(self): + good_tests = [ + '255.255.255.0', + '255.255.0.0', + '255.255.255.254', + '128.0.0.0', + ]
+ bad_tests = [ + '255.254.255.0', + '24', + '255', + '255.0', + '255.255.0', + '192.168.1.1', + '256.0.0.0' + '255.b.255.0', + '...', + '255...' + ]
+ netmask_re = re.compile('^(' + IPV4_NETMASK_WITHOUT_ANCHORS
- ')$')
+ _run_tests(self, netmask_re, good_tests, bad_tests)
Looks good to me. Good work. ACK.
On Fri, Apr 29, 2016 at 01:03:13PM +0200, Radek Vykydal wrote:
+++ b/tests/regex_tests/netmask_test.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# vim:set fileencoding=utf-8 +# +# Copyright (C) 2014 Red Hat, Inc.
Should be 2016 :)
Looks good, thanks for also adding tests.
anaconda-patches@lists.fedorahosted.org