From fd294f65bef116497663bf182476a5874b5927df Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Thu, 15 Sep 2016 22:25:02 +0200 Subject: [PATCH 1/5] Add explicit Safe Haskell annotations Add explicit Safe/Trustworthy annotations to every module. Move the writeByteString function from Blaze.ByteString.Builder.ByteString to Blaze.ByteString.Builder.Internal.Write because it uses rather unsafe functions compared to the rest of the module and fits better in the unsafe context of the latter module. This makes it possible to mark the former module Safe. There is no impact on the public API (if you consider the Internal modules private). --- Blaze/ByteString/Builder.hs | 2 +- Blaze/ByteString/Builder/ByteString.hs | 14 +++----------- Blaze/ByteString/Builder/Char/Utf8.hs | 2 ++ Blaze/ByteString/Builder/Char8.hs | 2 ++ Blaze/ByteString/Builder/Compat/Write.hs | 2 ++ Blaze/ByteString/Builder/HTTP.hs | 1 + Blaze/ByteString/Builder/Html/Utf8.hs | 1 + Blaze/ByteString/Builder/Int.hs | 2 ++ Blaze/ByteString/Builder/Internal/Write.hs | 11 +++++++++++ Blaze/ByteString/Builder/Word.hs | 2 ++ 10 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Blaze/ByteString/Builder.hs b/Blaze/ByteString/Builder.hs index 9cc61c2..2b9b689 100644 --- a/Blaze/ByteString/Builder.hs +++ b/Blaze/ByteString/Builder.hs @@ -1,5 +1,5 @@ {-# LANGUAGE CPP, BangPatterns #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE Trustworthy #-} ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/ByteString.hs b/Blaze/ByteString/Builder/ByteString.hs index 9962253..46fe88a 100644 --- a/Blaze/ByteString/Builder/ByteString.hs +++ b/Blaze/ByteString/Builder/ByteString.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.ByteString @@ -33,24 +35,14 @@ module Blaze.ByteString.Builder.ByteString ) where +import Blaze.ByteString.Builder.Internal.Write (writeByteString) -import Blaze.ByteString.Builder.Internal.Write ( Write, exactWrite ) -import Foreign import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Builder.Extra as B import qualified Data.ByteString as S -import qualified Data.ByteString.Internal as S import qualified Data.ByteString.Lazy as L --- | Write a strict 'S.ByteString' to a buffer. -writeByteString :: S.ByteString -> Write -writeByteString bs = exactWrite l io - where - (fptr, o, l) = S.toForeignPtr bs - io pf = withForeignPtr fptr $ \p -> copyBytes pf (p `plusPtr` o) l -{-# INLINE writeByteString #-} - -- | Create a 'B.Builder' denoting the same sequence of bytes as a strict -- 'S.ByteString'. -- The 'B.Builder' inserts large 'S.ByteString's directly, but copies small ones diff --git a/Blaze/ByteString/Builder/Char/Utf8.hs b/Blaze/ByteString/Builder/Char/Utf8.hs index c14db6c..66a8f12 100644 --- a/Blaze/ByteString/Builder/Char/Utf8.hs +++ b/Blaze/ByteString/Builder/Char/Utf8.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.Char.Utf8 diff --git a/Blaze/ByteString/Builder/Char8.hs b/Blaze/ByteString/Builder/Char8.hs index fe932bc..fce305e 100644 --- a/Blaze/ByteString/Builder/Char8.hs +++ b/Blaze/ByteString/Builder/Char8.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.Char8 diff --git a/Blaze/ByteString/Builder/Compat/Write.hs b/Blaze/ByteString/Builder/Compat/Write.hs index 6d43bb1..fb561af 100644 --- a/Blaze/ByteString/Builder/Compat/Write.hs +++ b/Blaze/ByteString/Builder/Compat/Write.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Trustworthy #-} + ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.Compat.Write diff --git a/Blaze/ByteString/Builder/HTTP.hs b/Blaze/ByteString/Builder/HTTP.hs index 78b904a..d0dd837 100644 --- a/Blaze/ByteString/Builder/HTTP.hs +++ b/Blaze/ByteString/Builder/HTTP.hs @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, MagicHash, OverloadedStrings #-} +{-# LANGUAGE Trustworthy #-} ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.HTTP diff --git a/Blaze/ByteString/Builder/Html/Utf8.hs b/Blaze/ByteString/Builder/Html/Utf8.hs index ecdb5d6..5fe301b 100644 --- a/Blaze/ByteString/Builder/Html/Utf8.hs +++ b/Blaze/ByteString/Builder/Html/Utf8.hs @@ -2,6 +2,7 @@ #if __GLASGOW_HASKELL__ >= 704 {-# OPTIONS_GHC -fsimpl-tick-factor=40000 #-} #endif +{-# LANGUAGE Safe #-} ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Int.hs b/Blaze/ByteString/Builder/Int.hs index 57ba7e7..2fa7523 100644 --- a/Blaze/ByteString/Builder/Int.hs +++ b/Blaze/ByteString/Builder/Int.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.Int diff --git a/Blaze/ByteString/Builder/Internal/Write.hs b/Blaze/ByteString/Builder/Internal/Write.hs index 0e6045e..7310452 100644 --- a/Blaze/ByteString/Builder/Internal/Write.hs +++ b/Blaze/ByteString/Builder/Internal/Write.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, BangPatterns #-} +{-# LANGUAGE Trustworthy #-} -- | -- Module : Blaze.ByteString.Builder.Internal.Poke @@ -45,6 +46,7 @@ module Blaze.ByteString.Builder.Internal.Write ( , fromStorable , fromStorables + , writeByteString ) where import Foreign @@ -52,6 +54,7 @@ import Foreign import Control.Monad import Data.ByteString.Builder.Internal +import Data.ByteString.Internal as S #if !MIN_VERSION_base(4,8,0) import Data.Monoid @@ -286,3 +289,11 @@ fromStorable = fromWriteSingleton writeStorable -- provided externally. fromStorables :: Storable a => [a] -> Builder fromStorables = fromWriteList writeStorable + +-- | Write a strict 'S.ByteString' to a buffer. +writeByteString :: S.ByteString -> Write +writeByteString bs = exactWrite l io + where + (fptr, o, l) = S.toForeignPtr bs + io pf = withForeignPtr fptr $ \p -> copyBytes pf (p `plusPtr` o) l +{-# INLINE writeByteString #-} diff --git a/Blaze/ByteString/Builder/Word.hs b/Blaze/ByteString/Builder/Word.hs index 670a224..eb7cfd2 100644 --- a/Blaze/ByteString/Builder/Word.hs +++ b/Blaze/ByteString/Builder/Word.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.Word From aad371af54e83b2af6bef073d222528a909028ba Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Sat, 17 Sep 2016 18:14:54 +0200 Subject: [PATCH 2/5] Mark Internal.Write explicitly Unsafe Blaze.ByteString.Builer.Internal.Write should be marked Unsafe since it makes it easy to shoot yourself in the foot. --- Blaze/ByteString/Builder/ByteString.hs | 2 +- Blaze/ByteString/Builder/Internal/Write.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Blaze/ByteString/Builder/ByteString.hs b/Blaze/ByteString/Builder/ByteString.hs index 46fe88a..eee68fc 100644 --- a/Blaze/ByteString/Builder/ByteString.hs +++ b/Blaze/ByteString/Builder/ByteString.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE Safe #-} +{-# LANGUAGE Trustworthy #-} ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Internal/Write.hs b/Blaze/ByteString/Builder/Internal/Write.hs index 7310452..59e26d8 100644 --- a/Blaze/ByteString/Builder/Internal/Write.hs +++ b/Blaze/ByteString/Builder/Internal/Write.hs @@ -1,5 +1,5 @@ {-# LANGUAGE CPP, BangPatterns #-} -{-# LANGUAGE Trustworthy #-} +{-# LANGUAGE Unsafe #-} -- | -- Module : Blaze.ByteString.Builder.Internal.Poke From b692fc3e0da027983d00eda352a58e8b6fbc8f33 Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Sat, 17 Sep 2016 18:22:58 +0200 Subject: [PATCH 3/5] Add CPP logic for GHC 7.4 and earlier Add CPP logic guarding the SafeHaskel statements. Only expose Safe or Trustworthy pragmas for GHC >= 7.2. Only expose Unsafe pragmas for GHC >= 7.4. --- Blaze/ByteString/Builder/ByteString.hs | 3 +++ Blaze/ByteString/Builder/Char/Utf8.hs | 3 +++ Blaze/ByteString/Builder/Char8.hs | 3 +++ Blaze/ByteString/Builder/Compat/Write.hs | 3 +++ Blaze/ByteString/Builder/HTTP.hs | 2 ++ Blaze/ByteString/Builder/Html/Utf8.hs | 2 ++ Blaze/ByteString/Builder/Int.hs | 3 +++ Blaze/ByteString/Builder/Internal/Write.hs | 2 ++ Blaze/ByteString/Builder/Word.hs | 3 +++ 9 files changed, 24 insertions(+) diff --git a/Blaze/ByteString/Builder/ByteString.hs b/Blaze/ByteString/Builder/ByteString.hs index eee68fc..3782558 100644 --- a/Blaze/ByteString/Builder/ByteString.hs +++ b/Blaze/ByteString/Builder/ByteString.hs @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} +#endif ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Char/Utf8.hs b/Blaze/ByteString/Builder/Char/Utf8.hs index 66a8f12..fd58b4b 100644 --- a/Blaze/ByteString/Builder/Char/Utf8.hs +++ b/Blaze/ByteString/Builder/Char/Utf8.hs @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} +#endif ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Char8.hs b/Blaze/ByteString/Builder/Char8.hs index fce305e..957b248 100644 --- a/Blaze/ByteString/Builder/Char8.hs +++ b/Blaze/ByteString/Builder/Char8.hs @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} +#endif ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Compat/Write.hs b/Blaze/ByteString/Builder/Compat/Write.hs index fb561af..5081f32 100644 --- a/Blaze/ByteString/Builder/Compat/Write.hs +++ b/Blaze/ByteString/Builder/Compat/Write.hs @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} +#endif ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/HTTP.hs b/Blaze/ByteString/Builder/HTTP.hs index d0dd837..be4520a 100644 --- a/Blaze/ByteString/Builder/HTTP.hs +++ b/Blaze/ByteString/Builder/HTTP.hs @@ -1,5 +1,7 @@ {-# LANGUAGE BangPatterns, CPP, MagicHash, OverloadedStrings #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} +#endif ------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.HTTP diff --git a/Blaze/ByteString/Builder/Html/Utf8.hs b/Blaze/ByteString/Builder/Html/Utf8.hs index 5fe301b..23e20fd 100644 --- a/Blaze/ByteString/Builder/Html/Utf8.hs +++ b/Blaze/ByteString/Builder/Html/Utf8.hs @@ -2,7 +2,9 @@ #if __GLASGOW_HASKELL__ >= 704 {-# OPTIONS_GHC -fsimpl-tick-factor=40000 #-} #endif +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} +#endif ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Int.hs b/Blaze/ByteString/Builder/Int.hs index 2fa7523..c2655af 100644 --- a/Blaze/ByteString/Builder/Int.hs +++ b/Blaze/ByteString/Builder/Int.hs @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} +#endif ------------------------------------------------------------------------------ -- | diff --git a/Blaze/ByteString/Builder/Internal/Write.hs b/Blaze/ByteString/Builder/Internal/Write.hs index 59e26d8..290b9ff 100644 --- a/Blaze/ByteString/Builder/Internal/Write.hs +++ b/Blaze/ByteString/Builder/Internal/Write.hs @@ -1,5 +1,7 @@ {-# LANGUAGE CPP, BangPatterns #-} +#if __GLASGOW_HASKELL__ >= 704 {-# LANGUAGE Unsafe #-} +#endif -- | -- Module : Blaze.ByteString.Builder.Internal.Poke diff --git a/Blaze/ByteString/Builder/Word.hs b/Blaze/ByteString/Builder/Word.hs index eb7cfd2..98823c6 100644 --- a/Blaze/ByteString/Builder/Word.hs +++ b/Blaze/ByteString/Builder/Word.hs @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} +#endif ------------------------------------------------------------------------------ -- | From 5be4c6a33978583c32a40ccfac220f3c3b96f039 Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Sat, 17 Sep 2016 18:30:45 +0200 Subject: [PATCH 4/5] Prepare version 0.4.1.0 Add changelog for 0.4.1.0 and bump version in the cabal file. --- CHANGES | 3 +++ blaze-builder.cabal | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 31f2af4..704684e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +* 0.4.1.0 + - Add Safe Haskell pragmas + * 0.4.0.2 - Fixed warnings on GHC 7.10, courtesy of Mikhail Glushenkov. diff --git a/blaze-builder.cabal b/blaze-builder.cabal index 4c3a869..269c4ac 100644 --- a/blaze-builder.cabal +++ b/blaze-builder.cabal @@ -1,5 +1,5 @@ Name: blaze-builder -Version: 0.4.0.2 +Version: 0.4.1.0 Synopsis: Efficient buffered output. Description: From 45638a34572fddeab032e758256535ef08aec24b Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Sat, 17 Sep 2016 18:36:27 +0200 Subject: [PATCH 5/5] Add missing CPP logic in Blaze/ByteString/Builder.hs Add CPP logic left out in an earlier commit. --- Blaze/ByteString/Builder.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Blaze/ByteString/Builder.hs b/Blaze/ByteString/Builder.hs index 2b9b689..3163ea5 100644 --- a/Blaze/ByteString/Builder.hs +++ b/Blaze/ByteString/Builder.hs @@ -1,5 +1,7 @@ {-# LANGUAGE CPP, BangPatterns #-} +#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} +#endif ------------------------------------------------------------------------------ -- |