Skip to content

unfoldrN, unfoldrNM and fromListN are dangerous #301

@lehins

Description

@lehins

Size argument supplied to all three functions unfoldrN, unfoldrNM and fromListN serves as hint for upper bound for the length of a vector. The problem is that regardless of how big a vector would have been, the supplied upper bound memory is allocated, even if it too big, which can result in an application being killed with an asynchronous exception HeapOverflow

fromListN.hs:

import qualified Data.Vector.Primitive as V

main = do
  let xs = [1, 2, 3, 4, 5] :: [Int]
  print $ V.fromListN (maxBound `div` 8) xs
$ ghc fromListN.hs && ./fromListN
[1 of 1] Compiling Main             ( fromListN.hs, fromListN.o )
fromListN: Out of memory

unfoldrN.hs

import qualified Data.Vector.Primitive as V

main = print (V.unfoldrN (maxBound `div` 8) (const Nothing) () :: V.Vector Int)
$ ghc unfoldrN.hs && ./unfoldrN
[1 of 1] Compiling Main             ( unfoldrN.hs, unfoldrN.o )
Linking unfoldrN ...
unfoldrN: Out of memory

unfoldrNM.hs

import Control.Exception
import qualified Data.Vector.Primitive as V

main = do
  eRes <- try (V.unfoldrNM (maxBound `div` 8) (const $ pure Nothing) () :: IO (V.Vector Int))
  print (eRes :: Either SomeException (V.Vector Int))
$ stack exec -- ghc unfoldrNM.hs -O2 && ./unfoldrNM
[1 of 1] Compiling Main             ( unfoldrNM.hs, unfoldrNM.o )
Linking unfoldrNM ...
Left heap overflow

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions