From 8cc4587b4ebd0a488db45dfdf51ce8ebbf562e0b Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sat, 8 Feb 2020 15:34:25 +0300 Subject: [PATCH] Stricter validation of *Time --- doc/news.rst | 2 ++ pyderasn.py | 36 ++++++++++++++-------------- tests/test_pyderasn.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/doc/news.rst b/doc/news.rst index b6b3e1b..90c894c 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -5,6 +5,8 @@ News 6.1 --- +* UTCTime and GeneralizedTime allowed values to have plus sign in them, + passing int() check successfully. Prohibit that incorrect behaviour * Explicitly Check that all ObjectIdentifier arcs are non-negative .. _release6.0: diff --git a/pyderasn.py b/pyderasn.py index 9e94184..7808029 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -4208,11 +4208,11 @@ class UTCTime(VisibleString): raise ValueError("non UTC timezone") return datetime( 2000 + int(value[:2]), # %y - int(value[2:4]), # %m - int(value[4:6]), # %d - int(value[6:8]), # %H - int(value[8:10]), # %M - int(value[10:12]), # %S + pureint(value[2:4]), # %m + pureint(value[4:6]), # %d + pureint(value[6:8]), # %H + pureint(value[8:10]), # %M + pureint(value[10:12]), # %S ) def _value_sanitize(self, value): @@ -4332,12 +4332,12 @@ class GeneralizedTime(UTCTime): if value[-1] != "Z": raise ValueError("non UTC timezone") return datetime( - int(value[:4]), # %Y - int(value[4:6]), # %m - int(value[6:8]), # %d - int(value[8:10]), # %H - int(value[10:12]), # %M - int(value[12:14]), # %S + pureint(value[:4]), # %Y + pureint(value[4:6]), # %m + pureint(value[6:8]), # %d + pureint(value[8:10]), # %H + pureint(value[10:12]), # %M + pureint(value[12:14]), # %S ) if l >= LEN_YYYYMMDDHHMMSSDMZ: # datetime.strptime's format: %Y%m%d%H%M%S.%fZ @@ -4351,14 +4351,14 @@ class GeneralizedTime(UTCTime): us_len = len(us) if us_len > 6: raise ValueError("only microsecond fractions are supported") - us = int(us + ("0" * (6 - us_len))) + us = pureint(us + ("0" * (6 - us_len))) decoded = datetime( - int(value[:4]), # %Y - int(value[4:6]), # %m - int(value[6:8]), # %d - int(value[8:10]), # %H - int(value[10:12]), # %M - int(value[12:14]), # %S + pureint(value[:4]), # %Y + pureint(value[4:6]), # %m + pureint(value[6:8]), # %d + pureint(value[8:10]), # %H + pureint(value[10:12]), # %M + pureint(value[12:14]), # %S us, # %f ) return decoded diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py index 630aead..f2e73b4 100644 --- a/tests/test_pyderasn.py +++ b/tests/test_pyderasn.py @@ -4054,6 +4054,35 @@ class TestGeneralizedTime(TimeMixin, CommonMixin, TestCase): with assertRaisesRegex(self, DecodeError, "only microsecond fractions"): GeneralizedTime(b"20010101000000.0000001Z") + def test_non_pure_integers(self): + for data in (( + # b"20000102030405Z, + b"+2000102030405Z", + b"2000+102030405Z", + b"200001+2030405Z", + b"20000102+30405Z", + b"2000010203+405Z", + b"200001020304+5Z", + b"20000102030405.+6Z", + b"20000102030405.-6Z", + b" 2000102030405Z", + b"2000 102030405Z", + b"200001 2030405Z", + b"20000102 30405Z", + b"2000010203 405Z", + b"200001020304 5Z", + b"20000102030405. 6Z", + b"200 0102030405Z", + b"20001 02030405Z", + b"2000012 030405Z", + b"200001023 0405Z", + b"20000102034 05Z", + b"2000010203045 Z", + b"20000102030405.6 Z", + )): + with self.assertRaises(DecodeError): + GeneralizedTime(data) + class TestUTCTime(TimeMixin, CommonMixin, TestCase): base_klass = UTCTime @@ -4124,6 +4153,31 @@ class TestUTCTime(TimeMixin, CommonMixin, TestCase): datetime(1991, 5, 6, 23, 45, 40, 0), ) + def test_non_pure_integers(self): + for data in (( + # b"000102030405Z", + b"+10102030405Z", + b"00+102030405Z", + b"0001+2030405Z", + b"000102+30405Z", + b"00010203+405Z", + b"0001020304+5Z", + b" 10102030405Z", + b"00 102030405Z", + b"0001 2030405Z", + b"000102 30405Z", + b"00010203 405Z", + b"0001020304 5Z", + b"1 0102030405Z", + b"001 02030405Z", + b"00012 030405Z", + b"0001023 0405Z", + b"000102034 05Z", + b"00010203045 Z", + )): + with self.assertRaises(DecodeError): + UTCTime(data) + @given(integers(min_value=0, max_value=49)) def test_pre50(self, year): self.assertEqual( -- 2.44.0