From 19106e6d8b4bce6956f182c379aead9b1ac8cef7 Mon Sep 17 00:00:00 2001 From: Adithya Kumar Date: Mon, 9 Dec 2024 14:32:37 +0530 Subject: [PATCH] Throw and error when DT_UNKNOWN is the d_type in Posix.ReadDir --- .../Internal/FileSystem/Posix/ReadDir.hsc | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/src/Streamly/Internal/FileSystem/Posix/ReadDir.hsc b/core/src/Streamly/Internal/FileSystem/Posix/ReadDir.hsc index fbcf533a25..1e6904e4a9 100644 --- a/core/src/Streamly/Internal/FileSystem/Posix/ReadDir.hsc +++ b/core/src/Streamly/Internal/FileSystem/Posix/ReadDir.hsc @@ -20,6 +20,8 @@ module Streamly.Internal.FileSystem.Posix.ReadDir where #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__) +import Control.Exception (Exception(..), throwIO) +import Control.Monad (when) import Control.Monad.IO.Class (MonadIO(..)) import Data.Char (ord) import Foreign (Ptr, Word8, nullPtr, peek, peekByteOff, castPtr, plusPtr) @@ -80,6 +82,21 @@ data {-# CTYPE "struct dirent" #-} CDirent newtype DirStream = DirStream (Ptr CDir) +------------------------------------------------------------------------------- +-- Exception Type +------------------------------------------------------------------------------- + +newtype ReadDirException = + RDE_DT_UNKNOWN Path.PosixPath + +instance Show ReadDirException where + show (RDE_DT_UNKNOWN p) = + "DT_UNKNOWN: " ++ Path.toString p + +instance Exception ReadDirException + +------------------------------------------------------------------------------- +-- Functions ------------------------------------------------------------------------------- foreign import ccall unsafe "closedir" @@ -163,6 +180,10 @@ readDirStreamEither (DirStream dirp) = loop -- fromPtrN, but it is not straightforward because the reclen is -- padded to 8-byte boundary. name <- Array.fromCString (castPtr dname) + + when (dtype == #const DT_UNKNOWN) + $ throwIO (RDE_DT_UNKNOWN (mkPath name)) + if (dtype == #const DT_DIR) then do isMeta <- isMetaDir dname @@ -236,6 +257,9 @@ readEitherChunks alldirs = name <- Array.fromCString (castPtr dname) let path = Path.append curdir (mkPath name) + when (dtype == #const DT_UNKNOWN) + $ liftIO $ throwIO (RDE_DT_UNKNOWN path) + if (dtype == (#const DT_DIR)) then do isMeta <- liftIO $ isMetaDir dname @@ -396,6 +420,11 @@ readEitherByteChunks alldirs = dtype :: #{type unsigned char} <- liftIO $ #{peek struct dirent, d_type} dentPtr + when (dtype == #const DT_UNKNOWN) $ do + name <- Array.fromCString (castPtr dname) + let path = Path.append curdir (mkPath name) + liftIO $ throwIO (RDE_DT_UNKNOWN path) + -- XXX Skips come around the entire loop, does that impact perf -- because it has a StreamK in the middle. -- Keep the file check first as it is more likely