From ca276dc879738664910d61650dda715e177da7cd Mon Sep 17 00:00:00 2001 From: Matthias Jaros Date: Tue, 11 Aug 2026 16:07:59 +0200 Subject: Boundaries: Added PortList class to encapsulate BitSet and thus have a clear boundary to the outside world that uses the result --- src/main/java/com/it_jaros/jscanner/PortList.java | 27 ++++++++++++++++++++++ .../java/com/it_jaros/jscanner/ProgressBar.java | 14 +++++------ .../java/com/it_jaros/jscanner/ScanResult.java | 13 +++++++---- src/main/java/com/it_jaros/jscanner/Scanner.java | 8 ++++++- 4 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/it_jaros/jscanner/PortList.java (limited to 'src/main') diff --git a/src/main/java/com/it_jaros/jscanner/PortList.java b/src/main/java/com/it_jaros/jscanner/PortList.java new file mode 100644 index 0000000..574d3eb --- /dev/null +++ b/src/main/java/com/it_jaros/jscanner/PortList.java @@ -0,0 +1,27 @@ +package com.it_jaros.jscanner; + +import java.util.BitSet; +import java.util.List; + +/** + * Encapsulates a port scan result and is immutable + */ +public class PortList { + private final BitSet ports; + + public PortList(BitSet ports) { + this.ports = ports; + } + + public List getPorts() { + return ports.stream().boxed().toList(); + } + + public boolean isEmpty() { + return ports.isEmpty(); + } + + public int size() { + return ports.cardinality(); + } +} diff --git a/src/main/java/com/it_jaros/jscanner/ProgressBar.java b/src/main/java/com/it_jaros/jscanner/ProgressBar.java index 795c9bb..3a38069 100644 --- a/src/main/java/com/it_jaros/jscanner/ProgressBar.java +++ b/src/main/java/com/it_jaros/jscanner/ProgressBar.java @@ -2,7 +2,7 @@ package com.it_jaros.jscanner; import java.io.BufferedReader; import java.io.InputStreamReader; -import java.util.BitSet; +import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -75,12 +75,12 @@ public class ProgressBar { sb.append("\n"); if (!result.openPorts().isEmpty()) { sb.append( - String.format("\t (%d) open:\t%s%n", result.openPorts().cardinality(), map(result.openPorts(), result.bannerRecognition())) + String.format("\t (%d) open:\t%s%n", result.openPorts().size(), map(result.openPorts().getPorts(), result.bannerRecognition())) ); } if (showFilteredPorts && !result.filteredPorts().isEmpty()) { sb.append( - String.format("\t (%d) filtered:\t%s%n", result.filteredPorts().cardinality(), map(result.filteredPorts())) + String.format("\t (%d) filtered:\t%s%n", result.filteredPorts().size(), map(result.filteredPorts().getPorts())) ); } sb.append("\n"); @@ -88,12 +88,12 @@ public class ProgressBar { System.out.flush(); } - private static String map(BitSet ports) { - return ports.stream().mapToObj(String::valueOf).collect(Collectors.joining(",")); + private static String map(List ports) { + return ports.stream().map(String::valueOf).collect(Collectors.joining(",")); } - private static String map(BitSet ports, Map bannerRecognition) { - return ports.stream().mapToObj(port -> { + private static String map(List ports, Map bannerRecognition) { + return ports.stream().map(port -> { ServiceType serviceType = bannerRecognition.getOrDefault(port, ServiceType.UNKNOWN); if (serviceType == ServiceType.UNKNOWN) { diff --git a/src/main/java/com/it_jaros/jscanner/ScanResult.java b/src/main/java/com/it_jaros/jscanner/ScanResult.java index 85d9a36..3eb4d0d 100644 --- a/src/main/java/com/it_jaros/jscanner/ScanResult.java +++ b/src/main/java/com/it_jaros/jscanner/ScanResult.java @@ -1,19 +1,22 @@ package com.it_jaros.jscanner; -import java.util.*; +import java.util.BitSet; +import java.util.Collections; +import java.util.List; +import java.util.Map; public record ScanResult( String host, - BitSet openPorts, - BitSet filteredPorts, + PortList openPorts, + PortList filteredPorts, Map bannerRecognition, List errors ) { public static ScanResult empty(String host) { return new ScanResult( host, - new BitSet(PortRange.MAX_PORT), - new BitSet(PortRange.MAX_PORT), + new PortList(new BitSet(PortRange.MAX_PORT)), + new PortList(new BitSet(PortRange.MAX_PORT)), Collections.emptyMap(), Collections.emptyList() ); diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java index fdd011e..7f6b743 100644 --- a/src/main/java/com/it_jaros/jscanner/Scanner.java +++ b/src/main/java/com/it_jaros/jscanner/Scanner.java @@ -464,7 +464,13 @@ public class Scanner implements AutoCloseable { } ScanResult build() { - return new ScanResult(host, openPorts, filteredPorts, Collections.unmodifiableMap(serviceTypes), Collections.unmodifiableList(scanFailures)); + return new ScanResult( + host, + new PortList(openPorts), + new PortList(filteredPorts), + Collections.unmodifiableMap(serviceTypes), + Collections.unmodifiableList(scanFailures) + ); } } } -- cgit v1.3.1