Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Fix a bug in `Data.Text.Fusion.mapAccumL` #50

merged 1 commit into from

2 participants


If the parameter f maps from Chars that fit in a single Word16 to Chars that require two Word16s, it is possible to write to an out-of-bounds index, as demonstrated by the following code:

module Main where

import Data.Char
import qualified Data.Text as T

main = do
  let f a c = (a, chr 65536)
  print . T.mapAccumL f 0 . T.pack $ "aaaaa"

If you run this code with -DASSERTS you'll get an exception. The source of the issue is that in the inner loop of Data.Text.Fusion.mapAccumL, you determine the safety of writing into the array based on the Char passed to f instead of the one it returns.

@bos bos merged commit 64149f2 into bos:master

Nice catch, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 11, 2013
  1. @gridaphobe
This page is out of date. Refresh to see the latest.
Showing with 3 additions and 3 deletions.
  1. +3 −3 Data/Text/Fusion.hs
6 Data/Text/Fusion.hs
@@ -223,9 +223,9 @@ mapAccumL f z0 (Stream next0 s0 len) = (nz,I.textP na 0 nl)
arr' <- top'
A.copyM arr' 0 arr 0 top
outer arr' top' z s i
- | otherwise -> do let (z',c) = f z x
- d <- unsafeWrite arr i c
+ | otherwise -> do d <- unsafeWrite arr i c
loop z' s' (i+d)
- where j | ord x < 0x10000 = i
+ where (z',c) = f z x
+ j | ord c < 0x10000 = i
| otherwise = i + 1
{-# INLINE [0] mapAccumL #-}
Something went wrong with that request. Please try again.