Skip to content

Commit 977a203

Browse files
committed
rel 2023.0.1
1 parent b3f96ce commit 977a203

File tree

18 files changed

+3823
-15
lines changed

18 files changed

+3823
-15
lines changed

‎CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
All major and minor version changes will be documented in this file. Details of
44
patch-level version changes can be found in [commit messages](../../commits/master).
55

6+
## 2023.0.1 - 2023/06/27
7+
8+
- Fix `csv` writer
9+
- Fix python 3.8 compatibility
10+
- Fix `ansi` writer on python 3.11
11+
- Fix `sarif` writer so output conforms with the schema
12+
613
## 2023 - 2023/06/27
714

815
- Refactor to fix bugs and improve readability

‎documentation/reference/simplesecurity/formatter.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Formatter
1616

1717
## ansi
1818

19-
[Show source in formatter.py:162](../../../simplesecurity/formatter.py#L162)
19+
[Show source in formatter.py:163](../../../simplesecurity/formatter.py#L163)
2020

2121
Format to ansi.
2222

@@ -48,7 +48,7 @@ def ansi(
4848

4949
## csv
5050

51-
[Show source in formatter.py:120](../../../simplesecurity/formatter.py#L120)
51+
[Show source in formatter.py:121](../../../simplesecurity/formatter.py#L121)
5252

5353
Format to CSV.
5454

@@ -78,7 +78,7 @@ def csv(findings: list[Finding], heading: str | None = None, colourMode: int = 0
7878

7979
## formatEvidence
8080

81-
[Show source in formatter.py:35](../../../simplesecurity/formatter.py#L35)
81+
[Show source in formatter.py:36](../../../simplesecurity/formatter.py#L36)
8282

8383
Format evidence to plaintext.
8484

@@ -106,7 +106,7 @@ def formatEvidence(evidence: list[Line], newlineChar: bool = True) -> str:
106106

107107
## json
108108

109-
[Show source in formatter.py:97](../../../simplesecurity/formatter.py#L97)
109+
[Show source in formatter.py:98](../../../simplesecurity/formatter.py#L98)
110110

111111
Format to Json.
112112

@@ -138,7 +138,7 @@ def json(
138138

139139
## markdown
140140

141-
[Show source in formatter.py:51](../../../simplesecurity/formatter.py#L51)
141+
[Show source in formatter.py:52](../../../simplesecurity/formatter.py#L52)
142142

143143
Format to Markdown.
144144

@@ -170,7 +170,7 @@ def markdown(
170170

171171
## sarif
172172

173-
[Show source in formatter.py:253](../../../simplesecurity/formatter.py#L253)
173+
[Show source in formatter.py:254](../../../simplesecurity/formatter.py#L254)
174174

175175
Format to sarif https://sarifweb.azurewebsites.net/.
176176

‎pyproject.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "simplesecurity"
3-
version = "2023"
3+
version = "2023.0.1"
44
license = "mit"
55
description = "Combine multiple popular python security tools and generate reports or output into different formats"
66
authors = ["FredHappyface"]
@@ -38,6 +38,9 @@ semgrep = {version = "<2,>=1.29.0", optional = true}
3838
[tool.poetry.extras]
3939
full = ["poetry", "bandit", "safety", "dodgy", "dlint", "semgrep"]
4040

41+
[tool.poetry.group.dev.dependencies]
42+
jsonschema = "^4.17.3"
43+
4144
[tool.black]
4245
line-length = 100
4346
target-version = ["py38"]
@@ -74,13 +77,16 @@ disable = ["pointless-string-statement", "superfluous-parens"]
7477
[tool.tox]
7578
legacy_tox_ini = """
7679
[tox]
80+
isolated_build = True
7781
env_list =
7882
py311
7983
py310
8084
py39
8185
py38
8286
8387
[testenv]
84-
deps = pytest
85-
commands = pytest tests
88+
allowlist_externals = poetry
89+
commands =
90+
poetry install -v
91+
poetry run pytest
8692
"""

‎simplesecurity/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def _processFormat(formatin: str | None) -> Callable:
7070

7171

7272
def _processPlugin(args) -> list[Callable]:
73-
pluginMap: dict[str, Any] = {
73+
pluginMap = {
7474
"bandit": {
7575
"func": plugins.bandit,
7676
"max_severity": 3,

‎simplesecurity/formatter.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def csv(findings: list[Finding], heading: str | None = None, colourMode: int = 0
133133
_ = colourMode # silence pylint
134134
findings = sorted(findings, key=lambda i: i["severity"], reverse=True)
135135
output = StringIO()
136-
csvString = writer(output, quoting=QUOTE_ALL)
136+
csvString = writer(output, quoting=QUOTE_ALL, lineterminator="\n", strict=True)
137137
csvString.writerow(
138138
[
139139
heading
@@ -224,7 +224,7 @@ def ansi(findings: list[Finding], heading: str | None = None, colourMode: int =
224224
strBuf.append("│Severity │Finding │")
225225
strBuf.append(f"├{'─'*10}{'─'*50}┤")
226226
for finding in findings:
227-
strBuf.append(f"│{finding['severity']: <10}{finding['title'][:50]: <50}│")
227+
strBuf.append(f"│{str(finding['severity']): <10}{finding['title'][:50]: <50}│")
228228
strBuf.append(f"└{'─'*10}{'─'*50}┘")
229229
strBuf.append("")
230230

@@ -289,7 +289,7 @@ def sarif(findings: list[Finding], heading: str | None = None, colourMode: int =
289289
"physicalLocation": {
290290
"artifactLocation": {"uri": finding["file"]},
291291
"region": {
292-
"startLine": finding["line"],
292+
"startLine": max(finding["line"], 1),
293293
"snippet": {
294294
"text": "".join(
295295
[
@@ -301,8 +301,8 @@ def sarif(findings: list[Finding], heading: str | None = None, colourMode: int =
301301
},
302302
},
303303
"contextRegion": {
304-
"startLine": finding["evidence"][0]["line"],
305-
"endLine": finding["evidence"][-1]["line"],
304+
"startLine": max(finding["evidence"][0]["line"], 1),
305+
"endLine": max(finding["evidence"][-1]["line"], 1),
306306
"snippet": {
307307
"text": "\n".join(
308308
[line["content"] for line in finding["evidence"]]

‎tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

‎tests/data/advanced.ansi

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Findings
2+
3+
Find a list of findings below ordered by severity
4+
5+
┌──────────┬──────────────────────────────────────────────────┐
6+
│Severity │Finding │
7+
├──────────┼──────────────────────────────────────────────────┤
8+
│Medium │TEST │
9+
│Low │TEST2 │
10+
└──────────┴──────────────────────────────────────────────────┘
11+
12+
TEST
13+
This is a test
14+
15+
Severity: Medium (confidence: Medium)
16+
17+
Evidence
18+
┌───────────────────────────── this_file_does_not_exist ──────────────────────────────┐
19+
│ 0 lineContent │
20+
└─────────────────────────────────────────────────────────────────────────────────────┘
21+
22+
TEST2
23+
This is a test2
24+
25+
Severity: Low (confidence: High)
26+
27+
Evidence
28+
┌───────────────────────────── this_file_does_not_exist2 ─────────────────────────────┐
29+
│ 3 3 │
30+
│ 5 5 │
31+
│ 9 9 │
32+
│ 99 999999999999999999999999999999999 │
33+
└─────────────────────────────────────────────────────────────────────────────────────┘

‎tests/data/advanced.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"Findings - Findings below are ordered by severity (you may want to delete this line)"
2+
"id","title","description","file","evidence","severity","confidence","line"
3+
"TEST_ID","TEST","This is a test","this_file_does_not_exist","lineContent","Medium","Medium","0"
4+
"TEST_ID2","TEST2","This is a test2","this_file_does_not_exist2","3\n5\n9\n999999999999999999999999999999999","Low","High","700"

‎tests/data/advanced.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"heading": "Findings - Findings below are ordered by severity",
3+
"findings": [
4+
{
5+
"id": "TEST_ID",
6+
"title": "TEST",
7+
"description": "This is a test",
8+
"file": "this_file_does_not_exist",
9+
"evidence": [
10+
{
11+
"selected": true,
12+
"line": 0,
13+
"content": "lineContent"
14+
}
15+
],
16+
"severity": 2,
17+
"confidence": 2,
18+
"line": 0,
19+
"_other": {}
20+
},
21+
{
22+
"id": "TEST_ID2",
23+
"title": "TEST2",
24+
"description": "This is a test2",
25+
"file": "this_file_does_not_exist2",
26+
"evidence": [
27+
{
28+
"selected": false,
29+
"line": 3,
30+
"content": "3"
31+
},
32+
{
33+
"selected": true,
34+
"line": 5,
35+
"content": "5"
36+
},
37+
{
38+
"selected": true,
39+
"line": 9,
40+
"content": "9"
41+
},
42+
{
43+
"selected": true,
44+
"line": 99,
45+
"content": "999999999999999999999999999999999"
46+
}
47+
],
48+
"severity": 1,
49+
"confidence": 3,
50+
"line": 700,
51+
"_other": {}
52+
}
53+
]
54+
}

‎tests/data/advanced.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Findings
2+
Find a list of findings below ordered by severity
3+
4+
|Severity|Finding|
5+
|:--|:--|
6+
|Medium|TEST|
7+
|Low|TEST2|
8+
9+
## TEST
10+
This is a test
11+
12+
13+
File: `this_file_does_not_exist`
14+
### Severity
15+
16+
Medium (confidence: Medium)
17+
### Evidence
18+
19+
Line: 0
20+
21+
```python
22+
lineContent
23+
```
24+
## TEST2
25+
This is a test2
26+
27+
28+
File: `this_file_does_not_exist2`
29+
### Severity
30+
31+
Low (confidence: High)
32+
### Evidence
33+
34+
Line: 700
35+
36+
```python
37+
3
38+
5
39+
9
40+
999999999999999999999999999999999
41+
```

‎tests/data/advanced.sarif

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"version": "2.1.0",
3+
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
4+
"runs": [
5+
{
6+
"tool": {
7+
"driver": {
8+
"name": "SimpleSecurity",
9+
"informationUri": "https://github.com/FHPythonUtils/SimpleSecurity",
10+
"version": "2020.*"
11+
}
12+
},
13+
"results": [
14+
{
15+
"ruleId": "TEST_ID",
16+
"level": "warning",
17+
"message": {
18+
"text": "TEST: This is a test"
19+
},
20+
"locations": [
21+
{
22+
"physicalLocation": {
23+
"artifactLocation": {
24+
"uri": "this_file_does_not_exist"
25+
},
26+
"region": {
27+
"startLine": 1,
28+
"snippet": {
29+
"text": "lineContent"
30+
}
31+
},
32+
"contextRegion": {
33+
"startLine": 1,
34+
"endLine": 1,
35+
"snippet": {
36+
"text": "lineContent"
37+
}
38+
}
39+
}
40+
}
41+
]
42+
},
43+
{
44+
"ruleId": "TEST_ID2",
45+
"level": "warning",
46+
"message": {
47+
"text": "TEST2: This is a test2"
48+
},
49+
"locations": [
50+
{
51+
"physicalLocation": {
52+
"artifactLocation": {
53+
"uri": "this_file_does_not_exist2"
54+
},
55+
"region": {
56+
"startLine": 700,
57+
"snippet": {
58+
"text": "59999999999999999999999999999999999"
59+
}
60+
},
61+
"contextRegion": {
62+
"startLine": 3,
63+
"endLine": 99,
64+
"snippet": {
65+
"text": "3\n5\n9\n999999999999999999999999999999999"
66+
}
67+
}
68+
}
69+
}
70+
]
71+
}
72+
]
73+
}
74+
]
75+
}

0 commit comments

Comments
 (0)