Skip to content

Commit 6bc728e

Browse files
committed
fix: fix invalid generation of TimeOfDay
1 parent 9a30a49 commit 6bc728e

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

src/Text/Megaparsec/Time.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@ module Text.Megaparsec.Time
2323
) where
2424

2525
import Control.Applicative (optional, (<|>))
26-
import Control.Monad (replicateM, void)
26+
import Control.Monad (replicateM)
2727
import Control.Monad.Combinators (choice, some)
2828
import Data.Char (toLower)
2929
import Data.Functor (($>))
3030
import Data.Maybe (fromMaybe)
3131
import Data.Time (Day, DayOfWeek (..),
3232
NominalDiffTime, TimeOfDay (..),
33-
defaultTimeLocale, parseTimeM,
33+
defaultTimeLocale,
34+
makeTimeOfDayValid, parseTimeM,
3435
secondsToNominalDiffTime)
3536
import Text.Megaparsec (Parsec, takeRest, try)
3637
import Text.Megaparsec.Char (char, digitChar, space, space1,
3738
string')
3839
import Text.Megaparsec.Utils (posNumParser)
40+
import Text.Printf (printf)
3941

4042
-- | Representation of a parser result with either a number of days relative to
4143
-- the current day, or a 'DayOfWeek'.
@@ -125,7 +127,10 @@ timeParser = do
125127
h <- read <$> replicateM 2 digitChar <* char ':'
126128
m <- read <$> replicateM 2 digitChar
127129

128-
return $ TimeOfDay h m 0
130+
maybe
131+
(fail (printf "invalid hours or minutes %02d:%02d" h m))
132+
pure
133+
(makeTimeOfDayValid h m 0)
129134

130135
-- | Zero seconds in 'NominalDiffTime'.
131136
zero :: NominalDiffTime

test/Text/Megaparsec/TimeSpec.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ spec = do
171171
Right d
172172

173173
describe "time" $ do
174+
it "invalid hours" . forAll (arbitrary `suchThat` (\h -> h > 23 && h < 100)) $ \h ->
175+
parseOrPrettyError timeParser (printf "%02d:00" (h :: Int)) `shouldSatisfy` isLeft
176+
177+
it "invalid hours" . forAll (arbitrary `suchThat` (\m -> m > 59 && m < 100)) $ \m ->
178+
parseOrPrettyError timeParser (printf "00:%02d" (m :: Int)) `shouldSatisfy` isLeft
179+
174180
it "valid" . property $ \t ->
175181
parseOrPrettyError timeParser (formatTime defaultTimeLocale "%R" t) `shouldBe`
176182
Right t

0 commit comments

Comments
 (0)