Skip to content

Commit d43ead2

Browse files
fix lint tests
1 parent 64d915d commit d43ead2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1257
-939
lines changed

guarddog/analyzer/analyzer.py

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,13 @@ def __init__(self, ecosystem=ECOSYSTEM.PYPI) -> None:
6767
".semgrep_logs",
6868
]
6969

70-
def analyze(self, path, info=None, rules=None, name: Optional[str] = None, version: Optional[str] = None) -> dict:
70+
def analyze(
71+
self,
72+
path,
73+
info=None,
74+
rules=None,
75+
name: Optional[str] = None,
76+
version: Optional[str] = None) -> dict:
7177
"""
7278
Analyzes a package in the given path
7379
@@ -87,23 +93,33 @@ def analyze(self, path, info=None, rules=None, name: Optional[str] = None, versi
8793
sourcecode_results = None
8894

8995
# populate results, errors, and number of issues
90-
metadata_results = self.analyze_metadata(path, info, rules, name, version)
96+
metadata_results = self.analyze_metadata(
97+
path, info, rules, name, version)
9198
sourcecode_results = self.analyze_sourcecode(path, rules)
9299

93100
# Concatenate dictionaries together
94101
issues = metadata_results["issues"] + sourcecode_results["issues"]
95102
results = metadata_results["results"] | sourcecode_results["results"]
96103
errors = metadata_results["errors"] | sourcecode_results["errors"]
97104

98-
output = {"issues": issues, "errors": errors, "results": results, "path": path}
105+
output = {
106+
"issues": issues,
107+
"errors": errors,
108+
"results": results,
109+
"path": path}
99110
# Including extension info - pending discussion
100111
# if info is not None:
101112
# output["package_info"] = info
102113

103114
return output
104115

105-
def analyze_metadata(self, path: str, info, rules=None, name: Optional[str] = None,
106-
version: Optional[str] = None) -> dict:
116+
def analyze_metadata(
117+
self,
118+
path: str,
119+
info,
120+
rules=None,
121+
name: Optional[str] = None,
122+
version: Optional[str] = None) -> dict:
107123
"""
108124
Analyzes the metadata of a given package
109125
@@ -132,7 +148,8 @@ def analyze_metadata(self, path: str, info, rules=None, name: Optional[str] = No
132148
for rule in all_rules:
133149
try:
134150
log.debug(f"Running rule {rule} against package '{name}'")
135-
rule_matches, message = self.metadata_detectors[rule].detect(info, path, name, version)
151+
rule_matches, message = self.metadata_detectors[rule].detect(
152+
info, path, name, version)
136153
results[rule] = None
137154
if rule_matches:
138155
issues += 1
@@ -162,7 +179,11 @@ def analyze_sourcecode(self, path, rules=None) -> dict:
162179
results = semgrepscan_results["results"] | yarascan_results["results"]
163180
errors = semgrepscan_results["errors"] | yarascan_results["errors"]
164181

165-
return {"issues": issues, "errors": errors, "results": results, "path": path}
182+
return {
183+
"issues": issues,
184+
"errors": errors,
185+
"results": results,
186+
"path": path}
166187

167188
def analyze_yara(self, path: str, rules: Optional[set] = None) -> dict:
168189
"""
@@ -212,30 +233,32 @@ def analyze_yara(self, path: str, rules: Optional[set] = None) -> dict:
212233
continue
213234

214235
scan_file_target_abspath = os.path.join(root, f)
215-
scan_file_target_relpath = os.path.relpath(scan_file_target_abspath, path)
236+
scan_file_target_relpath = os.path.relpath(
237+
scan_file_target_abspath, path)
216238

217239
matches = scan_rules.match(scan_file_target_abspath)
218240
for m in matches:
219241
rule_name = m.rule
220-
221242
if rule_name in verbose_rules:
222243
# For verbose rules, we only show that the rule was triggered in the matching file
223-
# We're logging appearances once instead of issue-counting
244+
# We're logging appearances once instead of
245+
# issue-counting
224246
file_already_reported = any(
225247
finding["location"].startswith(scan_file_target_relpath + ":")
226248
for finding in rule_results[rule_name]
227249
)
228-
229250
if not file_already_reported:
230251
finding = {
231252
"location": f"{scan_file_target_relpath}:1",
232-
"code": f"Rule triggered in file (matches hidden for brevity)",
233-
'message': m.meta.get("description", f"{rule_name} rule matched")
234-
}
253+
"code": f'{"Rule triggered in file (matches hidden for brevity)"}',
254+
'message': m.meta.get(
255+
"description",
256+
f"{rule_name} rule matched")}
235257
issues += 1
236258
rule_results[rule_name].append(finding)
237259
else:
238-
# For non-verbose rules, show detailed matches as before
260+
# For non-verbose rules, show detailed matches as
261+
# before
239262
for s in m.strings:
240263
for i in s.instances:
241264
finding = {
@@ -259,7 +282,10 @@ def analyze_yara(self, path: str, rules: Optional[set] = None) -> dict:
259282
except Exception as e:
260283
errors["rules-all"] = f"failed to run rule: {str(e)}"
261284

262-
return {"results": results | rule_results, "errors": errors, "issues": issues}
285+
return {
286+
"results": results | rule_results,
287+
"errors": errors,
288+
"issues": issues}
263289

264290
def analyze_semgrep(self, path, rules=None) -> dict:
265291
"""
@@ -284,10 +310,8 @@ def analyze_semgrep(self, path, rules=None) -> dict:
284310
errors = {}
285311
issues = 0
286312

287-
rules_path = list(map(
288-
lambda rule_name: os.path.join(SOURCECODE_RULES_PATH, f"{rule_name}.yml"),
289-
all_rules
290-
))
313+
rules_path = list(map(lambda rule_name: os.path.join(
314+
SOURCECODE_RULES_PATH, f"{rule_name}.yml"), all_rules))
291315

292316
if len(rules_path) == 0:
293317
log.debug("No semgrep code rules to run")
@@ -296,7 +320,8 @@ def analyze_semgrep(self, path, rules=None) -> dict:
296320
try:
297321
log.debug(f"Running semgrep code rules against {path}")
298322
response = self._invoke_semgrep(target=path, rules=rules_path)
299-
rule_results = self._format_semgrep_response(response, targetpath=targetpath)
323+
rule_results = self._format_semgrep_response(
324+
response, targetpath=targetpath)
300325
issues += sum(len(res) for res in rule_results.values())
301326

302327
results = results | rule_results
@@ -308,7 +333,9 @@ def analyze_semgrep(self, path, rules=None) -> dict:
308333
def _invoke_semgrep(self, target: str, rules: Iterable[str]):
309334
try:
310335
SEMGREP_MAX_TARGET_BYTES = int(
311-
os.getenv("GUARDDOG_SEMGREP_MAX_TARGET_BYTES", MAX_BYTES_DEFAULT))
336+
os.getenv(
337+
"GUARDDOG_SEMGREP_MAX_TARGET_BYTES",
338+
MAX_BYTES_DEFAULT))
312339
SEMGREP_TIMEOUT = int(
313340
os.getenv("GUARDDOG_SEMGREP_TIMEOUT", SEMGREP_TIMEOUT_DEFAULT))
314341
cmd = ["semgrep"]
@@ -325,7 +352,11 @@ def _invoke_semgrep(self, target: str, rules: Iterable[str]):
325352
cmd.append(f"--max-target-bytes={SEMGREP_MAX_TARGET_BYTES}")
326353
cmd.append(target)
327354
log.debug(f"Invoking semgrep with command line: {' '.join(cmd)}")
328-
result = subprocess.run(cmd, capture_output=True, check=True, encoding="utf-8")
355+
result = subprocess.run(
356+
cmd,
357+
capture_output=True,
358+
check=True,
359+
encoding="utf-8")
329360
return json.loads(str(result.stdout))
330361
except FileNotFoundError:
331362
raise Exception("unable to find semgrep binary")
@@ -379,9 +410,9 @@ def _format_semgrep_response(self, response, rule=None, targetpath=None):
379410
file_path = os.path.abspath(result["path"])
380411
code = self.trim_code_snippet(
381412
self.get_snippet(
382-
file_path=file_path, start_line=start_line, end_line=end_line
383-
)
384-
)
413+
file_path=file_path,
414+
start_line=start_line,
415+
end_line=end_line))
385416
if targetpath:
386417
file_path = os.path.relpath(file_path, targetpath)
387418

