Skip to content

Commit

Permalink
lib/advisories: add "limit" field for version ranges
Browse files Browse the repository at this point in the history
Some scenarios require limiting the version range without a fix
version.  Add support for the "limit" specifier, which is mutually
exclusive witih "fix".
  • Loading branch information
frasertweedale committed Jun 27, 2023
1 parent 8b442c3 commit 75bb09a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
26 changes: 23 additions & 3 deletions code/hsec-tools/src/Security/Advisories/Definition.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module Security.Advisories.Definition
, CWE(..)
, Architecture(..)
, AffectedVersionRange(..)
, VersionRangeTerminal(..)
, OS(..)
, Keyword(..)
)
Expand Down Expand Up @@ -95,8 +96,27 @@ newtype Keyword = Keyword Text
deriving stock (Eq, Ord)
deriving (Show) via Text

data VersionRangeTerminal
= Limit Text -- ^ closes a range without a fix
| Fixed Text
deriving (Show, Eq)

-- | Specify a version range.
--
-- In most cases, a range is either open (no fix yet) or closed via
-- the 'Fixed' terminal. Scenarios that require 'Limit' include
-- those where a vulnerability has been introduced on multiple
-- branches. For example, if an issue was introduced in 1.0.8 and
-- 1.1.2 (but 1.1 is unaffected), and a fix has not been released
-- for the 1.0.x series, then you need:
--
-- @
-- [ 'AffectedVersionRange' "1.0.8" (Just ('Limit' "1.1"))
-- , 'AffectedVersionRange' "1.1.2" Nothing ]
-- @
--
data AffectedVersionRange = AffectedVersionRange
{ affectedVersionRangeIntroduced :: Text,
affectedVersionRangeFixed :: Maybe Text
{ affectedVersionRangeIntroduced :: Text
, affectedVersionRangeTerminal :: Maybe VersionRangeTerminal
}
deriving stock (Show)
deriving stock (Show, Eq)
10 changes: 9 additions & 1 deletion code/hsec-tools/src/Security/Advisories/Parse.hs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,14 @@ parseAffectedVersionRange v = do
tbl <- isTable v
introduced <- mandatory tbl "introduced" isString
fixed <- optional tbl "fixed" isString
pure $ AffectedVersionRange introduced fixed
limit <- optional tbl "limit" isString
terminal <- case (fixed, limit) of
(Just _, Just _) -> throwError $ MutuallyExclusiveKeys "fixed" "limit"
(Just ver, _) -> pure $ Just (Fixed ver)
(_, Just ver) -> pure $ Just (Limit ver)
(_, _) -> pure Nothing

pure $ AffectedVersionRange introduced terminal

advisoryDoc :: Blocks -> Either T.Text (T.Text, [Block])
advisoryDoc (Many blocks) = case blocks of
Expand Down Expand Up @@ -318,6 +325,7 @@ versionRange =
data TableParseError
= UnexpectedKeys (NonEmpty T.Text)
| MissingKey T.Text
| MutuallyExclusiveKeys T.Text T.Text
| IllegalOutOfBandOverride T.Text
| InvalidFormat T.Text T.Text T.Text
| InvalidOS T.Text
Expand Down

0 comments on commit 75bb09a

Please sign in to comment.