LIB: improve safety by ignoring invalid file names for file operations
This commit is contained in:
parent
9445574097
commit
f2fb4e0be0
@ -324,6 +324,9 @@ pattern InvFN <- (invalidFileName -> (True,_))
|
|||||||
-- |Opposite of `InvFN`.
|
-- |Opposite of `InvFN`.
|
||||||
pattern ValFN f <- (invalidFileName -> (False, f))
|
pattern ValFN f <- (invalidFileName -> (False, f))
|
||||||
|
|
||||||
|
pattern AFileInvFN <- (fst . invalidFileName . name . file -> True)
|
||||||
|
pattern FileInvFN <- (fst . invalidFileName . name -> True)
|
||||||
|
|
||||||
|
|
||||||
-- |Matches on directories or symlinks pointing to directories.
|
-- |Matches on directories or symlinks pointing to directories.
|
||||||
-- If the symlink is pointing to a symlink pointing to a directory, then
|
-- If the symlink is pointing to a symlink pointing to a directory, then
|
||||||
|
@ -71,6 +71,7 @@ data FmIOException = FileDoesNotExist String
|
|||||||
| DirDoesExist String
|
| DirDoesExist String
|
||||||
| IsSymlink String
|
| IsSymlink String
|
||||||
| InvalidOperation String
|
| InvalidOperation String
|
||||||
|
| InvalidFileName
|
||||||
deriving (Show, Typeable)
|
deriving (Show, Typeable)
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +157,8 @@ copyDir :: DirCopyMode
|
|||||||
-> AnchoredFile FileInfo -- ^ source dir
|
-> AnchoredFile FileInfo -- ^ source dir
|
||||||
-> AnchoredFile FileInfo -- ^ destination dir
|
-> AnchoredFile FileInfo -- ^ destination dir
|
||||||
-> IO ()
|
-> IO ()
|
||||||
copyDir cm (_ :/ SymLink {}) _ = return ()
|
copyDir _ AFileInvFN _ = throw InvalidFileName
|
||||||
|
copyDir _ _ AFileInvFN = throw InvalidFileName
|
||||||
copyDir cm from@(_ :/ Dir fromn _)
|
copyDir cm from@(_ :/ Dir fromn _)
|
||||||
to@(_ :/ Dir {})
|
to@(_ :/ Dir {})
|
||||||
= do
|
= do
|
||||||
@ -209,6 +210,8 @@ recreateSymlink :: AnchoredFile FileInfo -- ^ the old symlink file
|
|||||||
-> AnchoredFile FileInfo -- ^ destination dir of the
|
-> AnchoredFile FileInfo -- ^ destination dir of the
|
||||||
-- new symlink file
|
-- new symlink file
|
||||||
-> IO ()
|
-> IO ()
|
||||||
|
recreateSymlink AFileInvFN _ = throw InvalidFileName
|
||||||
|
recreateSymlink _ AFileInvFN = throw InvalidFileName
|
||||||
recreateSymlink symf@(_ :/ SymLink {})
|
recreateSymlink symf@(_ :/ SymLink {})
|
||||||
symdest@(_ :/ Dir {})
|
symdest@(_ :/ Dir {})
|
||||||
= do
|
= do
|
||||||
@ -221,6 +224,8 @@ recreateSymlink _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
-- |Low-level function to copy a given file to the given path. The fileMode
|
-- |Low-level function to copy a given file to the given path. The fileMode
|
||||||
-- is preserved.
|
-- is preserved.
|
||||||
copyFile' :: FilePath -> FilePath -> IO ()
|
copyFile' :: FilePath -> FilePath -> IO ()
|
||||||
|
copyFile' InvFN _ = throw InvalidFileName
|
||||||
|
copyFile' _ InvFN = throw InvalidFileName
|
||||||
copyFile' from to = do
|
copyFile' from to = do
|
||||||
fromFstatus <- getSymbolicLinkStatus from
|
fromFstatus <- getSymbolicLinkStatus from
|
||||||
fromContent <- BS.readFile from
|
fromContent <- BS.readFile from
|
||||||
@ -235,6 +240,8 @@ copyFile' from to = do
|
|||||||
copyFile :: AnchoredFile FileInfo -- ^ source file
|
copyFile :: AnchoredFile FileInfo -- ^ source file
|
||||||
-> AnchoredFile FileInfo -- ^ destination file
|
-> AnchoredFile FileInfo -- ^ destination file
|
||||||
-> IO ()
|
-> IO ()
|
||||||
|
copyFile AFileInvFN _ = throw InvalidFileName
|
||||||
|
copyFile _ AFileInvFN = throw InvalidFileName
|
||||||
copyFile (_ :/ SymLink {}) _ = return ()
|
copyFile (_ :/ SymLink {}) _ = return ()
|
||||||
copyFile from@(_ :/ RegFile {}) to@(_ :/ RegFile {}) = do
|
copyFile from@(_ :/ RegFile {}) to@(_ :/ RegFile {}) = do
|
||||||
let from' = fullPath from
|
let from' = fullPath from
|
||||||
@ -249,6 +256,8 @@ copyFile _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
copyFileToDir :: AnchoredFile FileInfo
|
copyFileToDir :: AnchoredFile FileInfo
|
||||||
-> AnchoredFile FileInfo
|
-> AnchoredFile FileInfo
|
||||||
-> IO ()
|
-> IO ()
|
||||||
|
copyFileToDir AFileInvFN _ = throw InvalidFileName
|
||||||
|
copyFileToDir _ AFileInvFN = throw InvalidFileName
|
||||||
copyFileToDir (_ :/ SymLink {}) _ = return ()
|
copyFileToDir (_ :/ SymLink {}) _ = return ()
|
||||||
copyFileToDir from@(_ :/ RegFile fn _)
|
copyFileToDir from@(_ :/ RegFile fn _)
|
||||||
to@(_ :/ Dir {}) =
|
to@(_ :/ Dir {}) =
|
||||||
@ -288,6 +297,7 @@ easyCopy _ _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
-- |Deletes a symlink, which can either point to a file or directory.
|
-- |Deletes a symlink, which can either point to a file or directory.
|
||||||
deleteSymlink :: AnchoredFile FileInfo -> IO ()
|
deleteSymlink :: AnchoredFile FileInfo -> IO ()
|
||||||
|
deleteSymlink AFileInvFN = throw InvalidFileName
|
||||||
deleteSymlink f@(_ :/ SymLink {})
|
deleteSymlink f@(_ :/ SymLink {})
|
||||||
= removeLink (fullPath f)
|
= removeLink (fullPath f)
|
||||||
deleteSymlink _ = throw $ InvalidOperation "wrong input type"
|
deleteSymlink _ = throw $ InvalidOperation "wrong input type"
|
||||||
@ -295,6 +305,7 @@ deleteSymlink _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
-- |Deletes the given file, never symlinks.
|
-- |Deletes the given file, never symlinks.
|
||||||
deleteFile :: AnchoredFile FileInfo -> IO ()
|
deleteFile :: AnchoredFile FileInfo -> IO ()
|
||||||
|
deleteFile AFileInvFN = throw InvalidFileName
|
||||||
deleteFile (_ :/ SymLink {}) = return ()
|
deleteFile (_ :/ SymLink {}) = return ()
|
||||||
deleteFile f@(_ :/ RegFile {})
|
deleteFile f@(_ :/ RegFile {})
|
||||||
= removeLink (fullPath f)
|
= removeLink (fullPath f)
|
||||||
@ -303,6 +314,7 @@ deleteFile _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
-- |Deletes the given directory, never symlinks.
|
-- |Deletes the given directory, never symlinks.
|
||||||
deleteDir :: AnchoredFile FileInfo -> IO ()
|
deleteDir :: AnchoredFile FileInfo -> IO ()
|
||||||
|
deleteDir AFileInvFN = throw InvalidFileName
|
||||||
deleteDir (_ :/ SymLink {}) = return ()
|
deleteDir (_ :/ SymLink {}) = return ()
|
||||||
deleteDir f@(_ :/ Dir {})
|
deleteDir f@(_ :/ Dir {})
|
||||||
= removeDirectory (fullPath f)
|
= removeDirectory (fullPath f)
|
||||||
@ -311,6 +323,7 @@ deleteDir _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
-- |Deletes the given directory recursively.
|
-- |Deletes the given directory recursively.
|
||||||
deleteDirRecursive :: AnchoredFile FileInfo -> IO ()
|
deleteDirRecursive :: AnchoredFile FileInfo -> IO ()
|
||||||
|
deleteDirRecursive AFileInvFN = throw InvalidFileName
|
||||||
deleteDirRecursive f@(_ :/ Dir {}) = do
|
deleteDirRecursive f@(_ :/ Dir {}) = do
|
||||||
let fp = fullPath f
|
let fp = fullPath f
|
||||||
files <- readDirectory' fp
|
files <- readDirectory' fp
|
||||||
@ -346,6 +359,7 @@ easyDelete _ = throw $ InvalidOperation "wrong input type"
|
|||||||
-- |Opens a file appropriately by invoking xdg-open.
|
-- |Opens a file appropriately by invoking xdg-open.
|
||||||
openFile :: AnchoredFile a
|
openFile :: AnchoredFile a
|
||||||
-> IO ProcessHandle
|
-> IO ProcessHandle
|
||||||
|
openFile AFileInvFN = throw InvalidFileName
|
||||||
openFile f = spawnProcess "xdg-open" [fullPath f]
|
openFile f = spawnProcess "xdg-open" [fullPath f]
|
||||||
|
|
||||||
|
|
||||||
@ -353,6 +367,7 @@ openFile f = spawnProcess "xdg-open" [fullPath f]
|
|||||||
executeFile :: AnchoredFile FileInfo -- ^ program
|
executeFile :: AnchoredFile FileInfo -- ^ program
|
||||||
-> [String] -- ^ arguments
|
-> [String] -- ^ arguments
|
||||||
-> IO ProcessHandle
|
-> IO ProcessHandle
|
||||||
|
executeFile AFileInvFN _ = throw InvalidFileName
|
||||||
executeFile prog@(_ :/ RegFile {}) args
|
executeFile prog@(_ :/ RegFile {}) args
|
||||||
= spawnProcess (fullPath prog) args
|
= spawnProcess (fullPath prog) args
|
||||||
executeFile _ _ = throw $ InvalidOperation "wrong input type"
|
executeFile _ _ = throw $ InvalidOperation "wrong input type"
|
||||||
@ -366,6 +381,8 @@ executeFile _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
|
|
||||||
createFile :: AnchoredFile FileInfo -> FileName -> IO ()
|
createFile :: AnchoredFile FileInfo -> FileName -> IO ()
|
||||||
|
createFile AFileInvFN _ = throw InvalidFileName
|
||||||
|
createFile _ InvFN = throw InvalidFileName
|
||||||
createFile (ADirOrSym td) (ValFN fn) = do
|
createFile (ADirOrSym td) (ValFN fn) = do
|
||||||
let fullp = fullPath td </> fn
|
let fullp = fullPath td </> fn
|
||||||
throwFileDoesExist fullp
|
throwFileDoesExist fullp
|
||||||
@ -375,6 +392,8 @@ createFile _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
|
|
||||||
createDir :: AnchoredFile FileInfo -> FileName -> IO ()
|
createDir :: AnchoredFile FileInfo -> FileName -> IO ()
|
||||||
|
createDir AFileInvFN _ = throw InvalidFileName
|
||||||
|
createDir _ InvFN = throw InvalidFileName
|
||||||
createDir (ADirOrSym td) (ValFN fn) = do
|
createDir (ADirOrSym td) (ValFN fn) = do
|
||||||
let fullp = fullPath td </> fn
|
let fullp = fullPath td </> fn
|
||||||
throwDirDoesExist fullp
|
throwDirDoesExist fullp
|
||||||
@ -390,6 +409,8 @@ createDir _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
|
|
||||||
|
|
||||||
renameFile :: AnchoredFile FileInfo -> FileName -> IO ()
|
renameFile :: AnchoredFile FileInfo -> FileName -> IO ()
|
||||||
|
renameFile AFileInvFN _ = throw InvalidFileName
|
||||||
|
renameFile _ InvFN = throw InvalidFileName
|
||||||
renameFile (_ :/ Failed {}) _ = return ()
|
renameFile (_ :/ Failed {}) _ = return ()
|
||||||
renameFile af (ValFN fn) = do
|
renameFile af (ValFN fn) = do
|
||||||
let fromf = fullPath af
|
let fromf = fullPath af
|
||||||
@ -404,6 +425,8 @@ renameFile _ _ = throw $ InvalidOperation "wrong input type"
|
|||||||
moveFile :: AnchoredFile FileInfo -- ^ file to move
|
moveFile :: AnchoredFile FileInfo -- ^ file to move
|
||||||
-> AnchoredFile FileInfo -- ^ base target directory
|
-> AnchoredFile FileInfo -- ^ base target directory
|
||||||
-> IO ()
|
-> IO ()
|
||||||
|
moveFile AFileInvFN _ = throw InvalidFileName
|
||||||
|
moveFile _ AFileInvFN = throw InvalidFileName
|
||||||
moveFile from to@(_ :/ Dir {}) = do
|
moveFile from to@(_ :/ Dir {}) = do
|
||||||
let from' = fullPath from
|
let from' = fullPath from
|
||||||
to' = fullPath to </> (name . file $ from)
|
to' = fullPath to </> (name . file $ from)
|
||||||
|
Loading…
Reference in New Issue
Block a user