diff mbox series

[1/2] cve-json-to-text: add script

Message ID 20240823131034.1580972-1-marta.rybczynska@ygreky.com
State Accepted, archived
Commit da4e01dfa538578936e565413871a7496b8752df
Headers show
Series [1/2] cve-json-to-text: add script | expand

Commit Message

Marta Rybczynska Aug. 23, 2024, 1:10 p.m. UTC
Add a script that converts the cve-check result from the JSON format
to the TEXT format.

Signed-off-by: Marta Rybczynska <marta.rybczynska@ygreky.com>
---
 scripts/cve-json-to-text.py | 145 ++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100755 scripts/cve-json-to-text.py
diff mbox series

Patch

diff --git a/scripts/cve-json-to-text.py b/scripts/cve-json-to-text.py
new file mode 100755
index 0000000000..5531ee5eb6
--- /dev/null
+++ b/scripts/cve-json-to-text.py
@@ -0,0 +1,145 @@ 
+#!/bin/env python3
+# SPDX-FileCopyrightText: OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+
+# CVE results conversion script: JSON format to text
+# Derived from cve-report.py from Oniro (MIT, by Huawei Inc)
+
+import sys
+import getopt
+
+infile = "in.json"
+outfile = "out.txt"
+
+
+def show_syntax_and_exit(code):
+    """
+    Show the program syntax and exit with an errror
+    Arguments:
+        code: the error code to return
+    """
+    print("Syntax: %s [-h] [-i inputJSONfile][-o outputfile]" % sys.argv[0])
+    sys.exit(code)
+
+
+def exit_error(code, message):
+    """
+    Show the error message and exit with an errror
+    Arguments:
+        code: the error code to return
+        message: the message to show
+    """
+    print("Error: %s" % message)
+    sys.exit(code)
+
+
+def parse_args(argv):
+    """
+    Parse the program arguments, put options in global variables
+    Arguments:
+        argv: program arguments
+    """
+    global infile, outfile
+    try:
+        opts, args = getopt.getopt(
+            argv, "hi:o:", ["help", "input", "output"]
+        )
+    except getopt.GetoptError:
+        show_syntax_and_exit(1)
+    for opt, arg in opts:
+        if opt in ("-h", "--help"):
+            show_syntax_and_exit(0)
+        elif opt in ("-a", "--all"):
+            show_all = True
+            show_unknown = True
+        elif opt in ("-i", "--input"):
+            infile = arg
+
+def load_json(filename):
+    """
+    Load the JSON file, return the resulting dictionary
+    Arguments:
+        filename: the file to open
+    Returns:
+        Parsed file as a dictionary
+    """
+    import json
+
+    out = {}
+    try:
+        with open(filename, "r") as f:
+            out = json.load(f)
+    except FileNotFoundError:
+        exit_error(1, "Input file (%s) not found" % (filename))
+    except json.decoder.JSONDecodeError as error:
+        exit_error(1, "Malformed JSON file: %s" % str(error))
+    return out
+
+
+def process_data(filename, data):
+    """
+    Write the resulting CSV with one line for each package
+    Arguments:
+        filename: the file to write to
+        data: dictionary from parsing the JSON file
+    Returns:
+        None
+    """
+    if not "version" in data or data["version"] != "1":
+        exit_error(1, "Unrecognized format version number")
+    if not "package" in data:
+        exit_error(1, "Mandatory 'package' key not found")
+
+    lines = ""
+    total_issue_count = 0
+    for package in data["package"]:
+        package_info = ""
+        keys_in_package = {"name", "layer", "version", "issue"}
+        if keys_in_package - package.keys():
+            exit_error(
+                1,
+                "Missing a mandatory key in package: %s"
+                % (keys_in_package - package.keys()),
+            )
+
+        package_info += "LAYER: %s\n" % package["layer"]
+        package_info += "PACKAGE NAME: %s\n" % package["name"]
+        package_info += "PACKAGE VERSION: %s\n" % package["version"]
+
+        for issue in package["issue"]:
+            keys_in_issue = {"id", "status", "detail"}
+            if keys_in_issue - issue.keys():
+                print("Warning: Missing keys %s in 'issue' for the package '%s'"
+                    % (keys_in_issue - issue.keys(), package["name"]))
+
+            lines += package_info
+            lines += "CVE: %s\n" % issue["id"]
+            lines += "CVE STATUS: %s\n" % issue["status"]
+            lines += "CVE DETAIL: %s\n" % issue["detail"]
+            if "description" in issue:
+                lines += "CVE DESCRIPTION: %s\n" % issue["description"]
+            if "summary" in issue:
+                lines += "CVE SUMMARY: %s\n" % issue["summary"]
+            if "scorev2" in issue:
+                lines += "CVSS v2 BASE SCORE: %s\n" % issue["scorev2"]
+            if "scorev3" in issue:
+                lines += "CVSS v3 BASE SCORE: %s\n" % issue["scorev3"]
+            if "vector" in issue:
+                lines += "VECTOR: %s\n" % issue["vector"]
+            if "vectorString" in issue:
+                lines += "VECTORSTRING: %s\n" % issue["vectorString"]
+            lines += "MORE INFORMATION: https://nvd.nist.gov/vuln/detail/%s\n" % issue["id"]
+            lines += "\n"
+
+    with open(filename, "w") as f:
+        f.write(lines)
+
+def main(argv):
+    parse_args(argv)
+    data = load_json(infile)
+    process_data(outfile, data)
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])