~fgaz/haskell-ucl

0261636bc83c0b0eaf7f145b22faa3d39a495d07 — Francesco Gazzetta 2 years ago e272d25
Fix failure on unicode characters in parseString

The string length was miscomputed
2 files changed, 6 insertions(+), 7 deletions(-)

M src/Data/UCL.hs
M test/ucl-test.hs
M src/Data/UCL.hs => src/Data/UCL.hs +4 -5
@@ 10,7 10,7 @@ module Data.UCL

import Foreign.C
  ( CUInt(..), CInt(..), CSize(..), CDouble(..), CString, CStringLen
  , newCString, peekCString )
  , newCString, newCStringLen, peekCString )
import Foreign.Ptr (Ptr)
import System.IO.Unsafe (unsafePerformIO)
import qualified Data.Text.Foreign as TF


@@ 19,6 19,7 @@ import qualified Data.Map as Map
import Data.Map (Map)
import Data.Time.Clock (DiffTime)
import Data.ByteString (ByteString, useAsCStringLen)
import Control.Monad ((>=>))


newtype ParserHandle = ParserHandle (Ptr ())


@@ 47,7 48,7 @@ pattern UCL_NULL = 8


foreign import ccall "ucl_parser_new" ucl_parser_new :: CInt -> IO ParserHandle
foreign import ccall "ucl_parser_add_string" ucl_parser_add_string :: ParserHandle -> CString -> CUInt -> IO Bool
foreign import ccall "ucl_parser_add_string" ucl_parser_add_string :: ParserHandle -> CString -> CSize -> IO Bool
foreign import ccall "ucl_parser_add_file" ucl_parser_add_file :: ParserHandle -> CString -> IO Bool
foreign import ccall "ucl_parser_get_object" ucl_parser_get_object :: ParserHandle -> IO UCLObjectHandle
foreign import ccall "ucl_parser_get_error" ucl_parser_get_error :: ParserHandle -> IO CString


@@ 97,9 98,7 @@ parseByteString bs = useAsCStringLen bs parseCStringLen
-- read files, make http requests, do "billion laughs" attacks, and possibly
-- crash the parser.
parseString :: String -> IO (Either String UCL)
parseString s = do
  cs <- newCString s
  parseCStringLen (cs, length s)
parseString = newCStringLen >=> parseCStringLen

parseCStringLen :: CStringLen -> IO (Either String UCL)
parseCStringLen (cs, len) = do

M test/ucl-test.hs => test/ucl-test.hs +2 -2
@@ 11,7 11,7 @@ main :: IO ()
main = do
  parsed1 <- parseString "0: 1min"
  print parsed1
  parsed <- parseString "\"a\": [12,34], 1:2, 1:3, 2:\"ab🌅c\", 3: yes, \"a\": [56]"
  parsed <- parseString "\"a\": [12,34], 1:2, 1:3, 2:\"ab🌅c\", 3: yes, \"a\": [56], \"b\": \"foo\""
  print parsed
  unless (parsed == Right (UCLMap (fromList [("1",UCLInt 2),("2",UCLText "ab\127749c"),("3",UCLBool True),("a",UCLArray [UCLInt 12,UCLInt 34])])))
  unless (parsed == Right (UCLMap (fromList [("1",UCLInt 2),("2",UCLText "ab\127749c"),("3",UCLBool True),("a",UCLArray [UCLInt 12,UCLInt 34, UCLInt 56]),("b",UCLText "foo")])))
     exitFailure