1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
"""
Common functions for processing Fixes in SSG
"""
from __future__ import absolute_import
from __future__ import print_function
import os
from .build_remediations import parse_from_file_without_jinja
from .utils import read_file_list, parse_platform
from .build_remediations import REMEDIATION_TO_EXT_MAP as REMEDIATION_MAP
def get_fix_path(rule_obj, lang, fix_id):
"""
Return the full path to the fix for the given language and fix_id in the rule described by rule_obj.
Args:
rule_obj (dict): A dictionary containing information about the rule, including dir', 'id',
and 'remediations'.
lang (str): The language for which the fix is required.
fix_id (str): The identifier for the specific fix.
Returns:
str: The full path to the fix file.
Raises:
ValueError: If the rule_obj is malformed or if the fix_id is unknown for the given rule_id
and language.
"""
if not fix_id.endswith(REMEDIATION_MAP[lang]):
fix_id += REMEDIATION_MAP[lang]
if ('dir' not in rule_obj or 'id' not in rule_obj or
'remediations' not in rule_obj or lang not in rule_obj['remediations']):
raise ValueError("Malformed rule_obj")
if fix_id not in rule_obj['remediations'][lang]:
raise ValueError("Unknown fix_id:%s for rule_id:%s and lang:%s" %
(fix_id, rule_obj['id'], lang))
return os.path.join(rule_obj['dir'], lang, fix_id)
def get_fix_contents(rule_obj, lang, fix_id):
"""
Retrieve the path and contents of a specific fix.
Args:
rule_obj (object): The rule object containing the fix information.
lang (str): The language of the fix.
fix_id (str): The identifier of the fix.
Returns:
tuple: A tuple containing the path to the fix and the contents of the fix.
"""
fix_path = get_fix_path(rule_obj, lang, fix_id)
fix_contents = read_file_list(fix_path)
return fix_path, fix_contents
def applicable_platforms(fix_path):
"""
Determines the applicable platforms for a given fix.
Args:
fix_path (str): The file path to the fix configuration file.
Returns:
list: A list of platforms that the fix applies to.
Raises:
ValueError: If the fix configuration is malformed or missing the 'platform' key.
"""
_, config = parse_from_file_without_jinja(fix_path)
if 'platform' not in config:
raise ValueError("Malformed fix: missing platform" % fix_path)
return parse_platform(config['platform'])
def find_platform_line(fix_contents):
"""
Parses the fix content to determine the line number that the platforms configuration option is on.
Note:
If the configuration specification changes, please update the corresponding parsing in
ssg.build_remediations.parse_from_file_with_jinja(...).
Args:
fix_contents (list of str): The contents of the configuration file as a list of strings.
Returns:
int or None: The line number of the platform configuration option, or None if not found.
"""
matched_line = None
for line_num in range(0, len(fix_contents)):
line = fix_contents[line_num]
if line.startswith('#') and '=' in line:
key, value = line.strip('#').split('=', 1)
if key.strip() == 'platform':
matched_line = line_num
return matched_line
def set_applicable_platforms(fix_contents, new_platforms):
"""
Modifies the given fix contents to update the platforms to the new platforms.
Args:
fix_contents (list of str): The contents of the fix file as a list of strings.
new_platforms (list of str): A list of new platforms to set in the fix file.
Returns:
list of str: The modified contents with the updated platforms.
Raises:
ValueError: If the platform line cannot be found in the fix contents.
"""
platform_line = find_platform_line(fix_contents)
if platform_line is None:
raise ValueError("When parsing config file, unable to find platform "
"line!\n\n%s" % "\n".join(fix_contents))
new_platforms_str = "# platform = " + ",".join(sorted(new_platforms))
new_contents = fix_contents[0:platform_line]
new_contents.extend([new_platforms_str])
new_contents.extend(fix_contents[platform_line+1:])
return new_contents
|