IOExts.slurpFile fails on zero-length files

Volker Stolz vs at foldr.org
Wed May 8 11:09:13 EDT 2002


Am 02. May 2002 um 22:20 CEST schrieb George Russell:
> *** Exception: invalid argument
> Action: hGetBuf
> Handle: {loc=/tmp/d,type=readable,binary=False,buffering=block (8192)}
> Reason: illegal buffer size 0

Yes, that's straight forward to see in the source. I'm not sure where to
place the fix.

slurpFile calls hGetBuf which issued the offending error in your case:

slurpFile :: FilePath -> IO (Ptr (), Int)
slurpFile fname = do
  handle <- openFile fname ReadMode
  sz     <- hFileSize handle
  if sz > fromIntegral (maxBound::Int) then 
    ioError (userError "slurpFile: file too big")
   else do
    let sz_i = fromIntegral sz
    chunk <- mallocBytes sz_i
    r <- hGetBuf handle chunk sz_i
    hClose handle
    return (chunk, r)

hGetBuf :: Handle -> Ptr a -> Int -> IO Int
hGetBuf handle ptr count
  | count <= 0 = illegalBufferSize handle "hGetBuf" count
  | otherwise = 

The obvious fix would be to check the size in 'slurpFile' and don't
call 'hGetBuf' with an argument of zero, which means somebody else
who calls 'hGetBuf' with 0 might get tripped up.

Unluckily it doesn't look easy to make 'hGetBuf' fail more gracefully
(you could read 0 bytes after all), because then still the
'mallocBytes 0' in 'slurpFile' will probably fail -- to quote FreeBSD's
man page for malloc:

"It can be argued that returning a NULL pointer when asked to allocate
     zero bytes is a silly response to a silly question."

Does somebody object to fixing things in 'slurpFile'?

Volker



More information about the Glasgow-haskell-bugs mailing list