Skip to content

Commit 661e9a6

Browse files
mmhatblackheaven
authored andcommitted
Added isVersionAffectedBy, listVersionAffectedBy
1 parent b9e11cc commit 661e9a6

File tree

1 file changed

+48
-27
lines changed

1 file changed

+48
-27
lines changed

code/hsec-tools/src/Security/Advisories/Queries.hs

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
{-# LANGUAGE OverloadedStrings #-}
33

44
module Security.Advisories.Queries
5-
( listVersionRangeAffectedBy
5+
( listVersionAffectedBy
6+
, listVersionRangeAffectedBy
7+
, isVersionAffectedBy
68
, isVersionRangeAffectedBy
79
, parseVersionRange
810
)
@@ -17,47 +19,66 @@ import Data.Text (Text)
1719
import qualified Data.Text as T
1820
import qualified Data.Text.IO as T
1921
import Distribution.Parsec (eitherParsec)
22+
import Distribution.Types.Version (Version)
2023
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)
2225
import Validation (Validation(..))
2326

2427
import Security.Advisories.Definition
2528
import Security.Advisories.Filesystem
2629

30+
-- | Check whether a package and a version is concerned by an advisory
31+
isVersionAffectedBy :: Text -> Version -> Advisory -> Bool
32+
isVersionAffectedBy = isAffectedByHelper withinRange
33+
2734
-- | Check whether a package and a version range is concerned by an advisory
2835
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 =
3048
any checkAffected . advisoryAffected
3149
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)
3654

37-
fromAffected :: Affected -> VersionRange
38-
fromAffected = foldr (unionVersionRanges . fromAffectedVersionRange) noVersion . affectedVersions
55+
fromAffected :: Affected -> VersionRange
56+
fromAffected = foldr (unionVersionRanges . fromAffectedVersionRange) noVersion . affectedVersions
3957

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))
4462

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
4966

50-
-- | List the advisories matching package/version range
67+
-- | List the advisories matching a package name and a version range
5168
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
6182

6283
-- | Parse 'VersionRange' as given to the CLI
6384
parseVersionRange :: Maybe Text -> Either Text VersionRange

0 commit comments

Comments
 (0)