From 0077f29d716d946fec1380ac5fa540573008abd2 Mon Sep 17 00:00:00 2001 From: Seth Kinast Date: Wed, 13 Feb 2019 21:14:05 -0800 Subject: [PATCH] gluon.validators: update IS_STRONG to behave as it did in web2py < 2.15 We used to compare `type(self.upper) == int` but the check was changed to `isinstance(self.upper, int)`. Because bool is an instance of int but is not the type int, the meaning of the checks changed to treat False as 0. This patch specifically differentiates between False and 0. - False means "no requirements for this character class". - 0 means "exactly 0 of this character class". Fixes #2093 --- gluon/tests/test_validators.py | 8 ++++++++ gluon/validators.py | 10 +++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/gluon/tests/test_validators.py b/gluon/tests/test_validators.py index 8afccc5a..6f07dc73 100644 --- a/gluon/tests/test_validators.py +++ b/gluon/tests/test_validators.py @@ -943,6 +943,14 @@ class TestValidators(unittest.TestCase): 'May not include any lowercase letters', 'May not include any numbers'])) ) + rtn = IS_STRONG(special=0, es=True)('Abcde1!') + self.assertEqual(rtn, + ('Abcde1!', + '|'.join(['Minimum length is 8', + 'May not contain any of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|'])) + ) + rtn = IS_STRONG(upper=False, number=False, special=False, es=True)('Abcde1!') + self.assertEqual(rtn, ('Abcde1!', 'Minimum length is 8')) def test_IS_IMAGE(self): class DummyImageFile(object): diff --git a/gluon/validators.py b/gluon/validators.py index f3da9cc1..f9b494e0 100644 --- a/gluon/validators.py +++ b/gluon/validators.py @@ -3163,6 +3163,10 @@ class IS_STRONG(object): if not all_special.count(True) >= self.special: failures.append(translate("Must include at least %s of the following: %s") % (self.special, self.specials)) + elif self.special is 0: + if len(all_special) > 0: + failures.append(translate("May not contain any of the following: %s") + % self.specials) if self.invalid: all_invalid = [ch in value for ch in self.invalid] if all_invalid.count(True) > 0: @@ -3174,7 +3178,7 @@ class IS_STRONG(object): if not len(all_upper) >= self.upper: failures.append(translate("Must include at least %s uppercase") % str(self.upper)) - else: + elif self.upper is 0: if len(all_upper) > 0: failures.append( translate("May not include any uppercase letters")) @@ -3184,7 +3188,7 @@ class IS_STRONG(object): if not len(all_lower) >= self.lower: failures.append(translate("Must include at least %s lowercase") % str(self.lower)) - else: + elif self.lower is 0: if len(all_lower) > 0: failures.append( translate("May not include any lowercase letters")) @@ -3197,7 +3201,7 @@ class IS_STRONG(object): if not len(all_number) >= self.number: failures.append(translate("Must include at least %s %s") % (str(self.number), numbers)) - else: + elif self.number is 0: if len(all_number) > 0: failures.append(translate("May not include any numbers")) if len(failures) == 0: