Beispiel #1
0
def get_rule_range(document: str, pos: lsp.Position) -> lsp.Range:
    '''Get the range of the YARA rule that a given symbol is in

    :document: Text to search in
               To determine line numbers, text is split at newlines, and carriage returns are ignored
    :pos: Symbol position to base range off of
    '''
    start_pattern = re.compile(r"^((private|global) )?rule\b")
    end_pattern = re.compile("^}$")
    lines = document.replace("\r", "").split("\n")
    # default to assuming the entire document is within range
    start_pos = lsp.Position(line=0, char=0)
    end_pos = lsp.Position(line=len(lines), char=0)
    # work backwards from the given position and find the start of rule
    for index in range(pos.line, 0, -1):
        line = lines[index]
        match = start_pattern.match(line)
        if match:
            start_pos = lsp.Position(line=index, char=0)
            break
    # start from the given position and find the first end of rule
    for index in range(pos.line, len(lines)):
        line = lines[index]
        match = end_pattern.match(line)
        if match:
            end_pos = lsp.Position(line=index, char=0)
            break
    return lsp.Range(start=start_pos, end=end_pos)
def test_range():
    ''' Ensure Range is properly encoded to JSON dictionaries '''
    pos_dict = {"line": 10, "character": 15}
    pos = protocol.Position(line=pos_dict["line"], char=pos_dict["character"])
    rg_dict = {"start": pos_dict, "end": pos_dict}
    rg_obj = protocol.Range(start=pos, end=pos)
    assert json.dumps(rg_obj, cls=protocol.JSONEncoder) == json.dumps(rg_dict)
def test_location():
    ''' Ensure Location is properly encoded to JSON dictionaries '''
    pos_dict = {"line": 10, "character": 15}
    pos = protocol.Position(line=pos_dict["line"], char=pos_dict["character"])
    rg_dict = {"start": pos_dict, "end": pos_dict}
    rg_obj = protocol.Range(start=pos, end=pos)
    loc_dict = {"range": rg_dict, "uri": "fake:///one/two/three/four.path"}
    loc = protocol.Location(locrange=rg_obj, uri=loc_dict["uri"])
    assert json.dumps(loc, cls=protocol.JSONEncoder) == json.dumps(loc_dict)
def test_get_rule_range(test_rules):
    ''' Ensure YARA rules are parsed out and their range is returned '''
    peek_rules = test_rules.joinpath("peek_rules.yara").resolve()
    rules = peek_rules.read_text()
    pos = protocol.Position(line=42, char=12)
    result = helpers.get_rule_range(rules, pos)
    assert isinstance(result, protocol.Range) is True
    assert result.start.line == 33
    assert result.start.char == 0
    assert result.end.line == 43
    assert result.end.char == 0
def test_diagnostic():
    ''' Ensure Diagnostic is properly encoded to JSON dictionaries '''
    pos_dict = {"line": 10, "character": 15}
    pos = protocol.Position(line=pos_dict["line"], char=pos_dict["character"])
    rg_dict = {"start": pos_dict, "end": pos_dict}
    rg_obj = protocol.Range(start=pos, end=pos)
    diag_dict = {
        "message": "Test Diagnostic",
        "range": rg_dict,
        "relatedInformation": [],
        "severity": 1
    }
    diag = protocol.Diagnostic(locrange=rg_obj,
                               message=diag_dict["message"],
                               severity=diag_dict["severity"])
    assert json.dumps(diag, cls=protocol.JSONEncoder) == json.dumps(diag_dict)
def test_position():
    ''' Ensure Position is properly encoded to JSON dictionaries '''
    pos_dict = {"line": 10, "character": 15}
    pos = protocol.Position(line=pos_dict["line"], char=pos_dict["character"])
    assert json.dumps(pos, cls=protocol.JSONEncoder) == json.dumps(pos_dict)
def test_resolve_symbol():
    ''' Ensure symbols are properly resolved '''
    document = "rule ResolveSymbol {\n strings:\n  $a = \"test\"\n condition:\n  #a > 3\n}\n"
    pos = protocol.Position(line=4, char=4)
    symbol = helpers.resolve_symbol(document, pos)
    assert symbol == "#a"