Skip to content
Snippets Groups Projects
Commit 97f99171 authored by Javier Sagredo's avatar Javier Sagredo Committed by Mikolaj
Browse files

Use Base16 hash for script path.

Issue #9334 shows that `%` characters on Windows result in invalid
paths, also `/` characters on Linux create invalid paths.

This changes from using base64 to using base16 with the same length
we use for unit-ids.
parent 4f53a2fe
No related branches found
No related tags found
No related merge requests found
......@@ -209,7 +209,6 @@ library
async >= 2.0 && < 2.3,
array >= 0.4 && < 0.6,
base16-bytestring >= 0.1.1 && < 1.1.0.0,
base64-bytestring >= 1.0 && < 1.3,
binary >= 0.7.3 && < 0.9,
bytestring >= 0.10.6.0 && < 0.13,
containers >= 0.5.6.2 && < 0.8,
......
......@@ -7,7 +7,6 @@ module Distribution.Client.HashValue
, hashValue
, truncateHash
, showHashValue
, showHashValueBase64
, readFileHashValue
, hashFromTUF
) where
......@@ -19,7 +18,6 @@ import qualified Hackage.Security.Client as Sec
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Data.ByteString.Base16 as Base16
import qualified Data.ByteString.Base64 as Base64
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as LBS
......@@ -57,9 +55,6 @@ hashValue = HashValue . SHA256.hashlazy
showHashValue :: HashValue -> String
showHashValue (HashValue digest) = BS.unpack (Base16.encode digest)
showHashValueBase64 :: HashValue -> String
showHashValueBase64 (HashValue digest) = BS.unpack (Base64.encode digest)
-- | Hash the content of a file. Uses SHA256.
readFileHashValue :: FilePath -> IO HashValue
readFileHashValue tarball =
......
......@@ -37,7 +37,8 @@ import Distribution.Client.DistDirLayout
)
import Distribution.Client.HashValue
( hashValue
, showHashValueBase64
, showHashValue
, truncateHash
)
import Distribution.Client.HttpUtils
( HttpTransport
......@@ -218,18 +219,15 @@ import qualified Text.Parsec as P
-- repl to deal with the fact that the repl is relative to the working directory and not
-- the project root.
-- | Get the hash of a script's absolute path)
-- | Get the hash of a script's absolute path.
--
-- Two hashes will be the same as long as the absolute paths
-- are the same.
getScriptHash :: FilePath -> IO String
getScriptHash script =
-- Base64 is shorter than Base16, which helps avoid long path issues on windows
-- but it can contain /'s which aren't valid in file paths so replace them with
-- %'s. 26 chars / 130 bits is enough to practically avoid collisions.
map (\c -> if c == '/' then '%' else c)
. take 26
. showHashValueBase64
-- Truncation here tries to help with long path issues on Windows.
showHashValue
. truncateHash 26
. hashValue
. fromString
<$> canonicalizePath script
......
......@@ -60,7 +60,7 @@ library
, aeson ^>= 1.4.2.0 || ^>=1.5.0.0 || ^>= 2.0.0.0 || ^>= 2.1.0.0 || ^>= 2.2.1.0
, async ^>= 2.2.1
, attoparsec ^>= 0.13.2.2 || ^>=0.14.1
, base64-bytestring ^>= 1.0.0.0 || ^>= 1.1.0.0 || ^>= 1.2.0.0
, base16-bytestring ^>= 0.1.1.5 || ^>= 1.0
, bytestring ^>= 0.10.0.2 || ^>= 0.11.0.0 || ^>= 0.12.0.0
, containers ^>= 0.5.0.0 || ^>= 0.6.0.1
, cryptohash-sha256 ^>= 0.11.101.0
......@@ -120,6 +120,7 @@ executable setup
-- If you require an external dependency for a test it must be listed here.
executable test-runtime-deps
default-language: Haskell2010
build-depends: cabal-testsuite,
base,
directory,
......
......@@ -53,7 +53,7 @@ import Control.Monad (unless, when, void, forM_, liftM2, liftM4)
import Control.Monad.Trans.Reader (withReaderT, runReaderT)
import Control.Monad.IO.Class (MonadIO (..))
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Data.ByteString.Base64 as Base64
import qualified Data.ByteString.Base16 as Base16
import qualified Data.ByteString.Char8 as C
import Data.List (isInfixOf, stripPrefix, isPrefixOf, intercalate)
import Data.List.NonEmpty (NonEmpty (..))
......@@ -856,8 +856,7 @@ getScriptCacheDirectory :: FilePath -> TestM FilePath
getScriptCacheDirectory script = do
cabalDir <- testCabalDir `fmap` getTestEnv
hashinput <- liftIO $ canonicalizePath script
let hash = map (\c -> if c == '/' then '%' else c) . take 26
. C.unpack . Base64.encode . SHA256.hash . C.pack $ hashinput
let hash = C.unpack . Base16.encode . C.take 26 . SHA256.hash . C.pack $ hashinput
return $ cabalDir </> "script-builds" </> hash
------------------------------------------------------------------------
......
synopsis: Script cache dir is the base16 hash of the canonical path of the script.
prs: #9459
packages: cabal-install
description: {
Script cache dir is the base16 hash of the canonical path of the script.
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment