Commit bc05d359 authored by Ömer Sinan Ağacan's avatar Ömer Sinan Ağacan Committed by Ben Gamari

FastString: fix eager reading of string ptr in hashStr

This read causes NULL dereferencing when len is 0.

Fixes #17909

In the reproducer in #17909 this bug is triggered as follows:

- SimplOpt.dealWithStringLiteral is called with a single-char string
  ("=" in #17909)

- tailFS gets called on the FastString of the single-char string.

- tailFS checks the length of the string, which is 1, and calls
  mkFastStringByteString on the tail of the ByteString, which is an
  empty ByteString as the original ByteString has only one char.

- ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty
  ByteString, which is passed to mkFastStringWith.

- mkFastStringWith gets hash of the NULL pointer via hashStr, which
  fails on empty strings because of this bug.

(cherry picked from commit cb1785d9)
parent 9037a2b6
Pipeline #20193 passed with stages
in 423 minutes and 57 seconds
......@@ -519,16 +519,22 @@ cmpStringPrefix ptr1 ptr2 len =
do r <- memcmp ptr1 ptr2 len
return (r == 0)
hashStr :: Ptr Word8 -> Int -> Int
-- use the Addr to produce a hash value between 0 & m (inclusive)
hashStr (Ptr a#) (I# len#) = loop 0# 0#
where
loop h n | isTrue# (n ==# len#) = I# h
| otherwise = loop h2 (n +# 1#)
where
!c = ord# (indexCharOffAddr# a# n)
!h2 = (h *# 16777619#) `xorI#` c
where
loop h n =
if isTrue# (n ==# len#) then
I# h
else
let
-- DO NOT move this let binding! indexCharOffAddr# reads from the
-- pointer so we need to evaluate this based on the length check
-- above. Not doing this right caused #17909.
!c = ord# (indexCharOffAddr# a# n)
!h2 = (h *# 16777619#) `xorI#` c
in
loop h2 (n +# 1#)
-- -----------------------------------------------------------------------------
-- Operations
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment