Skip to content

Commit 6a74a47

Browse files
committed
Fix out-of-bound access to "alex_check" array
`offset` can be negative. We must check this before using it to index into `alex_check` array. The issue is that 'check' is unlifted, hence it's a strict binding. The way it was written before, it was evaluated before checking that offset was greater than or equal to 0. I've just moved the binding after the check. Caught with GHC's JS backend running Cabal-syntax's lexer. The JS backend uses arrays to represent unlifted string literals, so the bug results in out-of-bound JS array access. With the native backends the out-of-bound array access might trigger a segfault but it is more likely to just read some random values in the heap. That's why it went unnoticed.
1 parent 01990bd commit 6a74a47

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Change in 3.2.7.2
2+
3+
* Fix bug with out-of-bound access to `alex_check` array.
4+
15
## Change in 3.2.7.1
26

37
* Fix bug with repeated numeral characters *outside* of `r{n,m}`

Diff for: alex.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: >= 1.10
22
name: alex
3-
version: 3.2.7.1
3+
version: 3.2.7.2
44
-- don't forget updating changelog.md!
55
license: BSD3
66
license-file: LICENSE

Diff for: data/AlexTemplate.hs

+8-4
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,15 @@ alex_scan_tkn user__ orig_input len input__ s last_acc =
161161
let
162162
base = alexIndexInt32OffAddr alex_base s
163163
offset = PLUS(base,ord_c)
164-
check = alexIndexInt16OffAddr alex_check offset
165164

166-
new_s = if GTE(offset,ILIT(0)) && EQ(check,ord_c)
167-
then alexIndexInt16OffAddr alex_table offset
168-
else alexIndexInt16OffAddr alex_deflt s
165+
new_s
166+
| GTE(offset,ILIT(0))
167+
, check <- alexIndexInt16OffAddr alex_check offset
168+
, EQ(check,ord_c)
169+
= alexIndexInt16OffAddr alex_table offset
170+
171+
| otherwise
172+
= alexIndexInt16OffAddr alex_deflt s
169173
in
170174
case new_s of
171175
ILIT(-1) -> (new_acc, input__)

0 commit comments

Comments
 (0)