Skip to content

Commit 0134f59

Browse files
authored
Avoid creating an out-of-bounds Char (#47)
insertRange and deleteRange can create a Char that is maxBound+1. This doesn't cause problems because 1. we create it with unsafeChr and 2. it is passed to split and simply ord-ed back. Pass the ord value directly instead.
1 parent 7f79dd5 commit 0134f59

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

Diff for: src/Regex/Internal/CharSet.hs

+10-10
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ insertRange :: (Char, Char) -> CharSet -> CharSet
105105
insertRange (cl,ch) cs | cl > ch = cs
106106
insertRange (cl,ch) cs = l `join` fromRange (cl,ch) `join` r
107107
where
108-
(l,mr) = split cl cs
109-
(_,r) = split (unsafeChr (ord ch + 1)) mr
108+
(l,mr) = split (ord cl) cs
109+
(_,r) = split (ord ch + 1) mr
110110

111111
-- | \(O(\min(n,C))\). Delete a @Char@ from a set.
112112
delete :: Char -> CharSet -> CharSet
@@ -117,8 +117,8 @@ deleteRange :: (Char, Char) -> CharSet -> CharSet
117117
deleteRange (cl,ch) cs | cl > ch = cs
118118
deleteRange (cl,ch) cs = l `join` r
119119
where
120-
(l,mr) = split cl cs
121-
(_,r) = split (unsafeChr (ord ch + 1)) mr
120+
(l,mr) = split (ord cl) cs
121+
(_,r) = split (ord ch + 1) mr
122122

123123
-- | \(O(s \min(s,C))\). Map a function over all @Char@s in a set.
124124
map :: (Char -> Char) -> CharSet -> CharSet
@@ -169,14 +169,14 @@ ranges cs = [(unsafeChr cl, ch) | (cl,ch) <- IM.assocs (unCharSet cs)]
169169
--------------------
170170

171171
-- | \(O(\min(n,W))\). Split a set into one containing @Char@s smaller than
172-
-- the given @Char@ and one greater than or equal to the given @Char@.
173-
split :: Char -> CharSet -> (CharSet, CharSet)
174-
split !c cs = case IM.splitLookup (ord c) (unCharSet cs) of
175-
(l, Just ch, r) -> (CharSet l, CharSet $ IM.insert (ord c) ch r)
172+
-- the given char and one greater than or equal to the given char.
173+
split :: Int -> CharSet -> (CharSet, CharSet)
174+
split !c cs = case IM.splitLookup c (unCharSet cs) of
175+
(l, Just ch, r) -> (CharSet l, CharSet $ IM.insert c ch r)
176176
(l, Nothing, r) -> case IM.maxViewWithKey l of
177177
Just ((lgl,lgh),l1)
178-
| lgh >= c -> ( CharSet $ IM.insert lgl (unsafeChr (ord c - 1)) l1
179-
, CharSet $ IM.insert (ord c) lgh r )
178+
| ord lgh >= c -> ( CharSet $ IM.insert lgl (unsafeChr (c - 1)) l1
179+
, CharSet $ IM.insert c lgh r )
180180
_ -> (CharSet l, CharSet r)
181181
-- The bang on c helps because splitLookup was unfortunately not strict in
182182
-- the lookup key until https://github.com/haskell/containers/pull/982.

0 commit comments

Comments
 (0)