diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# 1.0.0.3
+
+* Made performance more robust 
+  ([#27](https://github.com/haskell/base64-bytestring/pull/27)).
+* Improved documentation
+  ([#23](https://github.com/haskell/base64-bytestring/pull/23)).
+* Improved the performance of decodeLenient a bit
+  ([#21](https://github.com/haskell/base64-bytestring/pull/21)).
+
 # 1.0.0.2
 
 * Fixed a write past allocated memory in joinWith (potential security
diff --git a/Data/ByteString/Base64.hs b/Data/ByteString/Base64.hs
--- a/Data/ByteString/Base64.hs
+++ b/Data/ByteString/Base64.hs
@@ -36,6 +36,11 @@
 -- | Decode a base64-encoded string. This function strictly follows
 -- the specification in
 -- <http://tools.ietf.org/rfc/rfc4648 RFC 4648>.
+--
+-- (Note: this means that even @"\n", "\r\n"@ as line breaks are rejected
+-- rather than ignored.  If you are using this in the context of a
+-- standard that overrules RFC 4648 such as HTTP multipart mime bodies,
+-- consider using 'decodeLenient'.)
 decode :: ByteString -> Either String ByteString
 decode s = decodeWithTable decodeFP s
 
diff --git a/Data/ByteString/Base64/Internal.hs b/Data/ByteString/Base64/Internal.hs
--- a/Data/ByteString/Base64/Internal.hs
+++ b/Data/ByteString/Base64/Internal.hs
@@ -91,7 +91,7 @@
           fill (castPtr dptr) (sptr `plusPtr` soff)
   return $! PS dfp 0 dlen
 
-data EncodeTable = ET (ForeignPtr Word8) (ForeignPtr Word16)
+data EncodeTable = ET !(ForeignPtr Word8) !(ForeignPtr Word16)
 
 -- The encoding table is constructed such that the expansion of a 12-bit
 -- block to a 16-bit block can be done by a single Word16 copy from the
diff --git a/Data/ByteString/Base64/Lazy.hs b/Data/ByteString/Base64/Lazy.hs
--- a/Data/ByteString/Base64/Lazy.hs
+++ b/Data/ByteString/Base64/Lazy.hs
@@ -57,4 +57,5 @@
               . LC.filter goodChar
     where -- We filter out and '=' padding here, but B64.decodeLenient
           -- handles that
-          goodChar c = isAlphaNum c || c == '+' || c == '/'
+          goodChar c = isDigit c || isAsciiUpper c || isAsciiLower c
+                                 || c == '+' || c == '/'
diff --git a/Data/ByteString/Base64/URL/Lazy.hs b/Data/ByteString/Base64/URL/Lazy.hs
--- a/Data/ByteString/Base64/URL/Lazy.hs
+++ b/Data/ByteString/Base64/URL/Lazy.hs
@@ -58,3 +58,4 @@
     where -- We filter out and '=' padding here, but B64.decodeLenient
           -- handles that
           goodChar c = isAlphaNum c || c == '-' || c == '_'
+
diff --git a/base64-bytestring.cabal b/base64-bytestring.cabal
--- a/base64-bytestring.cabal
+++ b/base64-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                base64-bytestring
-version:             1.0.0.2
+version:             1.0.0.3
 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
diff --git a/benchmarks/BM.hs b/benchmarks/BM.hs
--- a/benchmarks/BM.hs
+++ b/benchmarks/BM.hs
@@ -5,6 +5,7 @@
 import qualified Data.ByteString.Base64 as B
 import qualified Data.ByteString.Base64.Lazy as L
 import qualified Data.ByteString.Base64.URL as U
+import qualified Data.ByteString.Base64.URL.Lazy as LU
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy as L
 
@@ -38,8 +39,16 @@
 lazy :: String -> L.ByteString -> Benchmark
 lazy name orig =
     bgroup name [
-      bench "decode" $ nf L.decode enc
-    , bench "encode" $ nf L.encode orig
+      bgroup "normal" [
+        bench "decode" $ nf L.decode enc
+      , bench "decodeLenient" $ nf L.decodeLenient enc
+      , bench "encode" $ nf L.encode orig
+      ]
+    , bgroup "url" [
+        bench "decode" $ nf LU.decode enc
+      , bench "decodeLenient" $ nf LU.decodeLenient enc
+      , bench "encode" $ nf LU.encode orig
+      ]
     ]
   where enc = L.encode orig
 
