From 86ae6fd5e58667b04570b806c72d4c6b2b1afcb2 Mon Sep 17 00:00:00 2001 From: TLS Attacker Developer Date: Mon, 30 Jun 2025 14:26:47 +0000 Subject: [PATCH] Fix questionable cast to abstract collection in ListResult and SetResult Instead of casting the parent's collection field, store the specific collection types (List and Set) as separate fields in ListResult and SetResult respectively. This eliminates the SpotBugs BC_BAD_CAST_TO_ABSTRACT_COLLECTION warnings. The changes: - Added private final List field to ListResult - Added private final Set field to SetResult - Modified getList() and getSet() to return the stored fields instead of casting - Added comprehensive unit tests for both classes Fixes #67 --- .../scanner/core/probe/result/ListResult.java | 6 +- .../scanner/core/probe/result/SetResult.java | 6 +- .../core/probe/result/ListResultTest.java | 102 +++++++++++++++ .../core/probe/result/SetResultTest.java | 118 ++++++++++++++++++ 4 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 src/test/java/de/rub/nds/scanner/core/probe/result/ListResultTest.java create mode 100644 src/test/java/de/rub/nds/scanner/core/probe/result/SetResultTest.java diff --git a/src/main/java/de/rub/nds/scanner/core/probe/result/ListResult.java b/src/main/java/de/rub/nds/scanner/core/probe/result/ListResult.java index 816180f2..3d24c7d9 100644 --- a/src/main/java/de/rub/nds/scanner/core/probe/result/ListResult.java +++ b/src/main/java/de/rub/nds/scanner/core/probe/result/ListResult.java @@ -18,11 +18,14 @@ */ public class ListResult extends CollectionResult { + private final List list; + @SuppressWarnings("unused") // Default constructor for deserialization private ListResult() { // Default constructor for deserialization super(null, null); + this.list = null; } /** @@ -33,12 +36,13 @@ private ListResult() { */ public ListResult(AnalyzedProperty property, List list) { super(property, list); + this.list = list; } /** * @return the list of the listResult object. */ public List getList() { - return (List) collection; + return list; } } diff --git a/src/main/java/de/rub/nds/scanner/core/probe/result/SetResult.java b/src/main/java/de/rub/nds/scanner/core/probe/result/SetResult.java index 7a13ec2d..74ef2032 100644 --- a/src/main/java/de/rub/nds/scanner/core/probe/result/SetResult.java +++ b/src/main/java/de/rub/nds/scanner/core/probe/result/SetResult.java @@ -18,10 +18,13 @@ */ public class SetResult extends CollectionResult { + private final Set set; + @SuppressWarnings("unused") private SetResult() { // Default constructor for deserialization super(null, null); + this.set = null; } /** @@ -32,12 +35,13 @@ private SetResult() { */ public SetResult(AnalyzedProperty property, Set set) { super(property, set); + this.set = set; } /** * @return The set of the SetResult. */ public Set getSet() { - return (Set) collection; + return set; } } diff --git a/src/test/java/de/rub/nds/scanner/core/probe/result/ListResultTest.java b/src/test/java/de/rub/nds/scanner/core/probe/result/ListResultTest.java new file mode 100644 index 00000000..daa590ad --- /dev/null +++ b/src/test/java/de/rub/nds/scanner/core/probe/result/ListResultTest.java @@ -0,0 +1,102 @@ +/* + * Scanner Core - A Modular Framework for Probe Definition, Execution, and Result Analysis. + * + * Copyright 2017-2023 Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + */ +package de.rub.nds.scanner.core.probe.result; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; + +import de.rub.nds.scanner.core.probe.AnalyzedProperty; +import de.rub.nds.scanner.core.probe.AnalyzedPropertyCategory; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +class ListResultTest { + + @Test + void testConstructor() { + AnalyzedProperty property = new TestAnalyzedProperty(); + List testList = new ArrayList<>(); + testList.add("test1"); + testList.add("test2"); + + ListResult result = new ListResult<>(property, testList); + + assertNotNull(result); + assertEquals(property, result.getProperty()); + assertNotNull(result.getList()); + assertEquals(2, result.getList().size()); + assertEquals("test1", result.getList().get(0)); + assertEquals("test2", result.getList().get(1)); + } + + @Test + void testGetListReturnsSameInstance() { + AnalyzedProperty property = new TestAnalyzedProperty(); + List testList = new ArrayList<>(); + testList.add(1); + testList.add(2); + + ListResult result = new ListResult<>(property, testList); + + List returnedList = result.getList(); + assertSame(testList, returnedList); + } + + @Test + void testGetCollectionReturnsCorrectCollection() { + AnalyzedProperty property = new TestAnalyzedProperty(); + List testList = new ArrayList<>(); + testList.add("a"); + testList.add("b"); + + ListResult result = new ListResult<>(property, testList); + + assertEquals(testList, result.getCollection()); + } + + @Test + void testEmptyList() { + AnalyzedProperty property = new TestAnalyzedProperty(); + List emptyList = new ArrayList<>(); + + ListResult result = new ListResult<>(property, emptyList); + + assertNotNull(result.getList()); + assertEquals(0, result.getList().size()); + } + + @Test + void testNullList() { + AnalyzedProperty property = new TestAnalyzedProperty(); + + ListResult result = new ListResult<>(property, null); + + assertNull(result.getList()); + assertNull(result.getCollection()); + } + + // Test implementation of AnalyzedProperty for testing + private static class TestAnalyzedProperty implements AnalyzedProperty { + @Override + public String getName() { + return "TestProperty"; + } + + @Override + public AnalyzedPropertyCategory getCategory() { + return new TestAnalyzedPropertyCategory(); + } + } + + // Test implementation of AnalyzedPropertyCategory for testing + private static class TestAnalyzedPropertyCategory implements AnalyzedPropertyCategory {} +} diff --git a/src/test/java/de/rub/nds/scanner/core/probe/result/SetResultTest.java b/src/test/java/de/rub/nds/scanner/core/probe/result/SetResultTest.java new file mode 100644 index 00000000..8aaf5b35 --- /dev/null +++ b/src/test/java/de/rub/nds/scanner/core/probe/result/SetResultTest.java @@ -0,0 +1,118 @@ +/* + * Scanner Core - A Modular Framework for Probe Definition, Execution, and Result Analysis. + * + * Copyright 2017-2023 Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + */ +package de.rub.nds.scanner.core.probe.result; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import de.rub.nds.scanner.core.probe.AnalyzedProperty; +import de.rub.nds.scanner.core.probe.AnalyzedPropertyCategory; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class SetResultTest { + + @Test + void testConstructor() { + AnalyzedProperty property = new TestAnalyzedProperty(); + Set testSet = new HashSet<>(); + testSet.add("test1"); + testSet.add("test2"); + + SetResult result = new SetResult<>(property, testSet); + + assertNotNull(result); + assertEquals(property, result.getProperty()); + assertNotNull(result.getSet()); + assertEquals(2, result.getSet().size()); + assertTrue(result.getSet().contains("test1")); + assertTrue(result.getSet().contains("test2")); + } + + @Test + void testGetSetReturnsSameInstance() { + AnalyzedProperty property = new TestAnalyzedProperty(); + Set testSet = new HashSet<>(); + testSet.add(1); + testSet.add(2); + + SetResult result = new SetResult<>(property, testSet); + + Set returnedSet = result.getSet(); + assertSame(testSet, returnedSet); + } + + @Test + void testGetCollectionReturnsCorrectCollection() { + AnalyzedProperty property = new TestAnalyzedProperty(); + Set testSet = new HashSet<>(); + testSet.add("a"); + testSet.add("b"); + + SetResult result = new SetResult<>(property, testSet); + + assertEquals(testSet, result.getCollection()); + } + + @Test + void testEmptySet() { + AnalyzedProperty property = new TestAnalyzedProperty(); + Set emptySet = new HashSet<>(); + + SetResult result = new SetResult<>(property, emptySet); + + assertNotNull(result.getSet()); + assertEquals(0, result.getSet().size()); + } + + @Test + void testNullSet() { + AnalyzedProperty property = new TestAnalyzedProperty(); + + SetResult result = new SetResult<>(property, null); + + assertNull(result.getSet()); + assertNull(result.getCollection()); + } + + @Test + void testSetUniqueness() { + AnalyzedProperty property = new TestAnalyzedProperty(); + Set testSet = new HashSet<>(); + testSet.add("duplicate"); + testSet.add("duplicate"); + testSet.add("unique"); + + SetResult result = new SetResult<>(property, testSet); + + assertEquals(2, result.getSet().size()); + assertTrue(result.getSet().contains("duplicate")); + assertTrue(result.getSet().contains("unique")); + } + + // Test implementation of AnalyzedProperty for testing + private static class TestAnalyzedProperty implements AnalyzedProperty { + @Override + public String getName() { + return "TestProperty"; + } + + @Override + public AnalyzedPropertyCategory getCategory() { + return new TestAnalyzedPropertyCategory(); + } + } + + // Test implementation of AnalyzedPropertyCategory for testing + private static class TestAnalyzedPropertyCategory implements AnalyzedPropertyCategory {} +}