Skip to content

Commit 261a6fa

Browse files
committed
Handle invalid UTF-8 in label
I hadn't actually considered that `decodeUtf8` must be partial until stumbling across ndmitchell/hlint#1280. It would actually be very odd for us to hit this in practice, so there's no need to do more sophisticated error handling. The string passed to `fail` will end up in a thrown `LifxError.DecodeFailure`. The impossible case covers a deprecated constructor. When it is finally removed, we'll get a warning prompting us to remove the redundant wildcard.
1 parent 4ff8a1a commit 261a6fa

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

src/Lifx/Lan.hs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ import Data.List.NonEmpty (NonEmpty)
100100
import Data.Map (Map)
101101
import Data.Map.Strict qualified as Map
102102
import Data.Text (Text)
103-
import Data.Text.Encoding (decodeUtf8)
103+
import Data.Text.Encoding (decodeUtf8')
104+
import Data.Text.Encoding.Error (UnicodeException (DecodeError))
104105
import GHC.Generics (Generic)
105106
import Network.Socket.ByteString (recvFrom, sendTo)
106107
import System.Random (randomIO)
@@ -317,9 +318,13 @@ instance Response LightState where
317318
hsbk <- HSBK <$> getWord16le <*> getWord16le <*> getWord16le <*> getWord16le
318319
skip 2
319320
power <- getWord16le
320-
label <- decodeUtf8 . BS.takeWhile (/= 0) <$> getByteString 32
321+
label <- either (fail . showDecodeError) pure . decodeUtf8' . BS.takeWhile (/= 0) =<< getByteString 32
321322
skip 8
322323
pure LightState{..}
324+
where
325+
showDecodeError = \case
326+
DecodeError s _ -> s
327+
_ -> "impossible"
323328
instance MessageResult LightState
324329

325330
msgResWitness :: (MessageResult r => Message r -> a) -> (Message r -> a)

0 commit comments

Comments
 (0)