Skip to content

Commit 5e67e18

Browse files
committed
Remove dependency on deprecated system-filepath
This patch removes `system-filepath` and tries to replace any existing functionality that that package provides. `system-filepath` has been deprecated in favor of `filepath`: https://hackage.haskell.org/package/system-filepath
1 parent 4c641cc commit 5e67e18

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

happstack-server.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ Library
8484
process,
8585
semigroups >= 0.16,
8686
sendfile >= 0.7.1 && < 0.8,
87-
system-filepath >= 0.3.1,
8887
syb,
8988
text >= 0.10 && < 1.3,
9089
time,

src/Happstack/Server/FileServe/BuildingBlocks.hs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,18 @@ import Control.Monad.Trans (MonadIO(liftIO))
6060
import qualified Data.ByteString.Lazy.Char8 as L
6161
import qualified Data.ByteString.Char8 as S
6262
import Data.Data (Data, Typeable)
63+
import Data.Foldable (toList)
6364
import Data.List (sort)
6465
import Data.Maybe (fromMaybe)
6566
import Data.Map (Map)
6667
import qualified Data.Map as Map
67-
import Filesystem.Path.CurrentOS (commonPrefix, encodeString, decodeString, collapse, append)
68+
import Data.Sequence (Seq ((:|>)), (|>))
69+
import qualified Data.Sequence as Seq
6870
import Happstack.Server.Monads (ServerMonad(askRq), FilterMonad, WebMonad)
6971
import Happstack.Server.Response (ToMessage(toResponse), ifModifiedSince, forbidden, ok, seeOther)
7072
import Happstack.Server.Types (Length(ContentLength), Request(rqPaths, rqUri), Response(SendFile), RsFlags(rsfLength), nullRsFlags, result, resultBS, setHeader)
7173
import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents, getModificationTime)
72-
import System.FilePath ((</>), addTrailingPathSeparator, hasDrive, isPathSeparator, joinPath, takeExtension, isValid)
74+
import System.FilePath ((</>), addTrailingPathSeparator, hasDrive, isPathSeparator, joinPath, takeExtension, isValid, normalise, splitPath)
7375
import System.IO (IOMode(ReadMode), hFileSize, hClose, openBinaryFile, withBinaryFile)
7476
import System.Log.Logger (Priority(DEBUG), logM)
7577
import Text.Blaze.Html ((!))
@@ -384,14 +386,22 @@ fileServe' serveFn mimeFn indexFn localPath = do
384386
-- >>> combineSafe "/var/uploads/" "../uploads/home/../etc/passwd"
385387
-- Just "/var/uploads/etc/passwd"
386388
combineSafe :: FilePath -> FilePath -> Maybe FilePath
387-
combineSafe root path =
388-
if commonPrefix [root', joined] == root'
389-
then Just $ encodeString joined
390-
else Nothing
389+
combineSafe root path = do
390+
pathSeq <- go Seq.empty $ splitPath $ normalise path
391+
let root' = normalise root
392+
let path' = joinPath (toList pathSeq)
393+
Just $ root' </> path'
391394
where
392-
root' = decodeString root
393-
path' = decodeString path
394-
joined = collapse $ append root' path'
395+
-- | Build up a 'Seq' representation of @path@, reducing any @..@ elements and returning
396+
-- @'Nothing'@ if it tries to go up beyond its top level.
397+
--
398+
-- Note that this functionality has been removed from the filepath package
399+
-- See: <https://neilmitchell.blogspot.com/2015/10/filepaths-are-subtle-symlinks-are-hard.html>
400+
go :: Seq FilePath -> [FilePath] -> Maybe (Seq FilePath)
401+
go p [] = Just p
402+
go Seq.Empty ("..":_ ) = Nothing -- Going up beyond the top level is not allowed
403+
go (s :|> _) ("..":ps) = go s ps -- Going up a level pops an element off the right side of the Seq
404+
go s (p :ps) = go (s |> p) ps -- Just add an element to the right side of the Seq
395405

396406
isSafePath :: [FilePath] -> Bool
397407
isSafePath [] = True

0 commit comments

Comments
 (0)