mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 12:59:02 +02:00

The cve_check functionality to parse CVE IDs from the patch filename and patch contents have been reworked to improve parsing and also utilize tests. This ensures that the parsing works as intended. Additionally, the new patched_cves dict has a few issues I tried to fix as well. If multiple patch files exist for a single CVE ID, only the last one will show up with the "resource" key. The value for the "resource" key has been updated to hold a list and return all patch files associated with a given CVE ID. Also, at the end of get_patch_cves, CVE_STATUS can overwrite an existing entry in the dict. This could cause an issue, for example, if a CVE has been addressed via a patch, but a CVE_STATUS line also exists that ignores the given CVE ID. A warning has been added if this ever happens. (From OE-Core rev: 87c6da681609b4f8e048eca2a27ae8e068c724e1) Signed-off-by: Colin McAllister <colinmca242@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
497 lines
20 KiB
Python
497 lines
20 KiB
Python
#
|
|
# Copyright OpenEmbedded Contributors
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
|
|
import json
|
|
import os
|
|
from oeqa.selftest.case import OESelftestTestCase
|
|
from oeqa.utils.commands import bitbake, get_bb_vars
|
|
|
|
class CVECheck(OESelftestTestCase):
|
|
|
|
def test_version_compare(self):
|
|
from oe.cve_check import Version
|
|
|
|
result = Version("100") > Version("99")
|
|
self.assertTrue( result, msg="Failed to compare version '100' > '99'")
|
|
result = Version("2.3.1") > Version("2.2.3")
|
|
self.assertTrue( result, msg="Failed to compare version '2.3.1' > '2.2.3'")
|
|
result = Version("2021-01-21") > Version("2020-12-25")
|
|
self.assertTrue( result, msg="Failed to compare version '2021-01-21' > '2020-12-25'")
|
|
result = Version("1.2-20200910") < Version("1.2-20200920")
|
|
self.assertTrue( result, msg="Failed to compare version '1.2-20200910' < '1.2-20200920'")
|
|
|
|
result = Version("1.0") >= Version("1.0beta")
|
|
self.assertTrue( result, msg="Failed to compare version '1.0' >= '1.0beta'")
|
|
result = Version("1.0-rc2") > Version("1.0-rc1")
|
|
self.assertTrue( result, msg="Failed to compare version '1.0-rc2' > '1.0-rc1'")
|
|
result = Version("1.0.alpha1") < Version("1.0")
|
|
self.assertTrue( result, msg="Failed to compare version '1.0.alpha1' < '1.0'")
|
|
result = Version("1.0_dev") <= Version("1.0")
|
|
self.assertTrue( result, msg="Failed to compare version '1.0_dev' <= '1.0'")
|
|
|
|
# ignore "p1" and "p2", so these should be equal
|
|
result = Version("1.0p2") == Version("1.0p1")
|
|
self.assertTrue( result ,msg="Failed to compare version '1.0p2' to '1.0p1'")
|
|
# ignore the "b" and "r"
|
|
result = Version("1.0b") == Version("1.0r")
|
|
self.assertTrue( result ,msg="Failed to compare version '1.0b' to '1.0r'")
|
|
|
|
# consider the trailing alphabet as patched level when comparing
|
|
result = Version("1.0b","alphabetical") < Version("1.0r","alphabetical")
|
|
self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' < '1.0r'")
|
|
result = Version("1.0b","alphabetical") > Version("1.0","alphabetical")
|
|
self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' > '1.0'")
|
|
|
|
# consider the trailing "p" and "patch" as patched released when comparing
|
|
result = Version("1.0","patch") < Version("1.0p1","patch")
|
|
self.assertTrue( result ,msg="Failed to compare version with suffix '1.0' < '1.0p1'")
|
|
result = Version("1.0p2","patch") > Version("1.0p1","patch")
|
|
self.assertTrue( result ,msg="Failed to compare version with suffix '1.0p2' > '1.0p1'")
|
|
result = Version("1.0_patch2","patch") < Version("1.0_patch3","patch")
|
|
self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'")
|
|
|
|
|
|
def test_convert_cve_version(self):
|
|
from oe.cve_check import convert_cve_version
|
|
|
|
# Default format
|
|
self.assertEqual(convert_cve_version("8.3"), "8.3")
|
|
self.assertEqual(convert_cve_version(""), "")
|
|
|
|
# OpenSSL format version
|
|
self.assertEqual(convert_cve_version("1.1.1t"), "1.1.1t")
|
|
|
|
# OpenSSH format
|
|
self.assertEqual(convert_cve_version("8.3_p1"), "8.3p1")
|
|
self.assertEqual(convert_cve_version("8.3_p22"), "8.3p22")
|
|
|
|
# Linux kernel format
|
|
self.assertEqual(convert_cve_version("6.2_rc8"), "6.2-rc8")
|
|
self.assertEqual(convert_cve_version("6.2_rc31"), "6.2-rc31")
|
|
|
|
def test_product_match(self):
|
|
from oe.cve_check import has_cve_product_match
|
|
|
|
status = {}
|
|
status["detail"] = "ignored"
|
|
status["vendor"] = "*"
|
|
status["product"] = "*"
|
|
status["description"] = ""
|
|
status["mapping"] = ""
|
|
|
|
self.assertEqual(has_cve_product_match(status, "some_vendor:some_product"), True)
|
|
self.assertEqual(has_cve_product_match(status, "*:*"), True)
|
|
self.assertEqual(has_cve_product_match(status, "some_product"), True)
|
|
self.assertEqual(has_cve_product_match(status, "glibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "glibca"), True)
|
|
self.assertEqual(has_cve_product_match(status, "aglibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "*"), True)
|
|
self.assertEqual(has_cve_product_match(status, "aglibc glibc test:test"), True)
|
|
|
|
status["product"] = "glibc"
|
|
self.assertEqual(has_cve_product_match(status, "some_vendor:some_product"), False)
|
|
# The CPE in the recipe must be defined, no * accepted
|
|
self.assertEqual(has_cve_product_match(status, "*:*"), False)
|
|
self.assertEqual(has_cve_product_match(status, "*"), False)
|
|
self.assertEqual(has_cve_product_match(status, "some_product"), False)
|
|
self.assertEqual(has_cve_product_match(status, "glibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "glibca"), False)
|
|
self.assertEqual(has_cve_product_match(status, "aglibc"), False)
|
|
self.assertEqual(has_cve_product_match(status, "some_vendor:glibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "some_vendor:glibc test"), True)
|
|
self.assertEqual(has_cve_product_match(status, "test some_vendor:glibc"), True)
|
|
|
|
status["vendor"] = "glibca"
|
|
status["product"] = "glibc"
|
|
self.assertEqual(has_cve_product_match(status, "some_vendor:some_product"), False)
|
|
# The CPE in the recipe must be defined, no * accepted
|
|
self.assertEqual(has_cve_product_match(status, "*:*"), False)
|
|
self.assertEqual(has_cve_product_match(status, "*"), False)
|
|
self.assertEqual(has_cve_product_match(status, "some_product"), False)
|
|
self.assertEqual(has_cve_product_match(status, "glibc"), False)
|
|
self.assertEqual(has_cve_product_match(status, "glibca"), False)
|
|
self.assertEqual(has_cve_product_match(status, "aglibc"), False)
|
|
self.assertEqual(has_cve_product_match(status, "some_vendor:glibc"), False)
|
|
self.assertEqual(has_cve_product_match(status, "glibca:glibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "test:test glibca:glibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "test glibca:glibc"), True)
|
|
self.assertEqual(has_cve_product_match(status, "glibca:glibc test"), True)
|
|
|
|
def test_parse_cve_from_patch_filename(self):
|
|
from oe.cve_check import parse_cve_from_filename
|
|
|
|
# Patch filename without CVE ID
|
|
self.assertEqual(parse_cve_from_filename("0001-test.patch"), "")
|
|
|
|
# Patch with single CVE ID
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2022-12345.patch"), "CVE-2022-12345"
|
|
)
|
|
|
|
# Patch with multiple CVE IDs
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2022-41741-CVE-2022-41742.patch"),
|
|
"CVE-2022-41742",
|
|
)
|
|
|
|
# Patches with CVE ID and appended text
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2023-3019-0001.patch"), "CVE-2023-3019"
|
|
)
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2024-21886-1.patch"), "CVE-2024-21886"
|
|
)
|
|
|
|
# Patch with CVE ID and prepended text
|
|
self.assertEqual(
|
|
parse_cve_from_filename("grep-CVE-2012-5667.patch"), "CVE-2012-5667"
|
|
)
|
|
self.assertEqual(
|
|
parse_cve_from_filename("0001-CVE-2012-5667.patch"), "CVE-2012-5667"
|
|
)
|
|
|
|
# Patch with CVE ID and both prepended and appended text
|
|
self.assertEqual(
|
|
parse_cve_from_filename(
|
|
"0001-tpm2_import-fix-fixed-AES-key-CVE-2021-3565-0001.patch"
|
|
),
|
|
"CVE-2021-3565",
|
|
)
|
|
|
|
# Only grab the last CVE ID in the filename
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2012-5667-CVE-2012-5668.patch"),
|
|
"CVE-2012-5668",
|
|
)
|
|
|
|
# Test invalid CVE ID with incorrect length (must be at least 4 digits)
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2024-001.patch"),
|
|
"",
|
|
)
|
|
|
|
# Test valid CVE ID with very long length
|
|
self.assertEqual(
|
|
parse_cve_from_filename("CVE-2024-0000000000000000000000001.patch"),
|
|
"CVE-2024-0000000000000000000000001",
|
|
)
|
|
|
|
def test_parse_cve_from_patch_contents(self):
|
|
import textwrap
|
|
from oe.cve_check import parse_cves_from_patch_contents
|
|
|
|
# Standard patch file excerpt without any patches
|
|
self.assertEqual(
|
|
parse_cves_from_patch_contents(
|
|
textwrap.dedent("""\
|
|
remove "*" for root since we don't have a /etc/shadow so far.
|
|
|
|
Upstream-Status: Inappropriate [configuration]
|
|
|
|
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
|
|
|
|
--- base-passwd/passwd.master~nobash
|
|
+++ base-passwd/passwd.master
|
|
@@ -1,4 +1,4 @@
|
|
-root:*:0:0:root:/root:/bin/sh
|
|
+root::0:0:root:/root:/bin/sh
|
|
daemon:*:1:1:daemon:/usr/sbin:/bin/sh
|
|
bin:*:2:2:bin:/bin:/bin/sh
|
|
sys:*:3:3:sys:/dev:/bin/sh
|
|
""")
|
|
),
|
|
set(),
|
|
)
|
|
|
|
# Patch file with multiple CVE IDs (space-separated)
|
|
self.assertEqual(
|
|
parse_cves_from_patch_contents(
|
|
textwrap.dedent("""\
|
|
There is an assertion in function _cairo_arc_in_direction().
|
|
|
|
CVE: CVE-2019-6461 CVE-2019-6462
|
|
Upstream-Status: Pending
|
|
Signed-off-by: Ross Burton <ross.burton@intel.com>
|
|
|
|
diff --git a/src/cairo-arc.c b/src/cairo-arc.c
|
|
index 390397bae..1bde774a4 100644
|
|
--- a/src/cairo-arc.c
|
|
+++ b/src/cairo-arc.c
|
|
@@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr,
|
|
if (cairo_status (cr))
|
|
return;
|
|
|
|
- assert (angle_max >= angle_min);
|
|
+ if (angle_max < angle_min)
|
|
+ return;
|
|
|
|
if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) {
|
|
angle_max = fmod (angle_max - angle_min, 2 * M_PI);
|
|
"""),
|
|
),
|
|
{"CVE-2019-6461", "CVE-2019-6462"},
|
|
)
|
|
|
|
# Patch file with multiple CVE IDs (comma-separated w/ both space and no space)
|
|
self.assertEqual(
|
|
parse_cves_from_patch_contents(
|
|
textwrap.dedent("""\
|
|
There is an assertion in function _cairo_arc_in_direction().
|
|
|
|
CVE: CVE-2019-6461,CVE-2019-6462, CVE-2019-6463
|
|
Upstream-Status: Pending
|
|
Signed-off-by: Ross Burton <ross.burton@intel.com>
|
|
|
|
diff --git a/src/cairo-arc.c b/src/cairo-arc.c
|
|
index 390397bae..1bde774a4 100644
|
|
--- a/src/cairo-arc.c
|
|
+++ b/src/cairo-arc.c
|
|
@@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr,
|
|
if (cairo_status (cr))
|
|
return;
|
|
|
|
- assert (angle_max >= angle_min);
|
|
+ if (angle_max < angle_min)
|
|
+ return;
|
|
|
|
if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) {
|
|
angle_max = fmod (angle_max - angle_min, 2 * M_PI);
|
|
|
|
"""),
|
|
),
|
|
{"CVE-2019-6461", "CVE-2019-6462", "CVE-2019-6463"},
|
|
)
|
|
|
|
# Patch file with multiple CVE IDs (&-separated)
|
|
self.assertEqual(
|
|
parse_cves_from_patch_contents(
|
|
textwrap.dedent("""\
|
|
There is an assertion in function _cairo_arc_in_direction().
|
|
|
|
CVE: CVE-2019-6461 & CVE-2019-6462
|
|
Upstream-Status: Pending
|
|
Signed-off-by: Ross Burton <ross.burton@intel.com>
|
|
|
|
diff --git a/src/cairo-arc.c b/src/cairo-arc.c
|
|
index 390397bae..1bde774a4 100644
|
|
--- a/src/cairo-arc.c
|
|
+++ b/src/cairo-arc.c
|
|
@@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr,
|
|
if (cairo_status (cr))
|
|
return;
|
|
|
|
- assert (angle_max >= angle_min);
|
|
+ if (angle_max < angle_min)
|
|
+ return;
|
|
|
|
if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) {
|
|
angle_max = fmod (angle_max - angle_min, 2 * M_PI);
|
|
"""),
|
|
),
|
|
{"CVE-2019-6461", "CVE-2019-6462"},
|
|
)
|
|
|
|
# Patch file with multiple lines with CVE IDs
|
|
self.assertEqual(
|
|
parse_cves_from_patch_contents(
|
|
textwrap.dedent("""\
|
|
There is an assertion in function _cairo_arc_in_direction().
|
|
|
|
CVE: CVE-2019-6461 & CVE-2019-6462
|
|
|
|
CVE: CVE-2019-6463 & CVE-2019-6464
|
|
Upstream-Status: Pending
|
|
Signed-off-by: Ross Burton <ross.burton@intel.com>
|
|
|
|
diff --git a/src/cairo-arc.c b/src/cairo-arc.c
|
|
index 390397bae..1bde774a4 100644
|
|
--- a/src/cairo-arc.c
|
|
+++ b/src/cairo-arc.c
|
|
@@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr,
|
|
if (cairo_status (cr))
|
|
return;
|
|
|
|
- assert (angle_max >= angle_min);
|
|
+ if (angle_max < angle_min)
|
|
+ return;
|
|
|
|
if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) {
|
|
angle_max = fmod (angle_max - angle_min, 2 * M_PI);
|
|
|
|
"""),
|
|
),
|
|
{"CVE-2019-6461", "CVE-2019-6462", "CVE-2019-6463", "CVE-2019-6464"},
|
|
)
|
|
|
|
def test_recipe_report_json(self):
|
|
config = """
|
|
INHERIT += "cve-check"
|
|
CVE_CHECK_FORMAT_JSON = "1"
|
|
"""
|
|
self.write_config(config)
|
|
|
|
vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json")
|
|
|
|
try:
|
|
os.remove(summary_json)
|
|
os.remove(recipe_json)
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
bitbake("m4-native -c cve_check")
|
|
|
|
def check_m4_json(filename):
|
|
with open(filename) as f:
|
|
report = json.load(f)
|
|
self.assertEqual(report["version"], "1")
|
|
self.assertEqual(len(report["package"]), 1)
|
|
package = report["package"][0]
|
|
self.assertEqual(package["name"], "m4-native")
|
|
found_cves = { issue["id"]: issue["status"] for issue in package["issue"]}
|
|
self.assertIn("CVE-2008-1687", found_cves)
|
|
self.assertEqual(found_cves["CVE-2008-1687"], "Patched")
|
|
|
|
self.assertExists(summary_json)
|
|
check_m4_json(summary_json)
|
|
self.assertExists(recipe_json)
|
|
check_m4_json(recipe_json)
|
|
|
|
|
|
def test_image_json(self):
|
|
config = """
|
|
INHERIT += "cve-check"
|
|
CVE_CHECK_FORMAT_JSON = "1"
|
|
"""
|
|
self.write_config(config)
|
|
|
|
vars = get_bb_vars(["CVE_CHECK_DIR", "CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
report_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
print(report_json)
|
|
try:
|
|
os.remove(report_json)
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
bitbake("core-image-minimal-initramfs")
|
|
self.assertExists(report_json)
|
|
|
|
# Check that the summary report lists at least one package
|
|
with open(report_json) as f:
|
|
report = json.load(f)
|
|
self.assertEqual(report["version"], "1")
|
|
self.assertGreater(len(report["package"]), 1)
|
|
|
|
# Check that a random recipe wrote a recipe report to deploy/cve/
|
|
recipename = report["package"][0]["name"]
|
|
recipe_report = os.path.join(vars["CVE_CHECK_DIR"], recipename + "_cve.json")
|
|
self.assertExists(recipe_report)
|
|
with open(recipe_report) as f:
|
|
report = json.load(f)
|
|
self.assertEqual(report["version"], "1")
|
|
self.assertEqual(len(report["package"]), 1)
|
|
self.assertEqual(report["package"][0]["name"], recipename)
|
|
|
|
|
|
def test_recipe_report_json_unpatched(self):
|
|
config = """
|
|
INHERIT += "cve-check"
|
|
CVE_CHECK_FORMAT_JSON = "1"
|
|
CVE_CHECK_REPORT_PATCHED = "0"
|
|
"""
|
|
self.write_config(config)
|
|
|
|
vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json")
|
|
|
|
try:
|
|
os.remove(summary_json)
|
|
os.remove(recipe_json)
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
bitbake("m4-native -c cve_check")
|
|
|
|
def check_m4_json(filename):
|
|
with open(filename) as f:
|
|
report = json.load(f)
|
|
self.assertEqual(report["version"], "1")
|
|
self.assertEqual(len(report["package"]), 1)
|
|
package = report["package"][0]
|
|
self.assertEqual(package["name"], "m4-native")
|
|
#m4 had only Patched CVEs, so the issues array will be empty
|
|
self.assertEqual(package["issue"], [])
|
|
|
|
self.assertExists(summary_json)
|
|
check_m4_json(summary_json)
|
|
self.assertExists(recipe_json)
|
|
check_m4_json(recipe_json)
|
|
|
|
|
|
def test_recipe_report_json_ignored(self):
|
|
config = """
|
|
INHERIT += "cve-check"
|
|
CVE_CHECK_FORMAT_JSON = "1"
|
|
CVE_CHECK_REPORT_PATCHED = "1"
|
|
"""
|
|
self.write_config(config)
|
|
|
|
vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
|
|
recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "logrotate_cve.json")
|
|
|
|
try:
|
|
os.remove(summary_json)
|
|
os.remove(recipe_json)
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
bitbake("logrotate -c cve_check")
|
|
|
|
def check_m4_json(filename):
|
|
with open(filename) as f:
|
|
report = json.load(f)
|
|
self.assertEqual(report["version"], "1")
|
|
self.assertEqual(len(report["package"]), 1)
|
|
package = report["package"][0]
|
|
self.assertEqual(package["name"], "logrotate")
|
|
found_cves = {}
|
|
for issue in package["issue"]:
|
|
found_cves[issue["id"]] = {
|
|
"status" : issue["status"],
|
|
"detail" : issue["detail"] if "detail" in issue else "",
|
|
"description" : issue["description"] if "description" in issue else ""
|
|
}
|
|
# m4 CVE should not be in logrotate
|
|
self.assertNotIn("CVE-2008-1687", found_cves)
|
|
# logrotate has both Patched and Ignored CVEs
|
|
detail = "version-not-in-range"
|
|
self.assertIn("CVE-2011-1098", found_cves)
|
|
self.assertEqual(found_cves["CVE-2011-1098"]["status"], "Patched")
|
|
self.assertEqual(found_cves["CVE-2011-1098"]["detail"], detail)
|
|
self.assertEqual(len(found_cves["CVE-2011-1098"]["description"]), 0)
|
|
detail = "not-applicable-platform"
|
|
description = "CVE is debian, gentoo or SUSE specific on the way logrotate was installed/used"
|
|
self.assertIn("CVE-2011-1548", found_cves)
|
|
self.assertEqual(found_cves["CVE-2011-1548"]["status"], "Ignored")
|
|
self.assertEqual(found_cves["CVE-2011-1548"]["detail"], detail)
|
|
self.assertEqual(found_cves["CVE-2011-1548"]["description"], description)
|
|
self.assertIn("CVE-2011-1549", found_cves)
|
|
self.assertEqual(found_cves["CVE-2011-1549"]["status"], "Ignored")
|
|
self.assertEqual(found_cves["CVE-2011-1549"]["detail"], detail)
|
|
self.assertEqual(found_cves["CVE-2011-1549"]["description"], description)
|
|
self.assertIn("CVE-2011-1550", found_cves)
|
|
self.assertEqual(found_cves["CVE-2011-1550"]["status"], "Ignored")
|
|
self.assertEqual(found_cves["CVE-2011-1550"]["detail"], detail)
|
|
self.assertEqual(found_cves["CVE-2011-1550"]["description"], description)
|
|
|
|
self.assertExists(summary_json)
|
|
check_m4_json(summary_json)
|
|
self.assertExists(recipe_json)
|
|
check_m4_json(recipe_json)
|