From 2ab719c38cff64c4afc0cd4c61c878020fcde83b Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 2 Nov 2020 15:03:43 -0600 Subject: [PATCH] padding: Tip-toe around bytes subclasses. This change allows future's newbytes class to be padded again. Fixes https://github.com/pyca/cryptography/issues/5547. --- src/cryptography/hazmat/primitives/padding.py | 10 ++++++-- tests/hazmat/primitives/test_padding.py | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py index d3dc7093ae51..98abffbc08be 100644 --- a/src/cryptography/hazmat/primitives/padding.py +++ b/src/cryptography/hazmat/primitives/padding.py @@ -42,7 +42,10 @@ def _byte_padding_update(buffer_, data, block_size): utils._check_byteslike("data", data) - buffer_ += bytes(data) + # six.PY2: Only coerce non-bytes objects to avoid triggering bad behavior + # of future's newbytes type. Unconditionally call bytes() after Python 2 + # support is gone. + buffer_ += data if isinstance(data, bytes) else bytes(data) finished_blocks = len(buffer_) // (block_size // 8) @@ -66,7 +69,10 @@ def _byte_unpadding_update(buffer_, data, block_size): utils._check_byteslike("data", data) - buffer_ += bytes(data) + # six.PY2: Only coerce non-bytes objects to avoid triggering bad behavior + # of future's newbytes type. Unconditionally call bytes() after Python 2 + # support is gone. + buffer_ += data if isinstance(data, bytes) else bytes(data) finished_blocks = max(len(buffer_) // (block_size // 8) - 1, 0) diff --git a/tests/hazmat/primitives/test_padding.py b/tests/hazmat/primitives/test_padding.py index bf5379730131..b15eb37539c5 100644 --- a/tests/hazmat/primitives/test_padding.py +++ b/tests/hazmat/primitives/test_padding.py @@ -43,6 +43,18 @@ def test_non_bytes(self): with pytest.raises(TypeError): unpadder.update(u"abc") + def test_zany_py2_bytes_subclass(self): + class mybytes(bytes): # noqa: N801 + def __str__(self): + return "broken" + + str(mybytes()) + padder = padding.PKCS7(128).padder() + padder.update(mybytes(b"abc")) + unpadder = padding.PKCS7(128).unpadder() + unpadder.update(mybytes(padder.finalize())) + assert unpadder.finalize() == b"abc" + @pytest.mark.parametrize( ("size", "unpadded", "padded"), [ @@ -154,6 +166,18 @@ def test_non_bytes(self): with pytest.raises(TypeError): unpadder.update(u"abc") + def test_zany_py2_bytes_subclass(self): + class mybytes(bytes): # noqa: N801 + def __str__(self): + return "broken" + + str(mybytes()) + padder = padding.ANSIX923(128).padder() + padder.update(mybytes(b"abc")) + unpadder = padding.ANSIX923(128).unpadder() + unpadder.update(mybytes(padder.finalize())) + assert unpadder.finalize() == b"abc" + @pytest.mark.parametrize( ("size", "unpadded", "padded"), [