2
2
{-# LANGUAGE OverloadedStrings #-}
3
3
4
4
module Security.Advisories.Queries
5
- ( listVersionRangeAffectedBy
5
+ ( listVersionAffectedBy
6
+ , listVersionRangeAffectedBy
7
+ , isVersionAffectedBy
6
8
, isVersionRangeAffectedBy
7
9
, parseVersionRange
8
10
)
@@ -17,47 +19,66 @@ import Data.Text (Text)
17
19
import qualified Data.Text as T
18
20
import qualified Data.Text.IO as T
19
21
import Distribution.Parsec (eitherParsec )
22
+ import Distribution.Types.Version (Version )
20
23
import Distribution.Types.VersionInterval (asVersionIntervals )
21
- import Distribution.Types.VersionRange (VersionRange , anyVersion , earlierVersion , intersectVersionRanges , noVersion , orLaterVersion , unionVersionRanges )
24
+ import Distribution.Types.VersionRange (VersionRange , anyVersion , earlierVersion , intersectVersionRanges , noVersion , orLaterVersion , unionVersionRanges , withinRange )
22
25
import Validation (Validation (.. ))
23
26
24
27
import Security.Advisories.Definition
25
28
import Security.Advisories.Filesystem
26
29
30
+ -- | Check whether a package and a version is concerned by an advisory
31
+ isVersionAffectedBy :: Text -> Version -> Advisory -> Bool
32
+ isVersionAffectedBy = isAffectedByHelper withinRange
33
+
27
34
-- | Check whether a package and a version range is concerned by an advisory
28
35
isVersionRangeAffectedBy :: Text -> VersionRange -> Advisory -> Bool
29
- isVersionRangeAffectedBy queryPackageName queryVersionRange =
36
+ isVersionRangeAffectedBy = isAffectedByHelper $
37
+ \ queryVersionRange affectedVersionRange ->
38
+ isSomeVersion (affectedVersionRange `intersectVersionRanges` queryVersionRange)
39
+ where
40
+ isSomeVersion :: VersionRange -> Bool
41
+ isSomeVersion range
42
+ | [] <- asVersionIntervals range = False
43
+ | otherwise = True
44
+
45
+ -- | Helper function for 'isVersionAffectedBy' and 'isVersionRangeAffectedBy'
46
+ isAffectedByHelper :: (a -> VersionRange -> Bool ) -> Text -> a -> Advisory -> Bool
47
+ isAffectedByHelper checkWithRange queryPackageName queryVersionish =
30
48
any checkAffected . advisoryAffected
31
49
where
32
- checkAffected :: Affected -> Bool
33
- checkAffected affected =
34
- queryPackageName == affectedPackage affected
35
- && isSomeVersion (fromAffected affected `intersectVersionRanges` queryVersionRange )
50
+ checkAffected :: Affected -> Bool
51
+ checkAffected affected =
52
+ queryPackageName == affectedPackage affected
53
+ && checkWithRange queryVersionish (fromAffected affected)
36
54
37
- fromAffected :: Affected -> VersionRange
38
- fromAffected = foldr (unionVersionRanges . fromAffectedVersionRange) noVersion . affectedVersions
55
+ fromAffected :: Affected -> VersionRange
56
+ fromAffected = foldr (unionVersionRanges . fromAffectedVersionRange) noVersion . affectedVersions
39
57
40
- fromAffectedVersionRange :: AffectedVersionRange -> VersionRange
41
- fromAffectedVersionRange avr = intersectVersionRanges
42
- (orLaterVersion (affectedVersionRangeIntroduced avr))
43
- (maybe anyVersion earlierVersion (affectedVersionRangeFixed avr))
58
+ fromAffectedVersionRange :: AffectedVersionRange -> VersionRange
59
+ fromAffectedVersionRange avr = intersectVersionRanges
60
+ (orLaterVersion (affectedVersionRangeIntroduced avr))
61
+ (maybe anyVersion earlierVersion (affectedVersionRangeFixed avr))
44
62
45
- isSomeVersion :: VersionRange -> Bool
46
- isSomeVersion range
47
- | [] <- asVersionIntervals range = False
48
- | otherwise = True
63
+ -- | List the advisories matching a package name and a version
64
+ listVersionAffectedBy :: FilePath -> Text -> Version -> IO [Advisory ]
65
+ listVersionAffectedBy = listAffectedByHelper isVersionAffectedBy
49
66
50
- -- | List the advisories matching package/ version range
67
+ -- | List the advisories matching a package name and a version range
51
68
listVersionRangeAffectedBy :: FilePath -> Text -> VersionRange -> IO [Advisory ]
52
- listVersionRangeAffectedBy root queryPackageName queryVersionRange =
53
- listAdvisories root >>= \ case
54
- Failure errors -> do
55
- T. hPutStrLn stderr " Cannot parse some advisories"
56
- forM_ errors $
57
- hPrint stderr
58
- exitFailure
59
- Success advisories ->
60
- return $ filter (isVersionRangeAffectedBy queryPackageName queryVersionRange) advisories
69
+ listVersionRangeAffectedBy = listAffectedByHelper isVersionRangeAffectedBy
70
+
71
+ -- | Helper function for 'listVersionAffectedBy' and 'listVersionRangeAffectedBy'
72
+ listAffectedByHelper :: (Text -> a -> Advisory -> Bool ) -> FilePath -> Text -> a -> IO [Advisory ]
73
+ listAffectedByHelper checkAffectedBy root queryPackageName queryVersionish =
74
+ listAdvisories root >>= \ case
75
+ Failure errors -> do
76
+ T. hPutStrLn stderr " Cannot parse some advisories"
77
+ forM_ errors $
78
+ hPrint stderr
79
+ exitFailure
80
+ Success advisories ->
81
+ return $ filter (checkAffectedBy queryPackageName queryVersionish) advisories
61
82
62
83
-- | Parse 'VersionRange' as given to the CLI
63
84
parseVersionRange :: Maybe Text -> Either Text VersionRange
0 commit comments