From 818688ab0242a5d4329f9a690e6c119e4b3d34da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 8 Oct 2025 23:06:24 +0200 Subject: Handle invalid record objects Changelog: Gracefully handle invalid record objects --- src/Erebos/Object/Internal.hs | 13 ++++++++----- test/storage.et | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/Erebos/Object/Internal.hs b/src/Erebos/Object/Internal.hs index fdb587a..4604f13 100644 --- a/src/Erebos/Object/Internal.hs +++ b/src/Erebos/Object/Internal.hs @@ -236,11 +236,14 @@ unsafeDeserializeObject st bytes = (line, rest) | Just (otype, len) <- splitObjPrefix line -> do let (content, next) = first BL.toStrict $ BL.splitAt (fromIntegral len) $ BL.drop 1 rest guard $ B.length content == len - (,next) <$> case otype of - _ | otype == BC.pack "blob" -> return $ Blob content - | otype == BC.pack "rec" -> maybe (throwOtherError $ "malformed record item ") - (return . Rec) $ sequence $ map parseRecLine $ mergeCont [] $ BC.lines content - | otherwise -> return $ UnknownObject otype content + (, next) <$> if + | otype == BC.pack "blob" + -> return $ Blob content + | otype == BC.pack "rec" + , Just ritems <- sequence $ map parseRecLine $ mergeCont [] $ BC.lines content + -> return $ Rec ritems + | otherwise + -> return $ UnknownObject otype content _ -> throwOtherError $ "malformed object" where splitObjPrefix line = do [otype, tlen] <- return $ BLC.words line diff --git a/test/storage.et b/test/storage.et index 9bbbe6b..035a64b 100644 --- a/test/storage.et +++ b/test/storage.et @@ -566,6 +566,28 @@ test ObjectFormat: expect /load-type (.*)/ capture type guard (type == "rec") + # Record with unknown type + local: + send "store-raw EOF" + send "rec 14\nnum:UNKNOWN 1\n" + send "EOF" + expect /store-done ($refpat)/ capture r + + send "load-type $r" + expect /load-type (.*)/ capture type + guard (type == "rec") + + # Invalid records + for content in [ "rec 6\nnum 1\n", "rec 6\nnum:n\n" ]: + send "store-raw EOF" + send "$content" + send "EOF" + expect /store-done ($refpat)/ capture r + + send "load-type $r" + expect /load-type (.*)/ capture type + guard (type == "unknown rec") + # Empty unknown local: send "store-raw EOF" -- cgit v1.2.3