@@ -24,6 +24,7 @@ import Control.Monad.Trans.Class (lift)
2424import Data.Array (snoc , foldRecM )
2525import Data.Array as Array
2626import Data.ArrayBuffer.Builder (DataBuff (..), PutM , subBuilder )
27+ import Data.ArrayBuffer.DataView (byteLength )
2728import Data.ArrayBuffer.Types (DataView , ByteLength )
2829import Data.Enum (class BoundedEnum , fromEnum , toEnum )
2930import Data.Foldable (foldl )
@@ -39,7 +40,8 @@ import Data.UInt64 (UInt64)
3940import Data.UInt64 as UInt64
4041import Effect.Class (class MonadEffect )
4142import Parsing (ParserT , Position (..), fail , position )
42- import Parsing.DataView (takeN )
43+ import Parsing.Combinators (lookAhead )
44+ import Parsing.DataView (takeN , takeRest )
4345import Protobuf.Internal.Common (Bytes (..), FieldNumber , WireType (..), label )
4446import Protobuf.Internal.Decode as Decode
4547import Protobuf.Internal.Encode as Encode
@@ -76,6 +78,7 @@ type FieldNumberInt
7678 = Int
7779
7880-- | Call a parser repeatedly until exactly *N* bytes have been consumed.
81+ -- | Will fail if not enough bytes remain in the DataView.
7982-- | Will fail if too many bytes are consumed.
8083manyLength ::
8184 forall m a .
@@ -86,18 +89,22 @@ manyLength ::
8689 ParserT DataView m (Array a )
8790manyLength p len = do
8891 Position { index: posBegin } <- position
89- let
90- go :: List a -> ParserT DataView m (Step (List a ) (List a ))
91- go accum = do
92- Position { index: pos } <- position
93- case compare (pos - posBegin) len of
94- GT -> fail " manyLength consumed too many bytes."
95- EQ -> lift $ pure (Done accum)
96- LT -> do
97- x <- p
98- pure (Loop (x : accum))
99- -- https://github.com/purescript-contrib/purescript-parsing/pull/199#issuecomment-1145956271
100- Array .reverse <$> Array .fromFoldable <$> tailRecM go List.Nil
92+ remaining_bytes :: Int <- byteLength <$> lookAhead takeRest
93+ if remaining_bytes < len
94+ then fail $ " manyLength " <> show len <> " not enough bytes of input " <> show remaining_bytes <> " remaining."
95+ else do
96+ let
97+ go :: List a -> ParserT DataView m (Step (List a ) (List a ))
98+ go accum = do
99+ Position { index: pos } <- position
100+ case compare (pos - posBegin) len of
101+ GT -> fail " manyLength consumed too many bytes."
102+ EQ -> lift $ pure (Done accum)
103+ LT -> do
104+ x <- p
105+ pure (Loop (x : accum))
106+ -- https://github.com/purescript-contrib/purescript-parsing/pull/199#issuecomment-1145956271
107+ Array .reverse <$> Array .fromFoldable <$> tailRecM go List.Nil
101108
102109-- | A message field value from an unknown `.proto` definition.
103110-- |
0 commit comments