@@ -400,7 +431,11 @@ def _format_semgrep_response(self, response, rule=None, targetpath=None):
400431

401432
return results
402433

403-
def get_snippet(self, file_path: str, start_line: int, end_line: int) -> str:
434+
def get_snippet(
435+
self,
436+
file_path: str,
437+
start_line: int,
438+
end_line: int) -> str:
404439
"""
405440
Returns the code snippet between start_line and stop_line in a file
406441

guarddog/analyzer/metadata/extension/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515

1616
for detectorClass in classes:
1717
detectorInstance = detectorClass() # type: ignore
18-
EXTENSION_METADATA_RULES[detectorInstance.get_name()] = detectorInstance
18+
EXTENSION_METADATA_RULES[detectorInstance.get_name()] = detectorInstance

guarddog/analyzer/metadata/extension/empty_information.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,35 @@
1313
class ExtensionEmptyInfoDetector(EmptyInfoDetector):
1414
"""Detects extensions with empty description information"""
1515

16-
def detect(self, package_info, path: Optional[str] = None, name: Optional[str] = None,
17-
version: Optional[str] = None) -> tuple[bool, str]:
18-
19-
log.debug(f"Running extension empty description heuristic on extension {name} version {version}")
20-
16+
def detect(self,
17+
package_info,
18+
path: Optional[str] = None,
19+
name: Optional[str] = None,
20+
version: Optional[str] = None) -> tuple[bool,
21+
str]:
22+
23+
log.debug(
24+
f"Running extension empty description heuristic on extension {name} version {version}")
25+
2126
if not package_info or not isinstance(package_info, dict):
2227
return True, "Extension has no package information"
23-
28+
2429
manifest = package_info.get("manifest", {})
2530
marketplace = package_info.get("marketplace", {})
2631
source = package_info.get("source", "unknown")
27-
32+
2833
return self._detect_with_metadata(manifest, marketplace, source)
29-
30-
def _detect_with_metadata(self, manifest: dict, marketplace: dict, source: str) -> tuple[bool, str]:
34+
35+
def _detect_with_metadata(self,
36+
manifest: dict,
37+
marketplace: dict,
38+
source: str) -> tuple[bool,
39+
str]:
3140
"""Detect empty information with pre-extracted metadata"""
32-
41+
3342
manifest_description = manifest.get("description", "").strip()
3443
manifest_display_name = manifest.get("displayName", "").strip()
35-
44+
3645
if not manifest_description and not manifest_display_name:
3746
return True, self.MESSAGE_TEMPLATE % "Extension Marketplace (manifest)"
38-
return False, ""
47+
return False, ""

0 commit comments

Comments
 (0)