Skip to content

Commit 76de7ce

Browse files
Add CWE library
This change adds a new library to parse CWE names.
1 parent e443352 commit 76de7ce

File tree

6 files changed

+648
-3
lines changed

6 files changed

+648
-3
lines changed

code/cwe/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## 0.1
4+
5+
- Initial version

code/cwe/RenderCsvData.hs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env cabal
2+
{- cabal:
3+
build-depends: base, csv
4+
-}
5+
-- | Use this script to update the CWE.Raw module:
6+
-- Go to https://cwe.mitre.org/data/downloads.html
7+
-- Download and extract the 'Software Development' and 'CWE Simplified Mapping' CSV.zip files
8+
-- Run the following command: ./RenderCsvData.hs | fourmolu --stdin-input-file ./src/CWE/Raw.hs > src/CWE/Raw.hs
9+
module Main where
10+
11+
import Data.List
12+
import Data.Maybe
13+
import Text.CSV
14+
import Text.Read
15+
16+
main :: IO ()
17+
main = do
18+
dbs <- traverse readCSV ["699.csv", "1003.csv"]
19+
putStrLn $ unlines $ renderSource $ concat dbs
20+
21+
readCSV :: FilePath -> IO CSV
22+
readCSV fp = do
23+
txt <- readFile fp
24+
case Text.CSV.parseCSV "stdin" txt of
25+
Left e -> error ("bad csv: " <> show e)
26+
Right records -> pure (drop 1 records)
27+
28+
renderSource :: [Record] -> [String]
29+
renderSource xs =
30+
[ "{-# LANGUAGE OverloadedStrings #-}"
31+
, "module CWE.Data where"
32+
, "import Data.Text"
33+
, "cweData :: [(Word, Text)]"
34+
, "cweData = ["
35+
]
36+
<> map renderEntry (zip [0 ..] (sortOn byNum xs))
37+
<> [" ]"]
38+
where
39+
byNum (num : _) = fromMaybe (42 :: Int) (readMaybe num)
40+
renderEntry (pos, (num : desc : _)) = " " <> sep <> " (" <> num <> ", \"" <> name <> "\")"
41+
where
42+
sep = if pos == 0 then " " else ","
43+
-- Remove extra info in parenthesis
44+
name = dropWhileEnd (== ' ') $ takeWhile (/= '(') desc
45+
renderEntry _ = ""

code/cwe/cwe.cabal

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
cabal-version: 2.4
2+
name: cwe
3+
version: 0.1
4+
synopsis: Common Weakness Enumaration database
5+
description: Use this library to lookup or validate CWE numbers.
6+
license: BSD-3-Clause
7+
author: Tristan de Cacqueray
8+
maintainer: [email protected]
9+
category: Data
10+
extra-doc-files: CHANGELOG.md
11+
tested-with: GHC ==8.10.7 || ==9.0.2 || ==9.2.7 || ==9.4.5 || ==9.6.2
12+
13+
library
14+
exposed-modules: CWE
15+
other-modules: CWE.Data
16+
build-depends:
17+
, base >=4.14 && <5
18+
, containers >=0.6 && <0.7
19+
, parsec >=3 && <4
20+
, text >= 1.2 && < 3
21+
22+
23+
hs-source-dirs: src
24+
default-language: Haskell2010
25+
ghc-options:
26+
-Wall -Wcompat -Widentities -Wincomplete-record-updates
27+
-Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints

code/cwe/src/CWE.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{-# LANGUAGE ViewPatterns #-}
2+
{-# LANGUAGE DerivingStrategies #-}
3+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4+
{-# LANGUAGE OverloadedStrings #-}
5+
module CWE (CWEID, mkCWEID, cweNames, cweIds) where
6+
7+
import CWE.Data
8+
import Data.Text (Text)
9+
import Data.Coerce
10+
import Data.Map.Strict as Map
11+
import GHC.Bits
12+
13+
-- | A CWE identifier.
14+
newtype CWEID = CWEID Word
15+
deriving newtype (Eq, Ord, Show)
16+
17+
mkCWEID :: (Integral a, Bits a) => a -> Maybe CWEID
18+
mkCWEID num = CWEID <$> toIntegralSized num
19+
20+
-- | A map to lookup CWE names.
21+
cweNames :: Map CWEID Text
22+
cweNames = Map.fromList (coerce cweData)
23+
24+
-- | A map to lookup CWEID.
25+
cweIds :: Map Text CWEID
26+
cweIds = Map.fromList $ (\(k, v) -> (v, k)) <$> (coerce cweData)

0 commit comments

Comments
 (0)