Severe memory issues in basement strings #447
Description
By tracking down some bugs, I found quite a few places where foundation strings aren't memory safe. The example I started from was sToListStream
, particularly:
onAddr fptr (Ptr ptr) = pureST (loop start)
where
loop !idx
| idx == end = z
| otherwise = let !(Step c idx') = PrimAddr.next ptr idx in c `k` loop idx'
The onAddr
here basically ensures the fptr
holding the memory is available for zero time, as long as it takes pure x
to evaluate the pure
part but not any of the x
part. Moreover, because of laziness, there's no way a single withFinalPtr
could ever work - you absolutely have to have a withFinalPtr
on each PrimAddr.next
. Moreover, that withFinalPtr
and the corresponding touch
inside it had really better occur in a fixed order with respect to accessing the underlying Addr#
- so I think primIndex
is fundamentally dodgy called on anything other than infinitely accessible constants. It's used heavily on String
, and I think that's a source of plenty of bugs.
I suggest making primIndex
in IO and fixing what it shows up, but at the very least you definitely need to fix sToListStream
and sToList
- and I'm certain I'll find more if you don't fix it in a way the type system prevents it.