vulnerablecode
vulnerablecode copied to clipboard
Address Apache HTTPD issue
______________________________________ test_updated_advisories[ApacheHTTPDDataSource-config17] ______________________________________
data_source = 'ApacheHTTPDDataSource', config = {'etags': {}}
@pytest.mark.webtest
@pytest.mark.parametrize(
("data_source", "config"),
((data["data_source"], data["data_source_cfg"]) for data in IMPORTER_REGISTRY),
)
def test_updated_advisories(data_source, config):
if not data_source == "GitHubAPIDataSource":
data_src = getattr(importers, data_source)
data_src = data_src(batch_size=MAX_ADVISORIES, config=config)
advisory_counter = 0
def patched_advisory(*args, **kwargs):
nonlocal advisory_counter
if advisory_counter >= MAX_ADVISORIES:
raise MaxAdvisoriesCreatedInterrupt
advisory_counter += 1
return Advisory(*args, **kwargs)
module = inspect.getmodule(data_src)
module_members = [m[0] for m in inspect.getmembers(module)]
advisory_class = f"{module.__name__}.Advisory"
if "Advisory" not in module_members:
advisory_class = "vulnerabilities.data_source.Advisory"
# Either
# 1) Advisory class is successfully patched and MaxAdvisoriesCreatedInterrupt is thrown when
# an importer tries to create an Advisory or
# 2) Importer somehow bypasses the patch / handles BaseException internally, then
# updated_advisories is required to return non zero advisories
with patch(advisory_class, side_effect=patched_advisory):
try:
with data_src:
> assert len(list(data_src.updated_advisories())) > 0
vulnerabilities/tests/test_upstream.py:52:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
vulnerabilities/importers/apache_httpd.py:69: in updated_advisories
advisories.append(self.to_advisory(data))
vulnerabilities/importers/apache_httpd.py:121: in to_advisory
[
vulnerabilities/importers/apache_httpd.py:124: in <listcomp>
if SemverVersion(version) in version_range
venv/lib/python3.8/site-packages/univers/versions.py:107: in __init__
object.__setattr__(self, "value", semantic_version.Version.coerce(version_string))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'semantic_version.base.Version'>, version_string = 'candidate-2.4.49-rc1', partial = False
@classmethod
def coerce(cls, version_string, partial=False):
"""Coerce an arbitrary version string into a semver-compatible one.
The rule is:
- If not enough components, fill minor/patch with zeroes; unless
partial=True
- If more than 3 dot-separated components, extra components are "build"
data. If some "build" data already appeared, append it to the
extra components
Examples:
>>> Version.coerce('0.1')
Version(0, 1, 0)
>>> Version.coerce('0.1.2.3')
Version(0, 1, 2, (), ('3',))
>>> Version.coerce('0.1.2.3+4')
Version(0, 1, 2, (), ('3', '4'))
>>> Version.coerce('0.1+2-3+4_5')
Version(0, 1, 0, (), ('2-3', '4-5'))
"""
base_re = re.compile(r'^\d+(?:\.\d+(?:\.\d+)?)?')
match = base_re.match(version_string)
if not match:
> raise ValueError(
"Version string lacks a numerical component: %r"
% version_string
)
E ValueError: Version string lacks a numerical component: 'candidate-2.4.49-rc1'
See https://github.com/nexB/univers/issues/32 for tracking the fix there.