From b59eb0cefbf8f27b1c5e6b2a5f96c4561666eddd Mon Sep 17 00:00:00 2001 From: djhoulihan Date: Fri, 21 Dec 2018 15:02:54 -0500 Subject: [PATCH 1/6] Refactor base64.b16decode() to accept hexadecimal strings with lowercase characters by default, and eliminate the consequently unnecessary second argument casefold --- Lib/base64.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Lib/base64.py b/Lib/base64.py index 2be9c395a96674..d5030690e64fce 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -250,7 +250,7 @@ def b16encode(s): return binascii.hexlify(s).upper() -def b16decode(s, casefold=False): +def b16decode(s): """Decode the Base16 encoded bytes-like object or ASCII string s. Optional casefold is a flag specifying whether a lowercase alphabet is @@ -261,9 +261,7 @@ def b16decode(s, casefold=False): in the input. """ s = _bytes_from_decode_data(s) - if casefold: - s = s.upper() - if re.search(b'[^0-9A-F]', s): + if re.search(b'[^0-9A-Fa-f]', s): raise binascii.Error('Non-base16 digit found') return binascii.unhexlify(s) From a9103cba713c3b1e8aa6b6177e16df38f7c48d3b Mon Sep 17 00:00:00 2001 From: djhoulihan Date: Fri, 21 Dec 2018 15:05:26 -0500 Subject: [PATCH 2/6] Revise tests in test_base64.py since there is no longer a second argument to base64.b16decode() (casefold) and the function accepts hexadecimal strings with lowercase characters by default --- Lib/test/test_base64.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 2a4cc2acad24b1..00747b0c861590 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -373,21 +373,15 @@ def test_b16decode(self): eq(base64.b16decode('0102ABCDEF'), b'\x01\x02\xab\xcd\xef') eq(base64.b16decode(b'00'), b'\x00') eq(base64.b16decode('00'), b'\x00') - # Lower case is not allowed without a flag - self.assertRaises(binascii.Error, base64.b16decode, b'0102abcdef') - self.assertRaises(binascii.Error, base64.b16decode, '0102abcdef') - # Case fold - eq(base64.b16decode(b'0102abcdef', True), b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode('0102abcdef', True), b'\x01\x02\xab\xcd\xef') # Non-bytes self.check_other_types(base64.b16decode, b"0102ABCDEF", b'\x01\x02\xab\xcd\xef') self.check_decode_type_errors(base64.b16decode) - eq(base64.b16decode(bytearray(b"0102abcdef"), True), + eq(base64.b16decode(bytearray(b"0102abcdef")), b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode(memoryview(b"0102abcdef"), True), + eq(base64.b16decode(memoryview(b"0102abcdef")), b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode(array('B', b"0102abcdef"), True), + eq(base64.b16decode(array('B', b"0102abcdef")), b'\x01\x02\xab\xcd\xef') # Non-alphabet characters self.assertRaises(binascii.Error, base64.b16decode, '0102AG') From d71d2f33d84318310c86153fb6a1ede3db9d8e98 Mon Sep 17 00:00:00 2001 From: Dylan Houlihan Date: Fri, 21 Dec 2018 22:07:09 -0500 Subject: [PATCH 3/6] Revise the `b16.decode` docstring Since the `casefold` argument is removed, alter the docstring to reflect that and get rid of the reference to a second argument --- Lib/base64.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/base64.py b/Lib/base64.py index d5030690e64fce..948c052eb059d0 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -252,10 +252,7 @@ def b16encode(s): def b16decode(s): """Decode the Base16 encoded bytes-like object or ASCII string s. - - Optional casefold is a flag specifying whether a lowercase alphabet is - acceptable as input. For security purposes, the default is False. - + The result is returned as a bytes object. A binascii.Error is raised if s is incorrectly padded or if there are non-alphabet characters present in the input. From dc2589c7011c0b007b56915cb746326d9d84993a Mon Sep 17 00:00:00 2001 From: Dylan Houlihan Date: Fri, 21 Dec 2018 22:09:09 -0500 Subject: [PATCH 4/6] Remove RFC reference Assuming the change isn't met with resistance from a security perspective, there is probably no need to keep a stale RFC reference around that mentions an outdated security consideration --- Lib/base64.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Lib/base64.py b/Lib/base64.py index 948c052eb059d0..bb6ff3609359aa 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -241,9 +241,6 @@ def b32decode(s, casefold=False, map01=None): return bytes(decoded) -# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns -# lowercase. The RFC also recommends against accepting input case -# insensitively. def b16encode(s): """Encode the bytes-like object s using Base16 and return a bytes object. """ From 23b58535c039b2edc4e87ab996aff0a9e383ad88 Mon Sep 17 00:00:00 2001 From: djhoulihan Date: Sat, 22 Dec 2018 19:18:27 -0500 Subject: [PATCH 5/6] Remove superfluous whitespace in base64.b16decode() docstring --- Lib/base64.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/base64.py b/Lib/base64.py index bb6ff3609359aa..df9615e392ea1e 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -250,7 +250,7 @@ def b16encode(s): def b16decode(s): """Decode the Base16 encoded bytes-like object or ASCII string s. - The result is returned as a bytes object. A binascii.Error is raised if + The result is returned as a bytes object. A binascii.Error is raised if s is incorrectly padded or if there are non-alphabet characters present in the input. """ From 7c36ad2fed9be2eca78c59eb475a4d8397e289fb Mon Sep 17 00:00:00 2001 From: djhoulihan Date: Sat, 22 Dec 2018 19:45:57 -0500 Subject: [PATCH 6/6] Remove unneeded whitespace in the base64.b16decode() docstring between statements --- Lib/base64.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/base64.py b/Lib/base64.py index df9615e392ea1e..ae1ef9dc9c75c5 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -249,7 +249,6 @@ def b16encode(s): def b16decode(s): """Decode the Base16 encoded bytes-like object or ASCII string s. - The result is returned as a bytes object. A binascii.Error is raised if s is incorrectly padded or if there are non-alphabet characters present in the input.