Skip to content

Commit adaf924

Browse files
committed
Use Base16 hash for script path.
Issue haskell#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.
1 parent 88e4b00 commit adaf924

File tree

4 files changed

+16
-27
lines changed

4 files changed

+16
-27
lines changed

cabal-install/cabal-install.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ library
209209
async >= 2.0 && < 2.3,
210210
array >= 0.4 && < 0.6,
211211
base16-bytestring >= 0.1.1 && < 1.1.0.0,
212-
base64-bytestring >= 1.0 && < 1.3,
213212
binary >= 0.7.3 && < 0.9,
214213
bytestring >= 0.10.6.0 && < 0.13,
215214
containers >= 0.5.6.2 && < 0.8,

cabal-install/src/Distribution/Client/HashValue.hs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ module Distribution.Client.HashValue
77
, hashValue
88
, truncateHash
99
, showHashValue
10-
, showHashValueBase64
1110
, readFileHashValue
1211
, hashFromTUF
1312
) where
@@ -19,7 +18,6 @@ import qualified Hackage.Security.Client as Sec
1918

2019
import qualified Crypto.Hash.SHA256 as SHA256
2120
import qualified Data.ByteString.Base16 as Base16
22-
import qualified Data.ByteString.Base64 as Base64
2321
import qualified Data.ByteString.Char8 as BS
2422
import qualified Data.ByteString.Lazy.Char8 as LBS
2523

@@ -57,9 +55,6 @@ hashValue = HashValue . SHA256.hashlazy
5755
showHashValue :: HashValue -> String
5856
showHashValue (HashValue digest) = BS.unpack (Base16.encode digest)
5957

60-
showHashValueBase64 :: HashValue -> String
61-
showHashValueBase64 (HashValue digest) = BS.unpack (Base64.encode digest)
62-
6358
-- | Hash the content of a file. Uses SHA256.
6459
readFileHashValue :: FilePath -> IO HashValue
6560
readFileHashValue tarball =

cabal-install/src/Distribution/Client/ScriptUtils.hs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ import Distribution.Client.DistDirLayout
3636
, DistDirParams (..)
3737
)
3838
import Distribution.Client.HashValue
39-
( hashValue
40-
, showHashValueBase64
39+
( readFileHashValue
40+
, showHashValue
41+
, truncateHash
4142
)
4243
import Distribution.Client.HttpUtils
4344
( HttpTransport
@@ -218,33 +219,18 @@ import qualified Text.Parsec as P
218219
-- repl to deal with the fact that the repl is relative to the working directory and not
219220
-- the project root.
220221

221-
-- | Get the hash of a script's absolute path)
222-
--
223-
-- Two hashes will be the same as long as the absolute paths
224-
-- are the same.
222+
-- | Get the hash of a script's contents.
225223
getScriptHash :: FilePath -> IO String
226224
getScriptHash script =
227-
-- Base64 is shorter than Base16, which helps avoid long path issues on windows
228-
-- but it can contain /'s which aren't valid in file paths so replace them with
229-
-- %'s. 26 chars / 130 bits is enough to practically avoid collisions.
230-
map (\c -> if c == '/' then '%' else c)
231-
. take 26
232-
. showHashValueBase64
233-
. hashValue
234-
. fromString
235-
<$> canonicalizePath script
225+
showHashValue
226+
. truncateHash 26
227+
<$> readFileHashValue script
236228

237229
-- | Get the directory for caching a script build.
238-
--
239-
-- The only identity of a script is it's absolute path, so append the
240-
-- hashed path to the @script-builds@ dir to get the cache directory.
241230
getScriptCacheDirectory :: FilePath -> IO FilePath
242231
getScriptCacheDirectory script = (</>) <$> defaultScriptBuildsDir <*> getScriptHash script
243232

244233
-- | Get the directory for caching a script build and ensure it exists.
245-
--
246-
-- The only identity of a script is it's absolute path, so append the
247-
-- hashed path to the @script-builds@ dir to get the cache directory.
248234
ensureScriptCacheDirectory :: Verbosity -> FilePath -> IO FilePath
249235
ensureScriptCacheDirectory verbosity script = do
250236
cacheDir <- getScriptCacheDirectory script

changelog.d/base16-script-cache

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
synopsis: Script cache dir is the base16 hash of the contents of the script.
2+
prs: #9459
3+
packages: cabal-install
4+
5+
description: {
6+
7+
Script cache dir is the base16 hash of the contents of the script.
8+
9+
}

0 commit comments

Comments
 (0)