@@ -71,29 +71,33 @@ getAttributes :: (Word8 -> h -> Maybe (Get h))
71
71
-> Word32
72
72
-> h
73
73
-> Get (Attributes h )
74
- getAttributes keyGetMapper maxLen initData = do
75
- totalLen <- getWord32be
74
+ getAttributes keyGetMapper (fromIntegral -> maxLen) initData = do
75
+ -- CSL-594 TODO use varint
76
+ totalLen <- fromIntegral <$> getWord32be
76
77
when (maxLen > 0 && totalLen > maxLen) $
77
78
fail $ " Attributes: wrong totalLen " ++ show totalLen
78
79
++ " (maxLen=" ++ show maxLen ++ " )"
79
80
read1 <- G. bytesRead
80
- let readWhileKnown dat = ifM G. isEmpty (return dat) $ do
81
+ let cond = orM [ G. isEmpty
82
+ , (\ r -> r - read1 >= totalLen) <$> G. bytesRead ]
83
+ readWhileKnown dat = ifM cond (return dat) $ do
81
84
key <- G. lookAhead getWord8
82
85
case keyGetMapper key dat of
83
86
Nothing -> return dat
84
87
Just gh -> getWord8 >> gh >>= readWhileKnown
85
88
attrData <- readWhileKnown initData
86
89
read <- flip (-) read1 <$> G. bytesRead
87
- when (read > fromIntegral totalLen) $
90
+ when (read > totalLen) $
88
91
fail $ " Attributes: wrong total length field value, deserialized "
89
92
++ show read ++ " bytes, totalLen=" ++ show totalLen
90
- attrRemain <- getByteString $ fromIntegral totalLen - fromIntegral read
93
+ attrRemain <- getByteString $ fromIntegral $ totalLen - read
91
94
return $ Attributes {.. }
92
95
93
96
-- | Generate 'Put' given the way to serialize inner attribute value
94
97
-- into set of keys and values.
95
98
putAttributes :: (h -> [(Word8 , ByteString )]) -> Attributes h -> Put
96
99
putAttributes putMapper Attributes {.. } = do
100
+ -- CSL-594 TODO use varint
97
101
putWord32be totalLen
98
102
mapM_ putAttr kvs
99
103
putByteString attrRemain
0 commit comments