From 2ffe0a0127f9a4598ba2df8327ecbaa6e49c5f21 Mon Sep 17 00:00:00 2001 From: Vekhir <134215107+Vekhir@users.noreply.github.com> Date: Sun, 12 Jul 2026 11:52:44 +0200 Subject: [PATCH] Return length of 1 for continuation bytes A continuation byte is always at least one byte long; returning a length of two makes accidental out of bound reads more likely. Fixes #704 --- src/Data/Text/Internal/Encoding/Utf8.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Data/Text/Internal/Encoding/Utf8.hs b/src/Data/Text/Internal/Encoding/Utf8.hs index 14af4579..838680f2 100644 --- a/src/Data/Text/Internal/Encoding/Utf8.hs +++ b/src/Data/Text/Internal/Encoding/Utf8.hs @@ -82,13 +82,14 @@ utf8Length :: Char -> Int utf8Length (C# c) = I# ((1# +# geChar# c (chr# 0x80#)) +# (geChar# c (chr# 0x800#) +# geChar# c (chr# 0x10000#))) {-# INLINE utf8Length #-} --- | Measure byte length of UTF-8 encoding for characters, --- starting with a given byte. +-- | Measure byte length of UTF-8 encoding for characters +-- starting with the given leading byte. +-- Continuation bytes yield a fail-safe value of 1. -- -- @since 2.0 utf8LengthByLeader :: Word8 -> Int utf8LengthByLeader w - | w < 0x80 = 1 + | w < 0xC0 = 1 | w < 0xE0 = 2 | w < 0xF0 = 3 | otherwise = 4