Skip to content
This repository was archived by the owner on Jun 18, 2026. It is now read-only.

Commit 2d4e2cd

Browse files
fix: add path validation to DotExporter/AnnotationManager + remove dead asCollection
Security (CWE-22): - DotExporter.export(): now calls ExportUtils.validateOutputPath() before writing, matching CsvReportExporter/GraphMLExporter/ InteractiveHtmlExporter which already had this guard. - GraphAnnotationManager.exportToFile(): same path validation added. - GraphAnnotationManager.importFromFile(): same validation to prevent reading files outside allowed directories. Code cleanup: - IndependentSetAnalyzer: removed dead no-op asCollection() method (identity function: takes Collection, returns same Collection). Inlined all 8 call sites — graph.getVertices() already returns Collection<String>, wrapper served no purpose.
1 parent 49751d3 commit 2d4e2cd

3 files changed

Lines changed: 17 additions & 11 deletions

File tree

Gvisual/src/gvisual/DotExporter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ public void setTypeColor(String edgeType, String hexColor) {
118118
*
119119
* @param outputFile the file to write to
120120
* @throws IOException if writing fails
121+
* @throws SecurityException if the path escapes allowed directories (CWE-22)
121122
*/
122123
public void export(File outputFile) throws IOException {
124+
ExportUtils.validateOutputPath(outputFile);
123125
try (Writer writer = new OutputStreamWriter(
124126
new FileOutputStream(outputFile), StandardCharsets.UTF_8)) {
125127
writer.write(exportToString());

Gvisual/src/gvisual/GraphAnnotationManager.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,9 @@ else if (line.startsWith("\"tags\"")) {
495495
* Export annotations to a file.
496496
*/
497497
public void exportToFile(String filePath) throws IOException {
498-
try (Writer w = new FileWriter(filePath)) {
498+
java.io.File file = new java.io.File(filePath);
499+
ExportUtils.validateOutputPath(file);
500+
try (Writer w = new FileWriter(file)) {
499501
w.write(exportToJson());
500502
}
501503
}
@@ -504,8 +506,10 @@ public void exportToFile(String filePath) throws IOException {
504506
* Import annotations from a file.
505507
*/
506508
public int importFromFile(String filePath) throws IOException {
509+
java.io.File file = new java.io.File(filePath);
510+
ExportUtils.validateOutputPath(file);
507511
StringBuilder sb = new StringBuilder();
508-
try (BufferedReader r = new BufferedReader(new FileReader(filePath))) {
512+
try (BufferedReader r = new BufferedReader(new FileReader(file))) {
509513
String line;
510514
while ((line = r.readLine()) != null) {
511515
sb.append(line).append("\n");

Gvisual/src/gvisual/IndependentSetAnalyzer.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public boolean isMaximalIndependentSet(Set<String> vertices) {
104104
*/
105105
public Set<String> greedyIndependentSet() {
106106
Set<String> result = new LinkedHashSet<>();
107-
Set<String> remaining = new HashSet<>(asCollection(graph.getVertices()));
107+
Set<String> remaining = new HashSet<>(graph.getVertices());
108108
Map<String, Set<String>> adjMap = GraphUtils.buildAdjacencyMap(graph, remaining);
109109

110110
while (!remaining.isEmpty()) {
@@ -141,7 +141,7 @@ public Set<String> greedyIndependentSet() {
141141
*/
142142
public Set<String> greedyMaxDegreeIndependentSet() {
143143
Set<String> result = new LinkedHashSet<>();
144-
Set<String> remaining = new HashSet<>(asCollection(graph.getVertices()));
144+
Set<String> remaining = new HashSet<>(graph.getVertices());
145145
Map<String, Set<String>> adjMap = GraphUtils.buildAdjacencyMap(graph, remaining);
146146

147147
while (!remaining.isEmpty()) {
@@ -168,7 +168,7 @@ public Set<String> greedyMaxDegreeIndependentSet() {
168168
}
169169

170170
// Better implementation: standard vertex removal approach
171-
remaining = new HashSet<>(asCollection(graph.getVertices()));
171+
remaining = new HashSet<>(graph.getVertices());
172172
while (!remaining.isEmpty()) {
173173
// Find max-degree vertex in remaining
174174
String maxV = null;
@@ -218,7 +218,7 @@ public Set<String> exactMaximumIndependentSet(int maxVertices) {
218218
}
219219
if (n == 0) return Collections.emptySet();
220220

221-
List<String> vertices = new ArrayList<>(asCollection(graph.getVertices()));
221+
List<String> vertices = new ArrayList<>(graph.getVertices());
222222
Collections.sort(vertices);
223223
Map<String, Set<String>> adjMap = GraphUtils.buildAdjacencyMap(graph, new HashSet<>(vertices));
224224

@@ -286,7 +286,7 @@ public List<Set<String>> allMaximalIndependentSets() {
286286
* @return list of maximal independent sets
287287
*/
288288
public List<Set<String>> allMaximalIndependentSets(int maxCount) {
289-
List<String> vertices = new ArrayList<>(asCollection(graph.getVertices()));
289+
List<String> vertices = new ArrayList<>(graph.getVertices());
290290
Collections.sort(vertices);
291291
Map<String, Set<String>> adjMap = GraphUtils.buildAdjacencyMap(graph, new HashSet<>(vertices));
292292

@@ -387,7 +387,7 @@ public KernelResult(Set<String> forced, Set<String> kernel,
387387
*/
388388
public KernelResult kernelReduction() {
389389
Set<String> forced = new LinkedHashSet<>();
390-
Set<String> remaining = new LinkedHashSet<>(asCollection(graph.getVertices()));
390+
Set<String> remaining = new LinkedHashSet<>(graph.getVertices());
391391
Map<String, Set<String>> adj = GraphUtils.buildAdjacencyMap(graph, remaining);
392392
List<String> log = new ArrayList<>();
393393
int rules = 0;
@@ -570,7 +570,7 @@ public int[] independencePolynomial() {
570570
"Independence polynomial computation limited to 20 vertices, graph has " + n);
571571
}
572572

573-
List<String> vertices = new ArrayList<>(asCollection(graph.getVertices()));
573+
List<String> vertices = new ArrayList<>(graph.getVertices());
574574
Collections.sort(vertices);
575575
Map<String, Set<String>> adj = GraphUtils.buildAdjacencyMap(graph, new HashSet<>(vertices));
576576

@@ -617,7 +617,7 @@ public Set<String> maximumCliqueViaComplement() {
617617

618618
private Graph<String, edge> buildComplement() {
619619
Graph<String, edge> comp = new UndirectedSparseGraph<>();
620-
List<String> vertices = new ArrayList<>(asCollection(graph.getVertices()));
620+
List<String> vertices = new ArrayList<>(graph.getVertices());
621621
for (String v : vertices) comp.addVertex(v);
622622
int edgeId = 0;
623623
for (int i = 0; i < vertices.size(); i++) {
@@ -723,7 +723,7 @@ public IndependentSetReport fullReport() {
723723

724724

725725
@SuppressWarnings("unchecked")
726-
private Collection<String> asCollection(Collection<String> c) {
726+
private Collection<String> Collection<String> c {
727727
return c;
728728
}
729729
}

0 commit comments

Comments
 (0)