better error handling in ASN.1 message parser
This commit is contained in:
parent
6dc9650da5
commit
28254a9f83
|
@ -284,12 +284,17 @@ encodeMessage
|
|||
|
||||
parseMessage :: ParseASN1 FediChordMessage
|
||||
parseMessage = do
|
||||
begin <- getNext
|
||||
case begin of
|
||||
Start Sequence -> return ()
|
||||
x -> throwParseError $ "unexpected ASN.1 element " ++ show x
|
||||
-- request and response messages are distiguishable by their structure,
|
||||
-- see ASN.1 schema
|
||||
first <- getNext
|
||||
case first of
|
||||
Enumerated a -> parseRequest . toEnum . fromIntegral $ a
|
||||
IntVal i -> parseResponse i
|
||||
other -> throwParseError $ "unexpected first ASN1 element: " ++ show other
|
||||
|
||||
parseRequest :: Action -> ParseASN1 FediChordMessage
|
||||
parseRequest action = do
|
||||
|
@ -304,6 +309,11 @@ parseRequest action = do
|
|||
Leave -> parseLeaveRequest
|
||||
Stabilise -> parseStabiliseRequest
|
||||
Ping -> parsePingRequest
|
||||
-- consume sequence end
|
||||
end <- getNext
|
||||
case end of
|
||||
End Sequence -> return ()
|
||||
x -> throwParseError $ "unexpected ASN.1 element " ++ show x
|
||||
|
||||
return $ Request requestID sender parts part action payload
|
||||
|
||||
|
@ -320,35 +330,48 @@ parseResponse responseTo = do
|
|||
Leave -> parseLeaveResponse
|
||||
Stabilise -> parseStabiliseResponse
|
||||
Ping -> parsePingResponse
|
||||
-- consume sequence end
|
||||
end <- getNext
|
||||
case end of
|
||||
End Sequence -> return ()
|
||||
x -> throwParseError $ "unexpected ASN.1 element " ++ show x
|
||||
|
||||
return $ Response responseTo senderID parts part action payload
|
||||
|
||||
parseInteger :: ParseASN1 Integer
|
||||
parseInteger = do
|
||||
IntVal parsed <- getNext
|
||||
return parsed
|
||||
i <- getNext
|
||||
case i of
|
||||
IntVal parsed -> return parsed
|
||||
x -> throwParseError $ "Expected IntVal but got " ++ show x
|
||||
|
||||
parseEnum :: Enum a => ParseASN1 a
|
||||
parseEnum = do
|
||||
Enumerated en <- getNext
|
||||
return $ toEnum . fromIntegral $ en
|
||||
e <- getNext
|
||||
case e of
|
||||
Enumerated en -> return $ toEnum . fromIntegral $ en
|
||||
x -> throwParseError $ "Expected Enumerated but got " ++ show x
|
||||
|
||||
parseString :: ParseASN1 String
|
||||
parseString = do
|
||||
ASN1String toBeParsed <- getNext
|
||||
maybe (throwParseError "string parsing failed") return $ asn1CharacterToString toBeParsed
|
||||
s <- getNext
|
||||
case s of
|
||||
ASN1String toBeParsed -> maybe (throwParseError "string parsing failed") return $ asn1CharacterToString toBeParsed
|
||||
x -> throwParseError $ "Expected a ASN1String but got " ++ show x
|
||||
|
||||
parseOctets :: ParseASN1 BS.ByteString
|
||||
parseOctets = do
|
||||
OctetString bs <- getNext
|
||||
return bs
|
||||
os <- getNext
|
||||
case os of
|
||||
OctetString bs -> return bs
|
||||
x -> throwParseError $ "Expected an OctetString but got " ++ show x
|
||||
|
||||
parseNull :: ParseASN1 ()
|
||||
parseNull = do
|
||||
-- ToDo: figure out how this fails on wrong inputs,
|
||||
-- maybe a case distinction + throwParseError is better?
|
||||
Null <- getNext
|
||||
return ()
|
||||
n <- getNext
|
||||
case n of
|
||||
Null -> return ()
|
||||
x -> throwParseError $ "Expected Null but got " ++ show x
|
||||
|
||||
parseNodeState :: ParseASN1 NodeState
|
||||
parseNodeState = do
|
||||
|
|
Loading…
Reference in a new issue