Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion quark/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"-r",
"--rule",
help="Rules directory",
type=click.Path(exists=True, file_okay=True, dir_okay=True),
type=click.Path(exists=False, file_okay=True, dir_okay=True),
default=f"{config.DIR_PATH}",
required=False,
show_default=True,
Expand Down Expand Up @@ -205,6 +205,12 @@ def entry_point(

rule_path_list = [rule_filter]
else:
if not os.path.exists(rule):
raise click.BadParameter(
f"Path {rule} does not exist.",
param_hint="--rule",
)

rule_path_list = [
os.path.join(dir_path, file)
for dir_path, _, file_list in os.walk(rule)
Expand Down
101 changes: 101 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import json
from unittest.mock import patch

import pytest
from click.testing import CliRunner

from quark.cli import entry_point


@pytest.fixture
def mock_quark():
with patch("quark.cli.Quark") as mock:
data = mock.return_value
data.quark_analysis.score_sum = 0
data.quark_analysis.weight_sum = 0
data.quark_analysis.summary_report_table = ""
yield mock


def _rule_option():
for param in entry_point.params:
if param.name == "rule":
return param
raise AssertionError("rule option not found")


def _write_rule(path):
path.write_text(
json.dumps(
{
"crime": "test",
"permission": [],
"api": [
{
"class": "Lfoo/Bar;",
"method": "first",
"descriptor": "()V",
},
{
"class": "Lfoo/Bar;",
"method": "second",
"descriptor": "()V",
},
],
"score": 1,
"label": ["test"],
}
)
)


def test_custom_rule_does_not_validate_missing_default_rules(
tmp_path, monkeypatch, mock_quark
):
missing_default_rules = tmp_path / "missing-rules"
custom_rule = tmp_path / "custom_rule.json"
apk = tmp_path / "sample.apk"
_write_rule(custom_rule)
apk.write_text("")
monkeypatch.setattr(_rule_option(), "default", str(missing_default_rules))

runner = CliRunner()

result = runner.invoke(
entry_point,
["-a", str(apk), "-s", str(custom_rule)],
)

assert result.exit_code == 0
mock_quark.assert_called_once()


def test_missing_rules_path_fails_when_rules_are_loaded(tmp_path, monkeypatch):
missing_rules = tmp_path / "missing-rules"
apk = tmp_path / "sample.apk"
apk.write_text("")
monkeypatch.setattr(_rule_option(), "default", str(missing_rules))

runner = CliRunner()

result = runner.invoke(entry_point, ["-a", str(apk), "-s"])

assert result.exit_code != 0
assert "Path" in result.output
assert str(missing_rules) in result.output


def test_existing_rules_directory_is_loaded(tmp_path, monkeypatch, mock_quark):
rules_dir = tmp_path / "rules"
rules_dir.mkdir()
_write_rule(rules_dir / "custom_rule.json")
apk = tmp_path / "sample.apk"
apk.write_text("")
monkeypatch.setattr(_rule_option(), "default", str(rules_dir))

runner = CliRunner()

result = runner.invoke(entry_point, ["-a", str(apk), "-s"])

assert result.exit_code == 0
mock_quark.assert_called_once()
Loading