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(a)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)
--
2.4.3