Hello community,
here is the log from the commit of package ghc-base64-bytestring for
openSUSE:Factory checked in at 2020-08-28 21:26:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-base64-bytestring (Old)
and /work/SRC/openSUSE:Factory/.ghc-base64-bytestring.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-base64-bytestring"
Fri Aug 28 21:26:02 2020 rev:12 rq:829189 version:1.2.0.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/ghc-base64-bytestring/ghc-base64-bytestring.changes
2020-06-19 17:08:49.725326170 +0200
+++
/work/SRC/openSUSE:Factory/.ghc-base64-bytestring.new.3399/ghc-base64-bytestring.changes
2020-08-28 21:26:07.260460667 +0200
@@ -1,0 +2,17 @@
+Tue Aug 18 10:44:07 UTC 2020 - Peter Simons <[email protected]>
+
+- Replace %setup -q with the more modern %autosetup macro.
+
+-------------------------------------------------------------------
+Sat Aug 15 02:02:13 UTC 2020 - [email protected]
+
+- Update base64-bytestring to version 1.2.0.0.
+ # 1.2.0.0
+
+ * Security fix: reject non-canonical base64 encoded values -
([#38](https://github.com/haskell/base64-bytestring/pull/38)) fixing issue
[#24](https://github.com/haskell/base64-bytestring/issues/24).
+
+ * Security fix: reject bytestrings with improper padding that can be
"completed" by the unpadded-Base64url workflow, and homogenize error messages
([#33](https://github.com/haskell/base64-bytestring/pull/33))
+
+ * Test coverage expanded to 98% of the library. All critical paths covered.
+
+-------------------------------------------------------------------
Old:
----
base64-bytestring-1.1.0.0.tar.gz
New:
----
base64-bytestring-1.2.0.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-base64-bytestring.spec ++++++
--- /var/tmp/diff_new_pack.i2mByj/_old 2020-08-28 21:26:07.820460933 +0200
+++ /var/tmp/diff_new_pack.i2mByj/_new 2020-08-28 21:26:07.824460935 +0200
@@ -19,7 +19,7 @@
%global pkg_name base64-bytestring
%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 1.1.0.0
+Version: 1.2.0.0
Release: 0
Summary: Fast base64 encoding and decoding for ByteStrings
License: BSD-3-Clause
@@ -41,7 +41,10 @@
%description
This package provides support for encoding and decoding binary data according
to 'base64' (see also <https://tools.ietf.org/html/rfc4648 RFC 4648>) for
-strict and lazy ByteStrings.
+strict and lazy ByteStrings
+
+For a fuller-featured and better-performing Base64 library, see the
+<https://hackage.haskell.org/package/base64 base64> package.
%package devel
Summary: Haskell %{pkg_name} library development files
@@ -55,7 +58,7 @@
files.
%prep
-%setup -q -n %{pkg_name}-%{version}
+%autosetup -n %{pkg_name}-%{version}
%build
%ghc_lib_build
++++++ base64-bytestring-1.1.0.0.tar.gz -> base64-bytestring-1.2.0.0.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/base64-bytestring-1.1.0.0/CHANGELOG.md
new/base64-bytestring-1.2.0.0/CHANGELOG.md
--- old/base64-bytestring-1.1.0.0/CHANGELOG.md 2001-09-09 03:46:40.000000000
+0200
+++ new/base64-bytestring-1.2.0.0/CHANGELOG.md 2001-09-09 03:46:40.000000000
+0200
@@ -1,5 +1,14 @@
See also http://pvp.haskell.org/faq
+# 1.2.0.0
+
+* Security fix: reject non-canonical base64 encoded values -
([#38](https://github.com/haskell/base64-bytestring/pull/38)) fixing issue
[#24](https://github.com/haskell/base64-bytestring/issues/24).
+
+* Security fix: reject bytestrings with improper padding that can be
"completed" by the unpadded-Base64url workflow, and homogenize error messages
([#33](https://github.com/haskell/base64-bytestring/pull/33))
+
+* Test coverage expanded to 98% of the library. All critical paths covered.
+
+
# 1.1.0.0
* `joinWith` has been removed
([#32](https://github.com/haskell/base64-bytestring/pull/32))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/base64-bytestring-1.1.0.0/Data/ByteString/Base64/Internal.hs
new/base64-bytestring-1.2.0.0/Data/ByteString/Base64/Internal.hs
--- old/base64-bytestring-1.1.0.0/Data/ByteString/Base64/Internal.hs
2001-09-09 03:46:40.000000000 +0200
+++ new/base64-bytestring-1.2.0.0/Data/ByteString/Base64/Internal.hs
2001-09-09 03:46:40.000000000 +0200
@@ -28,7 +28,7 @@
import Data.Word (Word8, Word16, Word32)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, castForeignPtr)
import Foreign.Ptr (Ptr, castPtr, minusPtr, plusPtr)
-import Foreign.Storable (peek, peekElemOff, poke, peekByteOff)
+import Foreign.Storable (peek, peekElemOff, poke)
import System.IO.Unsafe (unsafePerformIO)
peek8 :: Ptr Word8 -> IO Word8
@@ -121,51 +121,46 @@
table = B.pack $ concat $ [ [ix j, ix k] | j <- [0..63], k <- [0..63] ]
-- | Decode a base64-encoded string. This function strictly follows
--- the specification in
--- <http://tools.ietf.org/rfc/rfc4648 RFC 4648>.
+-- the specification in <http://tools.ietf.org/rfc/rfc4648 RFC 4648>.
+--
-- This function takes the decoding table (for @base64@ or @base64url@) as
--- the first paramert.
+-- the first parameter.
+--
+-- For validation of padding properties, see note: $Validation
+--
decodeWithTable :: Padding -> ForeignPtr Word8 -> ByteString -> Either String
ByteString
decodeWithTable _ _ (PS _ _ 0) = Right B.empty
-decodeWithTable padding decodeFP bs@(PS !fp !o !l) = unsafePerformIO $
+decodeWithTable padding decodeFP bs =
case padding of
Padded
- | r == 1 -> err "Base64-encoded bytestring has invalid size"
- | r /= 0 -> err "Base64-encoded bytestring required to be padded"
- | otherwise -> go bs
+ | r == 0 -> unsafePerformIO $ go bs
+ | r == 1 -> Left "Base64-encoded bytestring has invalid size"
+ | otherwise -> Left "Base64-encoded bytestring is unpadded or has
invalid padding"
Don'tCare
- | r == 0 -> go bs
- | r == 2 -> go (B.append bs (B.replicate 2 0x3d))
- | r == 3 -> go (B.append bs (B.replicate 1 0x3d))
- | otherwise -> err "Base64-encoded bytestring has invalid size"
+ | r == 0 -> unsafePerformIO $ go bs
+ | r == 2 -> unsafePerformIO $ go (B.append bs (B.replicate 2 0x3d))
+ | r == 3 -> validateLastPad bs invalidPad $ go (B.append bs
(B.replicate 1 0x3d))
+ | otherwise -> Left "Base64-encoded bytestring has invalid size"
Unpadded
- | r == 0 -> validateUnpadded (go bs)
- | r == 2 -> validateUnpadded (go (B.append bs (B.replicate 2 0x3d)))
- | r == 3 -> validateUnpadded (go (B.append bs (B.replicate 1 0x3d)))
- | otherwise -> err "Base64-encoded bytestring has invalid size"
+ | r == 0 -> validateLastPad bs noPad $ go bs
+ | r == 2 -> validateLastPad bs noPad $ go (B.append bs (B.replicate 2
0x3d))
+ | r == 3 -> validateLastPad bs noPad $ go (B.append bs (B.replicate 1
0x3d))
+ | otherwise -> Left "Base64-encoded bytestring has invalid size"
where
- err = return . Left
+ (!q, !r) = (B.length bs) `divMod` 4
- (q, r) = (B.length bs) `divMod` 4
+ noPad = "Base64-encoded bytestring required to be unpadded"
+ invalidPad = "Base64-encoded bytestring has invalid padding"
- dlen = q * 3
-
- validateUnpadded io = withForeignPtr fp $ \p -> do
- let !end = l + o
- a <- peek (plusPtr p (end - 1))
- b <- peek (plusPtr p (end - 2))
-
- let !pad = 0x3d :: Word8
- if a == pad || b == pad
- then err "Base64-encoded bytestring required to be unpadded"
- else io
+ !dlen = q * 3
go (PS !sfp !soff !slen) = do
dfp <- mallocByteString dlen
withForeignPtr decodeFP $ \ !decptr ->
withForeignPtr sfp $ \sptr ->
withForeignPtr dfp $ \dptr ->
- decodeLoop decptr (plusPtr sptr soff) dptr (sptr `plusPtr` (slen +
soff)) dfp
+ decodeLoop decptr (plusPtr sptr soff) dptr
+ (sptr `plusPtr` (slen + soff)) dfp
decodeLoop
:: Ptr Word8
@@ -185,14 +180,18 @@
$ "invalid character at offset: "
++ show (p `minusPtr` sptr)
- padErr p = return . Left
+ padErr p = return . Left
$ "invalid padding at offset: "
++ show (p `minusPtr` sptr)
+ canonErr p = return . Left
+ $ "non-canonical encoding detected at offset: "
+ ++ show (p `minusPtr` sptr)
+
look :: Ptr Word8 -> IO Word32
look !p = do
- !i <- peekByteOff p 0 :: IO Word8
- !v <- peekByteOff dtable (fromIntegral i) :: IO Word8
+ !i <- peek p
+ !v <- peekElemOff dtable (fromIntegral i)
return (fromIntegral v)
go !dst !src
@@ -255,11 +254,17 @@
poke8 dst (fromIntegral (shiftR w 16))
if c == 0x63 && d == 0x63
- then return $ Right $ PS dfp 0 (1 + (dst `minusPtr` dptr))
+ then
+ if sanityCheckPos b mask_4bits
+ then return $ Right $ PS dfp 0 (1 + (dst `minusPtr` dptr))
+ else canonErr (plusPtr src 1)
else if d == 0x63
- then do
- poke8 (plusPtr dst 1) (fromIntegral (shiftR w 8))
- return $ Right $ PS dfp 0 (2 + (dst `minusPtr` dptr))
+ then
+ if sanityCheckPos c mask_2bits
+ then do
+ poke8 (plusPtr dst 1) (fromIntegral (shiftR w 8))
+ return $ Right $ PS dfp 0 (2 + (dst `minusPtr` dptr))
+ else canonErr (plusPtr src 2)
else do
poke8 (plusPtr dst 1) (fromIntegral (shiftR w 8))
poke8 (plusPtr dst 2) (fromIntegral w)
@@ -351,3 +356,59 @@
in acc' : go zs'
else -- suffix must be null
fixup acc' zs
+
+-- $Validation
+--
+-- This function checks that the last char of a bytestring is '='
+-- and, if true, fails with a message or completes some io action.
+--
+-- This is necessary to check when decoding permissively (i.e. filling in
padding chars).
+-- Consider the following 4 cases of a string of length l:
+--
+-- l = 0 mod 4: No pad chars are added, since the input is assumed to be good.
+-- l = 1 mod 4: Never an admissible length in base64
+-- l = 2 mod 4: 2 padding chars are added. If padding chars are present in the
last 4 chars of the string,
+-- they will fail to decode as final quanta.
+-- l = 3 mod 4: 1 padding char is added. In this case a string is of the form
<body> + <padchar>. If adding the
+-- pad char "completes" the string so that it is `l = 0 mod 4`, then this may
possibly form corrupted data.
+-- This case is degenerate and should be disallowed.
+--
+-- Hence, permissive decodes should only fill in padding chars when it makes
sense to add them. That is,
+-- if an input is degenerate, it should never succeed when we add padding
chars. We need the following invariant to hold:
+--
+-- @
+-- B64U.decodeUnpadded <|> B64U.decodePadded ~ B64U.decodePadded
+-- @
+--
+-- This means the only char we need to check is the last one, and only to
disallow `l = 3 mod 4`.
+--
+validateLastPad
+ :: ByteString
+ -- ^ input to validate
+ -> String
+ -- ^ error msg
+ -> IO (Either String ByteString)
+ -> Either String ByteString
+validateLastPad bs err io
+ | B.last bs == 0x3d = Left err
+ | otherwise = unsafePerformIO io
+{-# INLINE validateLastPad #-}
+
+-- | Sanity check an index against a bitmask to make sure
+-- it's coherent. If pos & mask == 0, we're good. If not, we should fail.
+--
+sanityCheckPos :: Word32 -> Word8 -> Bool
+sanityCheckPos pos mask = ((fromIntegral pos) .&. mask) == 0
+{-# INLINE sanityCheckPos #-}
+
+-- | Mask 2 bits
+--
+mask_2bits :: Word8
+mask_2bits = 3 -- (1 << 2) - 1
+{-# NOINLINE mask_2bits #-}
+
+-- | Mask 4 bits
+--
+mask_4bits :: Word8
+mask_4bits = 15 -- (1 << 4) - 1
+{-# NOINLINE mask_4bits #-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/base64-bytestring-1.1.0.0/base64-bytestring.cabal
new/base64-bytestring-1.2.0.0/base64-bytestring.cabal
--- old/base64-bytestring-1.1.0.0/base64-bytestring.cabal 2001-09-09
03:46:40.000000000 +0200
+++ new/base64-bytestring-1.2.0.0/base64-bytestring.cabal 2001-09-09
03:46:40.000000000 +0200
@@ -1,23 +1,38 @@
-cabal-version: 1.12
-name: base64-bytestring
-version: 1.1.0.0
-synopsis: Fast base64 encoding and decoding for ByteStrings
-description: This package provides support for encoding and decoding
binary data according to @base64@ (see also
<https://tools.ietf.org/html/rfc4648 RFC 4648>) for strict and lazy ByteStrings.
-homepage: https://github.com/haskell/base64-bytestring
-bug-reports: https://github.com/haskell/base64-bytestring/issues
-license: BSD3
-license-file: LICENSE
-author: Bryan O'Sullivan <[email protected]>
-maintainer: Herbert Valerio Riedel <[email protected]>,
- Mikhail Glushenkov <[email protected]>,
- Emily Pillmore <[email protected]>
-copyright: 2010-2020 Bryan O'Sullivan et al.
-category: Data
-build-type: Simple
-tested-with: GHC==8.10.1, GHC==8.8.3, GHC==8.6.5,
- GHC==8.4.4, GHC==8.2.2, GHC==8.0.2,
- GHC==7.10.3, GHC==7.8.4, GHC==7.6.3,
- GHC==7.4.2, GHC==7.2.2, GHC==7.0.4
+cabal-version: 1.12
+name: base64-bytestring
+version: 1.2.0.0
+synopsis: Fast base64 encoding and decoding for ByteStrings
+description:
+ This package provides support for encoding and decoding binary data
according to @base64@ (see also <https://tools.ietf.org/html/rfc4648 RFC 4648>)
for strict and lazy ByteStrings
+ .
+ For a fuller-featured and better-performing Base64 library, see the
<https://hackage.haskell.org/package/base64 base64> package.
+
+homepage: https://github.com/haskell/base64-bytestring
+bug-reports: https://github.com/haskell/base64-bytestring/issues
+license: BSD3
+license-file: LICENSE
+author: Bryan O'Sullivan <[email protected]>
+maintainer:
+ Herbert Valerio Riedel <[email protected]>,
+ Mikhail Glushenkov <[email protected]>,
+ Emily Pillmore <[email protected]>
+
+copyright: 2010-2020 Bryan O'Sullivan et al.
+category: Data
+build-type: Simple
+tested-with:
+ GHC ==7.0.4
+ || ==7.2.2
+ || ==7.4.2
+ || ==7.6.3
+ || ==7.8.4
+ || ==7.10.3
+ || ==8.0.2
+ || ==8.2.2
+ || ==8.4.4
+ || ==8.6.5
+ || ==8.8.3
+ || ==8.10.1
extra-source-files:
README.md
@@ -28,58 +43,49 @@
library
exposed-modules:
Data.ByteString.Base64
- Data.ByteString.Base64.URL
Data.ByteString.Base64.Lazy
+ Data.ByteString.Base64.URL
Data.ByteString.Base64.URL.Lazy
- other-modules:
- Data.ByteString.Base64.Internal
-
+ other-modules: Data.ByteString.Base64.Internal
build-depends:
- base == 4.*,
- bytestring >= 0.9 && < 0.11
-
- ghc-options: -Wall -funbox-strict-fields
+ base >=4 && <5
+ , bytestring >=0.9 && <0.11
+ ghc-options: -Wall -funbox-strict-fields
default-language: Haskell2010
test-suite tests
- type: exitcode-stdio-1.0
- hs-source-dirs: tests
- main-is: Tests.hs
-
- ghc-options:
- -Wall -threaded -rtsopts
-
+ type: exitcode-stdio-1.0
+ hs-source-dirs: tests
+ main-is: Tests.hs
+ ghc-options: -Wall -threaded -rtsopts
build-depends:
- QuickCheck,
- HUnit,
- base64-bytestring,
- base,
- containers,
- bytestring,
- split,
- test-framework,
- test-framework-quickcheck2,
- test-framework-hunit
+ base
+ , base64-bytestring
+ , bytestring
+ , containers
+ , HUnit
+ , QuickCheck
+ , split
+ , test-framework
+ , test-framework-hunit
+ , test-framework-quickcheck2
default-language: Haskell2010
benchmark benchmarks
- type: exitcode-stdio-1.0
- hs-source-dirs: benchmarks
- main-is: BM.hs
-
- ghc-options:
- -Wall -threaded -rtsopts
-
+ type: exitcode-stdio-1.0
+ hs-source-dirs: benchmarks
+ main-is: BM.hs
+ ghc-options: -Wall -threaded -rtsopts
build-depends:
- base,
- bytestring,
- containers,
- deepseq,
- base64-bytestring,
- criterion
+ base
+ , base64-bytestring
+ , bytestring
+ , containers
+ , criterion
+ , deepseq
default-language: Haskell2010
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/base64-bytestring-1.1.0.0/tests/Tests.hs
new/base64-bytestring-1.2.0.0/tests/Tests.hs
--- old/base64-bytestring-1.1.0.0/tests/Tests.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/base64-bytestring-1.2.0.0/tests/Tests.hs 2001-09-09
03:46:40.000000000 +0200
@@ -36,23 +36,51 @@
, _lenient :: bs -> bs
}
+data UrlImpl bs = UrlImpl
+ { _labelUrl :: String
+ , _encodeUrl :: bs -> bs
+ , _decodeUrl :: bs -> Either String bs
+ , _encodeUrlNopad :: bs -> bs
+ , _decodeUrlNopad :: bs -> Either String bs
+ , _decodeUrlPad :: bs -> Either String bs
+ , _lenientUrl :: bs -> bs
+ }
+
tests :: [Test]
tests =
[ testGroup "property tests"
- [ testsRegular $ Impl "Base64" Base64.encode Base64.decode
Base64.decodeLenient
- , testsRegular $ Impl "LBase64" LBase64.encode LBase64.decode
LBase64.decodeLenient
- , testsURL $ Impl "Base64URL" Base64URL.encode Base64URL.decode
Base64URL.decodeLenient
- , testsURL $ Impl "Base64URLPadded" Base64URL.encode
Base64URL.decodePadded Base64URL.decodeLenient
- , testsURLNopad $ Impl "Base64URLUnpadded" Base64URL.encodeUnpadded
Base64URL.decodeUnpadded Base64URL.decodeLenient
- , testsURL $ Impl "LBase64URL" LBase64URL.encode LBase64URL.decode
LBase64URL.decodeLenient
- , testsURL $ Impl "LBase64URLPadded" LBase64URL.encode
LBase64URL.decodePadded LBase64URL.decodeLenient
- , testsURLNopad $ Impl "LBase64URLUnpadded" LBase64URL.encodeUnpadded
LBase64URL.decodeUnpadded LBase64URL.decodeLenient
+ [ testsRegular b64impl
+ , testsRegular lb64impl
+ , testsURL b64uimpl
+ , testsURL lb64uimpl
]
, testGroup "unit tests"
[ base64UrlUnitTests
, lazyBase64UrlUnitTests
]
]
+ where
+ b64impl = Impl "Base64" Base64.encode Base64.decode Base64.decodeLenient
+ lb64impl = Impl "LBase64" LBase64.encode LBase64.decode
LBase64.decodeLenient
+
+ b64uimpl = UrlImpl
+ "Base64URL"
+ Base64URL.encode
+ Base64URL.decode
+ Base64URL.encodeUnpadded
+ Base64URL.decodeUnpadded
+ Base64URL.decodePadded
+ Base64URL.decodeLenient
+
+ lb64uimpl = UrlImpl
+ "LBase64URL"
+ LBase64URL.encode
+ LBase64URL.decode
+ LBase64URL.encodeUnpadded
+ LBase64URL.decodeUnpadded
+ LBase64URL.decodePadded
+ LBase64URL.decodeLenient
+
testsRegular
:: ( IsString bs
@@ -72,20 +100,17 @@
, Eq bs
, Arbitrary bs
)
- => Impl bs
+ => UrlImpl bs
-> Test
-testsURL = testsWith base64url_testData
-
-testsURLNopad
- :: ( IsString bs
- , AllRepresentations bs
- , Show bs
- , Eq bs
- , Arbitrary bs
- )
- => Impl bs
- -> Test
-testsURLNopad = testsWith base64url_testData_nopad
+testsURL (UrlImpl l e d eu du dp dl) = testGroup l
+ [ testsWith base64url_testData (Impl "Arbitrary Padding" e d dl)
+ , testsWith base64url_testData (Impl "Required Padding" e dp dl)
+ , testsWith base64url_testData_nopad (Impl "No padding" eu du dl)
+ , testProperty "prop_url_pad_roundtrip" $ \bs -> Right bs == dp (e bs)
+ , testProperty "prop_url_nopad_roundtrip" $ \bs -> Right bs == du (eu bs)
+ , testProperty "prop_url_decode_invariant" $ \bs ->
+ ((du (eu bs)) == (d (e bs))) || ((dp (e bs)) == d (e bs))
+ ]
testsWith
:: ( IsString bs
@@ -149,6 +174,7 @@
where
decodeLenient' = liftM Right decodeLenient
+
base64_testData :: IsString bs => [(bs, bs)]
base64_testData = [("", "")
,("\0", "AA==")
@@ -272,7 +298,26 @@
Base64.decode "eAoe=Ao=" @=? Left "invalid padding at offset: 4"
Base64.decode "eAoeA=o=" @=? Left "invalid padding at offset: 5"
]
-
+ , testGroup "Non-canonical encodings fail and canonical encodings succeed"
+ [ testCase "roundtrip for d ~ ZA==" $ do
+ Base64.decode "ZE==" @=? Left "non-canonical encoding detected at
offset: 1"
+ Base64.decode "ZK==" @=? Left "non-canonical encoding detected at
offset: 1"
+ Base64.decode "ZA==" @=? Right "d"
+ , testCase "roundtrip for f` ~ ZmA=" $ do
+ Base64.decode "ZmC=" @=? Left "non-canonical encoding detected at
offset: 2"
+ Base64.decode "ZmD=" @=? Left "non-canonical encoding detected at
offset: 2"
+ Base64.decode "ZmA=" @=? Right "f`"
+
+ , testCase "roundtrip for foo` ~ Zm9vYA==" $ do
+ Base64.decode "Zm9vYE==" @=? Left "non-canonical encoding detected at
offset: 5"
+ Base64.decode "Zm9vYK==" @=? Left "non-canonical encoding detected at
offset: 5"
+ Base64.decode "Zm9vYA==" @=? Right "foo`"
+
+ , testCase "roundtrip for foob` ~ Zm9vYmA=" $ do
+ Base64.decode "Zm9vYmC=" @=? Left "non-canonical encoding detected at
offset: 6"
+ Base64.decode "Zm9vYmD=" @=? Left "non-canonical encoding detected at
offset: 6"
+ Base64.decode "Zm9vYmA=" @=? Right "foob`"
+ ]
, testGroup "Base64URL padding case unit tests"
[ testCase "stress arbitarily padded URL strings" $ do
Base64URL.decode "P" @=? Left "Base64-encoded bytestring has invalid
size"
@@ -342,7 +387,7 @@
Right s
else do
assertEqual "Unpadded required: padding fails" u $
- Left "Base64-encoded bytestring required to be padded"
+ Left "Base64-encoded bytestring is unpadded or has invalid padding"
assertEqual "Unpadded required: unpadding succeeds" v $
Right s
@@ -446,7 +491,7 @@
Right s
else do
assertEqual "Unpadded required: padding fails" u $
- Left "Base64-encoded bytestring required to be padded"
+ Left "Base64-encoded bytestring is unpadded or has invalid padding"
assertEqual "Unpadded required: unpadding succeeds" v $
Right s