summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2025-10-08 23:06:24 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2025-10-08 23:06:24 +0200
commit818688ab0242a5d4329f9a690e6c119e4b3d34da (patch)
treea415c9d45cdd182985806d42e05dde2f2afb6f5d
parent3399d09c698953dfda8935eda8b87f1c402ae785 (diff)
Handle invalid record objects
Changelog: Gracefully handle invalid record objects
-rw-r--r--src/Erebos/Object/Internal.hs13
-rw-r--r--test/storage.et22
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"