Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integer overflow in replace #81

Closed
rwbarton opened this issue Jun 5, 2014 · 1 comment
Closed

integer overflow in replace #81

rwbarton opened this issue Jun 5, 2014 · 1 comment

Comments

@rwbarton
Copy link

rwbarton commented Jun 5, 2014

It's obvious that a lot of care went into properly handling integer overflow in this library. In the spirit of completeness, here is one spot that slipped through the cracks.

replace :: Text -> Text -> Text -> Text
replace needle@(Text _      _      neeLen)
               (Text repArr repOff repLen)
      haystack@(Text hayArr hayOff hayLen)
  | neeLen == 0 = emptyError "replace"
  | L.null ixs  = haystack
  | len > 0     = Text (A.run x) 0 len
  | len < 0     = overflowError "replace"
  | otherwise   = empty
  where
    ixs = indices needle haystack
    len = hayLen - (neeLen - repLen) * L.length ixs
    x = do {- ... -}

The computation of len can overflow to a incorrect but positive value, whereupon the loop will write off the end of the allocated array. On a 64-bit system, you need to have already allocated quite a lot of memory to trigger this overflow (something like 60 GB):

import qualified Data.Text as T

main = print $ T.head $ T.replace
       (T.singleton 'a')
       (T.replicate (2^34+1) (T.singleton 'b'))
       (T.replicate (2^30) (T.singleton 'a'))

On a 32-bit system, you can reduce both exponents above by 16 and then it is quite easy to reproduce the segmentation fault.

bos added a commit that referenced this issue Jun 6, 2014
This is a building block for gh-81.

--HG--
extra : amend_source : 83f1822fb6519becf548c19f74a9716dd00657f0
extra : histedit_source : 4d4b35eb9b7bd9f1ef294ca8afb76716211ed61d%2C4f5c1c3951ff68c503a5f92be6999e2d8a4c74ab
bos added a commit that referenced this issue Jun 6, 2014
Progress towards gh-81.

--HG--
extra : rebase_source : 0559da50e2b5d43f46e4c4baa9f4b5457e8781da
extra : amend_source : 1c20c33aa19bece776361953371efc46d0ec236e
extra : histedit_source : a7aba7dd23ae5f886fd41e3f0856da129165c878
@bos bos closed this as completed in 466172d Jun 6, 2014
@bos
Copy link
Contributor

bos commented Jun 6, 2014

Thanks for the report. I fixed this and found a faster checked multiply along the way.

jsonn pushed a commit to jsonn/pkgsrc that referenced this issue Sep 14, 2014
changelog:
1.2.0.0

* Fixed an integer overflow in the replace function
  (haskell/text#81)

* Fixed a hang in lazy decodeUtf8With
  (haskell/text#87)

* Reduced codegen bloat caused by use of empty and single-character
  literals

* Added an instance of IsList for GHC 7.8 and above
jsonn pushed a commit to jsonn/pkgsrc that referenced this issue Oct 11, 2014
changelog:
1.2.0.0

* Fixed an integer overflow in the replace function
  (haskell/text#81)

* Fixed a hang in lazy decodeUtf8With
  (haskell/text#87)

* Reduced codegen bloat caused by use of empty and single-character
  literals

* Added an instance of IsList for GHC 7.8 and above
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants