@@ -403,12 +403,15 @@ chunkedSource ipair = do
403 (src, mlen) <- liftIO $ I.readIORef ipair
403 (src, mlen) <- liftIO $ I.readIORef ipair
404 go src mlen
404 go src mlen
407+ (src', (len, bs)) <- lift $ src C.$$+ front getLen
410+ | otherwise = C.yield bs >> src'
411+ go src'' $ HaveLen len
406− go src NeedLen = do
413+ go src NeedLen = go' src id
407− (src', len) <- lift $ src C.$$+ getLen
408− go src' $ HaveLen len
409− go src NeedLenNewline = do
414+ go src NeedLenNewline = go' src (CB.take 2 >>)
410− (src', len) <- lift $ src C.$$+ (CB.take 2 >> getLen)
411− go src' $ HaveLen len
412 go src (HaveLen 0) = liftIO $ I.writeIORef ipair (src, HaveLen 0)
415 go src (HaveLen 0) = liftIO $ I.writeIORef ipair (src, HaveLen 0)
413 go src (HaveLen len) = do
416 go src (HaveLen len) = do
414 (src', mbs) <- lift $ src C.$$+ CL.head
417 (src', mbs) <- lift $ src C.$$+ CL.head
@@ -430,14 +433,25 @@ chunkedSource ipair = do
430 C.yield bs
433 C.yield bs
431 go src mlen
434 go src mlen
433− getLen :: MonadIO m => C.Sink ByteString m Word
436+ getLen :: Monad m => C.Sink ByteString m (Word, ByteString)
434 getLen = do
437 getLen = do
435− bss <- CB.takeWhile (/= 10) C.=$ CL.consume -- FIXME avoid attack
438+ mbs <- CL.head
436− _ <- CB.take 1
439+ case mbs of
437− return $
440+ Nothing -> return (0, S.empty)
443+ case S.breakByte 10 bs of
448+ Nothing -> return (x, y)
449+ Just bs2 -> return $ S.breakByte 10 $ bs `S.append` bs2
450+ | otherwise -> return (x, y)
438− S.foldl' (\i c -> i * 16 + fromIntegral (hexToWord c)) 0
452+ S.foldl' (\i c -> i * 16 + fromIntegral (hexToWord c)) 0
439− $ B.takeWhile isHexDigit
453+ $ B.takeWhile isHexDigit x
440− $ B.concat bss
454+ return (w, S.drop 1 y)
442 hexToWord w
456 hexToWord w
443 | w < 58 = w - 48
457 | w < 58 = w - 48