executable-hash 0.1.1.1 → 0.2.0.0
raw patch · 8 files changed
+52/−22 lines, 8 filesdep +template-haskellsetup-changedPVP ok
version bump matches the API change (PVP)
Dependencies added: template-haskell
API changes (from Hackage documentation)
- System.Executable.Hash: executableHash :: IO (Maybe ByteString)
+ System.Executable.Hash: executableHash :: Q Exp
- System.Executable.Hash.Internal: injectedExecutableHash :: Maybe ByteString
+ System.Executable.Hash.Internal: injectedExecutableHash :: Q Exp
Files
- ChangeLog.md +11/−0
- README.md +5/−4
- Setup.hs +0/−1
- System/Executable/Hash.hs +11/−4
- System/Executable/Hash/Internal.hs +15/−8
- executable-hash.cabal +4/−3
- test/test-inject.hs +3/−1
- test/test-no-inject.hs +3/−1
ChangeLog.md view
@@ -1,3 +1,14 @@+0.2.0.0+=======++In order to support dynamic linking, `executableHash` and+`injectedExecutableHash` now need to be run in TH splices. Before+this change, the library was assuming that it would be statically+linked, such that the file-embed dummy bytestring would be present in+the executable.++See [this github issue](https://github.com/fpco/executable-hash/issues/1).+ 0.1.1.1 =======
README.md view
@@ -7,10 +7,11 @@ ## Usage The main function expected to be used by the user is-`System.Executable.Hash.executableHash`. This function yields a SHA1-hash determined by the contents of the executable. However, note that-this may not be the actual SHA1 of the executable, since the hash can-be injected into the executable (which changes its "actual" hash).+`System.Executable.Hash.executableHash`. When used in a TH splice,+like `$(executableHash)`, the resulting expression yields a SHA1 hash+determined by the contents of the executable. However, note that this+may not be the actual SHA1 of the executable, since the hash can be+injected into the executable (which changes its "actual" hash). Installing this package will also install the `inject-executable-hash` executable. Running this program on a binary, like
Setup.hs view
@@ -6,4 +6,3 @@ { postBuild = \_ _ _ _ -> maybeInjectExecutableHash "dist/build/test-inject/test-inject" }-
System/Executable/Hash.hs view
@@ -29,11 +29,16 @@ import Control.Applicative ((<$>)) import Crypto.Hash.SHA1 (hash) import qualified Data.ByteString as BS+import Language.Haskell.TH (Q, Exp) import System.Environment.Executable (getScriptPath, ScriptPath(..)) import System.Executable.Hash.Internal --- | If a SHA1 hash of the executable has been injected into it, then--- it's directly yielded by this function. Otherwise, a hash is+-- | This generates an expression which yields a SHA1 hash. The+-- generated expression has the type @IO (Maybe ByteString)@, just+-- like 'computeExecutableHash'.+--+-- If a SHA1 hash of the executable has been injected into it, then+-- it's directly yielded by this expression. Otherwise, a hash is -- computed with 'computeExecutableHash'. -- -- Note that you shouldn't rely on the result being the actual SHA1@@ -43,11 +48,13 @@ -- contents of the executable. -- -- This yields 'Nothing' when run with @runhaskell@ or @ghci@.-executableHash :: IO (Maybe BS.ByteString)+executableHash :: Q Exp executableHash =- case injectedExecutableHash of+ [|+ case $(injectedExecutableHash) of Just x -> return (Just x) Nothing -> computeExecutableHash+ |] -- | Computes the SHA1 hash of the program executable. --
System/Executable/Hash/Internal.hs view
@@ -8,16 +8,23 @@ import Crypto.Hash.SHA1 (hash) import qualified Data.ByteString as BS import Data.FileEmbed (dummySpaceWith, injectWith)+import Language.Haskell.TH (Q, Exp) import System.Directory (doesFileExist) --- | Yields a 'Just' value of a hash which has been injected into the--- executable via 'injectExecutableHash'.-injectedExecutableHash :: Maybe BS.ByteString-injectedExecutableHash- | BS.all (== toEnum (fromEnum '0')) bs = Nothing- | otherwise = Just bs- where- bs = $(dummySpaceWith "executable-hash" 20)+-- | This generates an expression which yields the injected SHA1 hash.+--+-- The generated expression yields a 'Just' value when the injected+-- SHA1 hash is present in the executable. This hash is usually+-- injected due to a usage of 'injectExecutableHash' /+-- 'maybeInjectExecutableHash'.+injectedExecutableHash :: Q Exp+injectedExecutableHash =+ [|+ let bs = $(dummySpaceWith "executable-hash" 20)+ in if BS.all (== toEnum (fromEnum '0')) bs+ then Nothing+ else Just bs+ |] -- | Given the path to an executable, computes its hash and injects it -- into the binary, such that when that program demands the value of
executable-hash.cabal view
@@ -1,5 +1,5 @@ name: executable-hash-version: 0.1.1.1+version: 0.2.0.0 synopsis: Provides the SHA1 hash of the program executable description: See README.md homepage: https://github.com/fpco/executable-hash@@ -23,11 +23,12 @@ exposed-modules: System.Executable.Hash , System.Executable.Hash.Internal build-depends: base >= 4.0 && < 5.0- , executable-path >= 0.0.3 && < 0.1- , file-embed >= 0.0.8 && < 0.1 , bytestring , cryptohash , directory+ , executable-path >= 0.0.3 && < 0.1+ , file-embed >= 0.0.8 && < 0.1+ , template-haskell default-language: Haskell2010 ghc-options: -Wall
test/test-inject.hs view
@@ -1,7 +1,9 @@+{-# LANGUAGE TemplateHaskell #-}+ import System.Executable.Hash.Internal (injectedExecutableHash) main :: IO () main =- case injectedExecutableHash of+ case $(injectedExecutableHash) of Nothing -> fail "Expected executable hash." Just _ -> return ()
test/test-no-inject.hs view
@@ -1,7 +1,9 @@+{-# LANGUAGE TemplateHaskell #-}+ import System.Executable.Hash.Internal (injectedExecutableHash) main :: IO () main =- case injectedExecutableHash of+ case $(injectedExecutableHash) of Nothing -> return () Just x -> fail $ "Expected no injected executable hash. Instead got: " ++ show x