• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 19877232762

02 Dec 2025 11:45PM UTC coverage: 69.903% (+0.05%) from 69.852%
19877232762

push

github

web-flow
#1636: improved security scoring (#1637)

3857 of 6049 branches covered (63.76%)

Branch coverage included in aggregate %.

9851 of 13561 relevant lines covered (72.64%)

3.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.41
cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolSecurity.java
1
package com.devonfw.tools.ide.url.model.file.json;
2

3
import java.io.BufferedReader;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.util.ArrayList;
7
import java.util.Collection;
8
import java.util.Collections;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.TreeMap;
12
import java.util.function.Predicate;
13

14
import com.devonfw.tools.ide.json.JsonMapping;
15
import com.devonfw.tools.ide.log.IdeLogger;
16
import com.devonfw.tools.ide.security.ToolVulnerabilities;
17
import com.devonfw.tools.ide.variable.IdeVariables;
18
import com.devonfw.tools.ide.version.VersionIdentifier;
19
import com.devonfw.tools.ide.version.VersionRange;
20
import com.fasterxml.jackson.databind.ObjectMapper;
21

22
/**
23
 * Container representing data from the "security.json" file with all {@link Cve CVE}s of a specific tool.
24
 *
25
 * @see com.devonfw.tools.ide.url.model.file.UrlSecurityFile
26
 */
27
public class ToolSecurity {
28

29
  static final String PROPERTY_ISSUES = "issues";
30

31
  private static final ObjectMapper MAPPER = JsonMapping.create();
2✔
32

33
  private static final ToolSecurity EMPTY = new ToolSecurity(Map.of());
6✔
34

35
  private final Map<String, Cve> cveMap;
36

37
  private final Collection<Cve> issues;
38

39
  /**
40
   * The constructor.
41
   */
42
  public ToolSecurity() {
43
    this(new TreeMap<>());
5✔
44
  }
1✔
45

46
  private ToolSecurity(Map<String, Cve> cveMap) {
47
    super();
2✔
48
    this.cveMap = cveMap;
3✔
49
    this.issues = Collections.unmodifiableCollection(this.cveMap.values());
6✔
50
  }
1✔
51

52
  /**
53
   * @return the {@link Collection} of {@link Cve}s.
54
   */
55
  public Collection<Cve> getIssues() {
56
    return this.issues;
3✔
57
  }
58

59
  /**
60
   * @param issues the list of CVEs
61
   */
62
  public void setIssues(List<Cve> issues) {
63

64
    this.cveMap.clear();
3✔
65
    for (Cve issue : issues) {
10✔
66
      addIssue(issue);
4✔
67
    }
1✔
68
  }
1✔
69

70
  /**
71
   * @param issue the {@link Cve} to add.
72
   * @return {@code true} if this {@link ToolSecurity} was modified (issue added or merged), {@code false} otherwise ({@link Cve} was already contained).
73
   */
74
  public boolean addIssue(Cve issue) {
75

76
    Cve newIssue = issue;
2✔
77
    String id = issue.id();
3✔
78
    Cve existingIssue = this.cveMap.get(id);
6✔
79
    if (existingIssue != null) {
2!
80
      newIssue = existingIssue.merge(issue);
×
81
      if (newIssue.equals(existingIssue)) {
×
82
        return false;
×
83
      }
84
    }
85
    this.cveMap.put(id, newIssue);
6✔
86
    return true;
2✔
87
  }
88

89
  /**
90
   * Clears all issues.
91
   */
92
  public void clearIssues() {
93
    this.cveMap.clear();
×
94
  }
×
95

96
  /**
97
   * Finds all {@link Cve}s for the given {@link VersionIdentifier} that also match the given {@link Predicate}.
98
   *
99
   * @param version the {@link VersionIdentifier} to check.
100
   * @param logger the {@link IdeLogger}.
101
   * @param predicate the {@link Predicate} deciding which matching {@link Cve}s are {@link Predicate#test(Object) accepted}.
102
   * @return all {@link Cve}s for the given {@link VersionIdentifier}.
103
   */
104
  public ToolVulnerabilities findCves(VersionIdentifier version, IdeLogger logger, Predicate<Cve> predicate) {
105
    List<Cve> cvesOfVersion = new ArrayList<>();
4✔
106
    for (Cve cve : this.issues) {
11✔
107
      for (VersionRange range : cve.versions()) {
11✔
108
        if (range.contains(version)) {
4✔
109
          if (predicate.test(cve)) {
4!
110
            cvesOfVersion.add(cve);
5✔
111
          } else {
112
            logger.info("Ignoring CVE {} with severity {}", cve.id(), cve.severity());
×
113
          }
114
        }
115
      }
1✔
116
    }
1✔
117
    return ToolVulnerabilities.of(cvesOfVersion);
3✔
118
  }
119

120
  /**
121
   * Finds all {@link Cve}s for the given {@link VersionIdentifier} and {@code minSeverity}.
122
   *
123
   * @param version the {@link VersionIdentifier} to check.
124
   * @param logger the {@link IdeLogger}.
125
   * @param minSeverity the {@link IdeVariables#CVE_MIN_SEVERITY minimum severity}.
126
   * @return the {@link ToolVulnerabilities} for the given {@link VersionIdentifier}.
127
   */
128
  public ToolVulnerabilities findCves(VersionIdentifier version, IdeLogger logger, double minSeverity) {
129
    return findCves(version, logger, cve -> cve.severity() >= minSeverity);
15!
130
  }
131

132
  /**
133
   * @param file the {@link Path} to the JSON file to load.
134
   * @return the loaded {@link ToolSecurity} or the {@link #getEmpty() empty instance} if given {@link Path} does not exist.
135
   */
136
  public static ToolSecurity of(Path file) {
137

138
    if (Files.exists(file)) {
5!
139
      try (BufferedReader reader = Files.newBufferedReader(file)) {
3✔
140
        return MAPPER.readValue(reader, ToolSecurity.class);
8✔
141
      } catch (Exception e) {
×
142
        throw new IllegalStateException("Failed to load " + file, e);
×
143
      }
144
    } else {
145
      return EMPTY;
×
146
    }
147
  }
148

149
  /**
150
   * @return the empty instance of {@link ToolSecurity}.
151
   */
152
  public static ToolSecurity getEmpty() {
153

154
    return EMPTY;
2✔
155
  }
156
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc