erikd / base64-bytestring-type

A newtype around ByteString, for base64 encoding.
BSD 3-Clause "New" or "Revised" License
6 stars 2 forks source link

Semigroup, Monoid instances are wrong #31

Closed emilypi closed 2 years ago

emilypi commented 2 years ago

For Monoid/Semigroup mappends, the laws are that f (a <> b) = f a <>' f b. However, that law does not hold for Bytestring64:

П> getEncodedByteString64 "foob" <> getEncodedByteString64 "ar" -- encodes "foob" and "ar"
"Zm9vYg==YXI=" -- not valid

П> getEncodedByteString64 $ "foob" <> "ar"
"Zm9vYmFy"

The solution here is you have to trim pads and statefully shift bits to reassemble a new bytestring with new pads. These instances are only valid for bytestrings modulo lenient decoding as is.