Exemple #1
0
def compare_where_python(where_expression: str,
                         pattern_match: PatternMatch) -> bool:
    result = False
    return_var = "semgrep_pattern_return"
    lines = where_expression.strip().split("\n")
    to_eval = "\n".join(lines[:-1] + [f"{return_var} = {lines[-1]}"])

    local_vars = {
        metavar: pattern_match.get_metavariable_value(metavar)
        for metavar in pattern_match.metavariables
    }
    scope = {"vars": local_vars}

    try:
        # fmt: off
        exec(
            to_eval, scope
        )  # nosem: contrib.dlint.dlint-equivalent.insecure-exec-use, python.lang.security.audit.exec-detected.exec-detected
        # fmt: on
        result = scope[return_var]  # type: ignore
    except KeyError as ex:
        logger.error(
            f"could not find metavariable {ex} while evaluating where-python expression '{where_expression}', consider case where metavariable is missing"
        )
    except Exception as ex:
        logger.error(
            f"received error '{repr(ex)}' while evaluating where-python expression '{where_expression}'"
        )

    if not isinstance(result, bool):
        raise SemgrepError(
            f"where-python expression '{where_expression}' needs boolean output but got {result}"
        )
    return result
Exemple #2
0
def interpolate_message_metavariables(
    rule: Rule,
    pattern_match: PatternMatch,
    all_pattern_match_metavariables: Dict[str, List[PatternMatch]],
) -> str:
    msg_text = rule.message
    for metavar_text in all_pattern_match_metavariables:
        replace_text = metavar_text
        try:  # Always prefer the pattern match metavariable first.
            replace_text = pattern_match.get_metavariable_value(metavar_text)
        except KeyError:  # If one isn't present, retrieve the value from all metavariables.
            pattern_matches_with_metavars_that_enclose_match: List[PatternMatch] = list(
                filter(
                    lambda possible_enclosing_match: possible_enclosing_match.range.is_range_enclosing_or_eq(
                        pattern_match.range
                    ),
                    all_pattern_match_metavariables[metavar_text],
                )
            )
            if len(pattern_matches_with_metavars_that_enclose_match):
                replace_text = pattern_matches_with_metavars_that_enclose_match[
                    0
                ].get_metavariable_value(metavar_text)
        msg_text = msg_text.replace(metavar_text, replace_text)
    return msg_text
Exemple #3
0
def interpolate_message_metavariables(rule: Rule,
                                      pattern_match: PatternMatch) -> str:
    msg_text = rule.message
    for metavar in pattern_match.metavars:
        msg_text = msg_text.replace(
            metavar, pattern_match.get_metavariable_value(metavar))
    return msg_text
Exemple #4
0
def interpolate_fix_metavariables(
        rule: Rule, pattern_match: PatternMatch) -> Optional[str]:
    fix_str = rule.fix
    if fix_str is None:
        return None
    for metavar in pattern_match.metavars:
        fix_str = fix_str.replace(
            metavar, pattern_match.get_metavariable_value(metavar))
    return fix_str
Exemple #5
0
def interpolate_message_metavariables(
        rule: Rule, pattern_match: PatternMatch,
        propagated_metavariables: Dict[str, str]) -> str:
    msg_text = rule.message
    for metavariable in pattern_match.metavariables:
        msg_text = msg_text.replace(
            metavariable, pattern_match.get_metavariable_value(metavariable))
    for metavariable, metavariable_text in propagated_metavariables.items():
        msg_text = msg_text.replace(metavariable, metavariable_text)
    return msg_text
Exemple #6
0
def interpolate_fix_metavariables(
        rule: Rule, pattern_match: PatternMatch,
        propagated_metavariables: Dict[str, str]) -> Optional[str]:
    fix_str = rule.fix
    if fix_str is None:
        return None
    for metavariable in pattern_match.metavariables:
        fix_str = fix_str.replace(
            metavariable, pattern_match.get_metavariable_value(metavariable))
    for metavariable, metavariable_text in propagated_metavariables.items():
        fix_str = fix_str.replace(metavariable, metavariable_text)
    return fix_str
Exemple #7
0
def interpolate_string_with_metavariables(
        text: str, pattern_match: PatternMatch,
        propagated_metavariables: Dict[str, str]) -> str:
    """Interpolates a string with the metavariables contained in it, returning a new string"""

    # Sort by metavariable length to avoid name collisions (eg. $X2 must be handled before $X)
    for metavariable in sorted(pattern_match.metavariables,
                               key=len,
                               reverse=True):
        text = text.replace(metavariable,
                            pattern_match.get_metavariable_value(metavariable))

    # Sort by metavariable length to avoid name collisions (eg. $X2 must be handled before $X)
    for metavariable in sorted(propagated_metavariables.keys(),
                               key=len,
                               reverse=True):
        text = text.replace(metavariable,
                            propagated_metavariables[metavariable])

    return text