git.iko.soy/rowtype-yoga/purescript-parsing-dataview
on master help sign in
anyCodePointUTF8 exclude invalid UTF-8 encodings
commit2a1de94d827b7c37808d15533f0896c5a29db6a3 authorJames Brock <jamesbrock@gmail.com> dateSun 4 Dec 2022, 22:07 (4 years ago) parent7cfe20f
2 files changed+27−3
src/Parsing/DataView.Basic.purs+5−1 test/Main.purs+22−2
src/Parsing/DataView.Basic.purs+5−1
@@ -29,19 +29,23 @@ anyCodePointUTF8 = tryRethrow do
2929 c0 <- toInt <$> anyUint8
3030 if c0 < 128 then do
3131 liftMaybe (\_ -> "Invalid CodePoint " <> show c0) (toEnum c0)
32+ else if c0 < 192 then fail "Invalid UTF-8 encoding"
3233 else if c0 < 224 then do
3334 c1 <- toInt <$> anyUint8
35+ if c1 < 128 || c1 > 191 then fail "Invalid UTF-8 encoding" else pure unit
3436 let codepoint = (64 * (c0 `mod` 32)) + (c1 `mod` 64)
3537 liftMaybe (\_ -> "Invalid CodePoint " <> show codepoint) (toEnum codepoint)
3638 else if c0 < 240 then do
3739 c1 <- toInt <$> anyUint8
3840 c2 <- toInt <$> anyUint8
41+ if c1 < 128 || c1 > 191 || c2 < 128 || c2 > 191 then fail "Invalid UTF-8 encoding" else pure unit
3942 let codepoint = (4096 * (c0 `mod` 16)) + (64 * (c1 `mod` 64)) + (c2 `mod` 64)
4043 liftMaybe (\_ -> "Invalid CodePoint " <> show codepoint) (toEnum codepoint)
4144 else if c0 < 248 then do
4245 c1 <- toInt <$> anyUint8
4346 c2 <- toInt <$> anyUint8
4447 c3 <- toInt <$> anyUint8
48+ if c1 < 128 || c1 > 191 || c2 < 128 || c2 > 191 || c3 < 128 || c3 > 191 then fail "Invalid UTF-8 encoding" else pure unit
4549 let codepoint = (262144 * (c0 `mod` 8)) + (4096 * (c1 `mod` 64)) + (64 * (c2 `mod` 64)) + (c3 `mod` 64)
4650 liftMaybe (\_ -> "Invalid CodePoint " <> show codepoint) (toEnum codepoint)
47− else fail "Invalid first code point"
51+ else fail "Invalid UTF-8 encoding"
test/Main.purs+22−2
@@ -7,6 +7,8 @@ import Control.Monad.Trans.Class (lift)
77import Data.ArrayBuffer.ArrayBuffer as AB
88import Data.ArrayBuffer.Cast (fromUint8Array, toUint8Array)
99import Data.ArrayBuffer.DataView as DataView
10+import Data.ArrayBuffer.Typed (fromArray)
11+import Data.ArrayBuffer.Types (Uint8Array)
1012import Data.Either (Either(..))
1113import Data.Enum (fromEnum)
1214import Data.List (fromFoldable)
@@ -19,7 +21,7 @@ import Effect (Effect)
1921import Effect.Class (liftEffect)
2022import Effect.Console (logShow)
2123import Effect.Exception (catchException, message)
22−import Parsing (ParserT, Position(..), fail, liftExceptT, parseErrorPosition, runParserT)
24+import Parsing (ParseError(..), ParserT, Position(..), fail, liftExceptT, parseErrorPosition, runParserT)
2325import Parsing.Combinators (many, manyTill)
2426import Parsing.DataView (anyInt8, anyTill, eof, satisfyInt8)
2527import Parsing.DataView as DV
@@ -205,7 +207,25 @@ main = do
205207 eof
206208 pure [ c0, c1, c2, c3, c4 ]
207209
208− assertEqual' "anyCodePointUTF8"
210+ assertEqual' "anyCodePointUTF8 basic"
209211 { expected: Right [ 97, 955, 0x6708, 0x1F453, 97 ]
210212 , actual: result
211213 }
214+
215+ do
216+ test :: Uint8Array <- fromArray (map fromInt [ 0x00BF ])
217+ testv <- fromUint8Array test
218+ result <- runParserT testv anyCodePointUTF8
219+ assertEqual' "anyCodePointUTF8 invalid 1"
220+ { expected: Left (ParseError "Invalid UTF-8 encoding" (Position { index: 0, column: 1, line: 1 }))
221+ , actual: result
222+ }
223+
224+ do
225+ test :: Uint8Array <- fromArray (map fromInt [ 0x00C0, 0 ])
226+ testv <- fromUint8Array test
227+ result <- runParserT testv anyCodePointUTF8
228+ assertEqual' "anyCodePointUTF8 invalid 2"
229+ { expected: Left (ParseError "Invalid UTF-8 encoding" (Position { index: 0, column: 1, line: 1 }))
230+ , actual: result
231+ }