From 4505ba1ea65515fb01f1ea168131a48968d134a7 Mon Sep 17 00:00:00 2001 From: Arnim Rupp <46819580+ruppde@users.noreply.github.com> Date: Thu, 5 Oct 2023 00:48:11 +0200 Subject: [PATCH 1/3] Select hash for context and SHA1 & MD5, solve issue #136 New: Select hash for context and SHA1 & MD5 New: Case ignore in hashes, because why not Bugfix: Only show "Select hash for context" next to valid hashes Solve https://github.com/avast/yls/issues/136 --- .gitignore | 1 + tests/unit/test_utils.py | 13 +++++++------ yls/server.py | 4 ++-- yls/utils.py | 14 +++++++++----- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index b08827b..4822288 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .ropeproject __pycache__ dist +*.swp diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 2d264df..d6afadc 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -67,12 +67,13 @@ def test_first_non_space(): def test_is_sha(): - assert utils.is_sha256_hash("f3b7edffa346c23f24beba4d93880f358532085b3598319fed0cfa3010bbe675") - assert not utils.is_sha256_hash("") - assert utils.is_sha256_hash("a" * 64) - assert not utils.is_sha256_hash("A" * 64) - assert not utils.is_sha256_hash(" " + "A" * 64) - assert not utils.is_sha256_hash("A" * 64 + " ") + assert utils.is_hash("f3b7edffa346c23f24beba4d93880f358532085b3598319fed0cfa3010bbe675") + assert utils.is_hash("93880f358532085b3598319fed0cfa3010bbe675") + assert utils.is_hash("8532085b3598319fed0cfa3010bbe675") + assert utils.is_hash("8532085B3598319FED0CFA3010BBE675") + assert not utils.is_hash("") + assert not utils.is_hash(" " + "A" * 64) + assert not utils.is_hash("A" * 64 + " ") def test_range_from_line(mocker: MockerFixture): diff --git a/yls/server.py b/yls/server.py index 838cc34..bc079d0 100644 --- a/yls/server.py +++ b/yls/server.py @@ -477,7 +477,7 @@ def code_lens_eval(yara_file: yaramod.YaraFile) -> list[lsp_types.CodeLens]: for rule in utils.yaramod_rules_in_file(yara_file): for meta in rule.metas: # Consider only hash metas that have valid hash as value - if meta.key != "hash" and not utils.is_sha256_hash(meta.value.pure_text): + if meta.key != "hash" or not utils.is_hash(meta.value.pure_text): continue # Create code lens for debugging @@ -595,7 +595,7 @@ async def command_eval_set_context(ls: YaraLanguageServer, args: list[Any]) -> N utils.log_command(YaraLanguageServer.COMMAND_EVAL_SET_CONTEXT) log.debug(f"{args=}") - if len(args) != 2 or not utils.is_sha256_hash(args[0]): + if len(args) != 2 or not utils.is_hash(args[0]): return _hash = args[0] diff --git a/yls/utils.py b/yls/utils.py index 764b2c8..19cd6bd 100644 --- a/yls/utils.py +++ b/yls/utils.py @@ -484,11 +484,15 @@ def debug_hover(document: Document, position: lsp_types.Position) -> lsp_types.H return lsp_types.Hover(contents=f"Token = {token}\nLSP Position = {position}") -def is_sha256_hash(i: str) -> bool: - """Check if the `i` looks like a sha256 hash. +def is_hash(i: str) -> bool: + """Check if the `i` looks like a md5, sha1 or sha256 hash. - We accept only lowercase hashes because it is the same behavior as YRTC.""" - return re.fullmatch("[0-9a-f]{64}", i) is not None + We accept upper and lowercase hashes""" + return ( + re.fullmatch("[0-9a-f]{32}", i, flags=re.IGNORECASE) or + re.fullmatch("[0-9a-f]{40}", i, flags=re.IGNORECASE) or + re.fullmatch("[0-9a-f]{64}", i, flags=re.IGNORECASE) + ) is not None def markdown_content(value: str) -> lsp_types.MarkupContent: @@ -526,7 +530,7 @@ def yaramod_rule_has_hashes(rule: yaramod.Rule) -> bool: """Check if YARA rule contains sample hashes in hash meta.""" for meta in rule.metas: # Consider only hash metas that have valid hash as value - if meta.key != "hash" or not is_sha256_hash(meta.value.pure_text): + if meta.key != "hash" or not is_hash(meta.value.pure_text): continue return True From e134208bdbda7946d65558721ace089b260da796 Mon Sep 17 00:00:00 2001 From: Arnim Rupp <46819580+ruppde@users.noreply.github.com> Date: Mon, 9 Oct 2023 12:35:29 +0200 Subject: [PATCH 2/3] Update utils.py fix black --- yls/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yls/utils.py b/yls/utils.py index 19cd6bd..f65e52e 100644 --- a/yls/utils.py +++ b/yls/utils.py @@ -489,10 +489,10 @@ def is_hash(i: str) -> bool: We accept upper and lowercase hashes""" return ( - re.fullmatch("[0-9a-f]{32}", i, flags=re.IGNORECASE) or - re.fullmatch("[0-9a-f]{40}", i, flags=re.IGNORECASE) or - re.fullmatch("[0-9a-f]{64}", i, flags=re.IGNORECASE) - ) is not None + re.fullmatch("[0-9a-f]{32}", i, flags=re.IGNORECASE) + or re.fullmatch("[0-9a-f]{40}", i, flags=re.IGNORECASE) + or re.fullmatch("[0-9a-f]{64}", i, flags=re.IGNORECASE) + ) is not None def markdown_content(value: str) -> lsp_types.MarkupContent: From 3fc0a844d66e5a287d7a726c17cd54fee218677a Mon Sep 17 00:00:00 2001 From: Arnim Rupp <46819580+ruppde@users.noreply.github.com> Date: Mon, 9 Oct 2023 12:48:55 +0200 Subject: [PATCH 3/3] Update developing.md --- docs/developing.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/developing.md b/docs/developing.md index 0f9c102..207d3ae 100644 --- a/docs/developing.md +++ b/docs/developing.md @@ -16,3 +16,9 @@ You can run tests with the following command: ```bash poetry run pytest ``` + +Run tests including pylint and the Black code formatter like the CI workflow of the repo. Useful before PRs: + +```bash +poetry run pytest -vvv --black --pylint --pylint-rcfile=pyproject.toml --cov=yls --cov-report=term-missing -l ./yls ./tests +```