@@ -36,20 +36,17 @@ import qualified Commonmark.Parser as Commonmark
3636import Commonmark.Types (HasAttributes (.. ), IsBlock (.. ), IsInline (.. ), Rangeable (.. ), SourceRange (.. ))
3737import Commonmark.Pandoc (Cm (unCm ))
3838import qualified Toml
39- import qualified Toml.Pretty as Toml
40- import qualified Toml.FromValue as Toml
41- import qualified Toml.FromValue.Matcher as Toml
42- import qualified Toml.ToValue as Toml
39+ import qualified Toml.Syntax as Toml (startPos )
40+ import qualified Toml.Schema as Toml
4341import Text.Pandoc.Builder (Blocks , Many (.. ))
4442import Text.Pandoc.Definition (Block (.. ), Inline (.. ), Pandoc (.. ))
4543import Text.Pandoc.Walk (query )
4644import Text.Parsec.Pos (sourceLine )
4745
4846import Security.Advisories.Core.HsecId
4947import Security.Advisories.Core.Advisory
50- import Security.OSV (Reference (.. ), referenceTypes )
48+ import Security.OSV (Reference (.. ), ReferenceType , referenceTypes )
5149import qualified Security.CVSS as CVSS
52-
5350-- | A source of attributes supplied out of band from the advisory
5451-- content. Values provided out of band are treated according to
5552-- the 'AttributeOverridePolicy'.
@@ -80,7 +77,7 @@ data ParseAdvisoryError
8077 = MarkdownError Commonmark. ParseError T. Text
8178 | MarkdownFormatError T. Text
8279 | TomlError String T. Text
83- | AdvisoryError [Toml. MatchMessage ] T. Text
80+ | AdvisoryError [Toml. MatchMessage Toml. Position ] T. Text
8481 deriving stock (Eq , Show , Generic )
8582
8683-- | The main parsing function. 'OutOfBandAttributes' are handled
@@ -99,7 +96,7 @@ parseAdvisory policy attrs raw = do
9996 (frontMatter, rest) <- first MarkdownFormatError $ advisoryDoc markdown
10097 let doc = Pandoc mempty rest
10198 ! summary <- first MarkdownFormatError $ parseAdvisorySummary doc
102- table <- case Toml. parse ( T. unpack frontMatter) of
99+ table <- case Toml. parse frontMatter of
103100 Left e -> Left (TomlError e (T. pack e))
104101 Right t -> Right t
105102
@@ -129,10 +126,8 @@ parseAdvisory policy attrs raw = do
129126 (Commonmark. commonmark " input" raw :: Either Commonmark. ParseError (Html () ))
130127
131128 case parseAdvisoryTable attrs policy doc summary details html table of
132- Toml. Failure es -> Left (AdvisoryError es (T. pack (unlines (map Toml. prettyMatchMessage es))))
133- Toml. Success warnings adv
134- | null warnings -> pure adv
135- | otherwise -> Left (AdvisoryError warnings (T. pack (unlines (map Toml. prettyMatchMessage warnings)))) -- treat warnings as errors
129+ Left es -> Left (AdvisoryError es (T. pack (unlines (map Toml. prettyMatchMessage es))))
130+ Right adv -> pure adv
136131
137132 where
138133 firstPretty
@@ -156,11 +151,11 @@ parseAdvisoryTable
156151 -> T. Text -- ^ summary
157152 -> T. Text -- ^ details
158153 -> T. Text -- ^ rendered HTML
159- -> Toml. Table
160- -> Toml. Result Toml. MatchMessage Advisory
154+ -> Toml. Table' Toml. Position
155+ -> Either [ Toml. MatchMessage Toml. Position ] Advisory
161156parseAdvisoryTable oob policy doc summary details html tab =
162- Toml. runMatcher $
163- do fm <- Toml. fromValue (Toml. Table tab)
157+ Toml. runMatcherFatalWarn $
158+ do fm <- Toml. fromValue (Toml. Table' Toml. startPos tab)
164159 published <-
165160 mergeOobMandatory policy
166161 (oobPublished oob)
@@ -211,7 +206,7 @@ instance Toml.ToValue FrontMatter where
211206 toValue = Toml. defaultTableToValue
212207
213208instance Toml. ToTable FrontMatter where
214- toTable x = Map. fromList
209+ toTable x = Toml. table
215210 [ " advisory" Toml. .= frontMatterAdvisory x
216211 , " affected" Toml. .= frontMatterAffected x
217212 , " references" Toml. .= frontMatterReferences x
@@ -253,7 +248,7 @@ instance Toml.ToValue AdvisoryMetadata where
253248 toValue = Toml. defaultTableToValue
254249
255250instance Toml. ToTable AdvisoryMetadata where
256- toTable x = Map. fromList $
251+ toTable x = Toml. table $
257252 [" id" Toml. .= amdId x] ++
258253 [" modified" Toml. .= y | Just y <- [amdModified x]] ++
259254 [" date" Toml. .= y | Just y <- [amdPublished x]] ++
@@ -283,7 +278,7 @@ instance Toml.ToValue Affected where
283278 toValue = Toml. defaultTableToValue
284279
285280instance Toml. ToTable Affected where
286- toTable x = Map. fromList $
281+ toTable x = Toml. table $
287282 [ " package" Toml. .= affectedPackage x
288283 , " cvss" Toml. .= affectedCVSS x
289284 , " versions" Toml. .= affectedVersions x
@@ -307,7 +302,7 @@ instance Toml.ToValue AffectedVersionRange where
307302 toValue = Toml. defaultTableToValue
308303
309304instance Toml. ToTable AffectedVersionRange where
310- toTable x = Map. fromList $
305+ toTable x = Toml. table $
311306 (" introduced" Toml. .= affectedVersionRangeIntroduced x) :
312307 [" fixed" Toml. .= y | Just y <- [affectedVersionRangeFixed x]]
313308
@@ -316,7 +311,7 @@ instance Toml.FromValue HsecId where
316311 fromValue v =
317312 do s <- Toml. fromValue v
318313 case parseHsecId s of
319- Nothing -> fail " invalid HSEC-ID: expected HSEC-[0-9]{4,}-[0-9]{4,}"
314+ Nothing -> Toml. failAt ( Toml. valueAnn v) " invalid HSEC-ID: expected HSEC-[0-9]{4,}-[0-9]{4,}"
320315 Just x -> pure x
321316
322317instance Toml. ToValue HsecId where
@@ -335,11 +330,11 @@ instance Toml.ToValue Keyword where
335330 toValue (Keyword x) = Toml. toValue x
336331
337332-- | Get a datetime with the timezone defaulted to UTC and the time defaulted to midnight
338- getDefaultedZonedTime :: Toml. Value -> Toml. Matcher ZonedTime
339- getDefaultedZonedTime (Toml. ZonedTime x) = pure x
340- getDefaultedZonedTime (Toml. LocalTime x) = pure (ZonedTime x utc)
341- getDefaultedZonedTime (Toml. Day x) = pure (ZonedTime (LocalTime x midnight) utc)
342- getDefaultedZonedTime _ = fail " expected a date with optional time and timezone"
333+ getDefaultedZonedTime :: Toml. Value' l -> Toml. Matcher l ZonedTime
334+ getDefaultedZonedTime (Toml. ZonedTime' _ x) = pure x
335+ getDefaultedZonedTime (Toml. LocalTime' _ x) = pure (ZonedTime x utc)
336+ getDefaultedZonedTime (Toml. Day' _ x) = pure (ZonedTime (LocalTime x midnight) utc)
337+ getDefaultedZonedTime v = Toml. failAt ( Toml. valueAnn v) " expected a date with optional time and timezone"
343338
344339advisoryDoc :: Blocks -> Either T. Text (T. Text , [Block ])
345340advisoryDoc (Many blocks) = case blocks of
@@ -375,21 +370,22 @@ inlineText = query f
375370
376371instance Toml. FromValue Reference where
377372 fromValue = Toml. parseTableFromValue $
378- do refTypeStr <- Toml. reqKey " type"
379- refType <- case lookup refTypeStr (fmap swap referenceTypes) of
380- Just a -> pure a
381- Nothing ->
382- fail $
383- " Invalid format for reference.type: " ++ T. unpack refTypeStr ++
384- " should be one of: " ++ intercalate " , " (T. unpack . snd <$> referenceTypes)
385- url <- Toml. reqKey " url"
386- pure $ Reference refType url
373+ do refType <- Toml. reqKey " type"
374+ url <- Toml. reqKey " url"
375+ pure (Reference refType url)
376+
377+ instance Toml. FromValue ReferenceType where
378+ fromValue (Toml. Text' _ refTypeStr)
379+ | Just a <- lookup refTypeStr (fmap swap referenceTypes) = pure a
380+ fromValue v =
381+ Toml. failAt (Toml. valueAnn v) $
382+ " reference.type should be one of: " ++ intercalate " , " (T. unpack . snd <$> referenceTypes)
387383
388384instance Toml. ToValue Reference where
389385 toValue = Toml. defaultTableToValue
390386
391387instance Toml. ToTable Reference where
392- toTable x = Map. fromList
388+ toTable x = Toml. table
393389 [ " type" Toml. .= fromMaybe " UNKNOWN" (lookup (referencesType x) referenceTypes)
394390 , " url" Toml. .= referencesUrl x
395391 ]
@@ -405,7 +401,7 @@ instance Toml.FromValue OS where
405401 " mingw32" -> pure Windows
406402 " netbsd" -> pure NetBSD
407403 " openbsd" -> pure OpenBSD
408- other -> fail (" Invalid OS: " ++ show other)
404+ other -> Toml. failAt ( Toml. valueAnn v) (" Invalid OS: " ++ show other)
409405
410406instance Toml. ToValue OS where
411407 toValue x =
@@ -448,7 +444,7 @@ instance Toml.FromValue Architecture where
448444 " sparc64" -> pure SPARC64
449445 " vax" -> pure VAX
450446 " x86_64" -> pure X86_64
451- other -> fail (" Invalid architecture: " ++ show other)
447+ other -> Toml. failAt ( Toml. valueAnn v) (" Invalid architecture: " ++ show other)
452448
453449instance Toml. ToValue Architecture where
454450 toValue x =
@@ -484,7 +480,7 @@ instance Toml.FromValue Version where
484480 fromValue v =
485481 do s <- Toml. fromValue v
486482 case eitherParsec s of
487- Left err -> fail (" parse error in version range: " ++ err)
483+ Left err -> Toml. failAt ( Toml. valueAnn v) (" parse error in version range: " ++ err)
488484 Right affected -> pure affected
489485
490486instance Toml. ToValue Version where
@@ -494,7 +490,7 @@ instance Toml.FromValue VersionRange where
494490 fromValue v =
495491 do s <- Toml. fromValue v
496492 case eitherParsec s of
497- Left err -> fail (" parse error in version range: " ++ err)
493+ Left err -> Toml. failAt ( Toml. valueAnn v) (" parse error in version range: " ++ err)
498494 Right affected -> pure affected
499495
500496instance Toml. ToValue VersionRange where
@@ -504,7 +500,7 @@ instance Toml.FromValue CVSS.CVSS where
504500 fromValue v =
505501 do s <- Toml. fromValue v
506502 case CVSS. parseCVSS s of
507- Left err -> fail (" parse error in cvss: " ++ show err)
503+ Left err -> Toml. failAt ( Toml. valueAnn v) (" parse error in cvss: " ++ show err)
508504 Right cvss -> pure cvss
509505
510506instance Toml. ToValue CVSS. CVSS where
0 commit comments