java-topology/defects/wireshark/unit/WiresharkTest.java
russell@unturf.com 59ae52c7b4 wave16: nova/keystone/crystal/dovecot/wireshark CWE-407 patches + unit tests
nova-0001: scheduler/manager.py selected_hosts list → set (273x, CRITICAL)
nova-0002: scheduler/host_manager.py lowered_hosts_to_force list → set (43x, HIGH)
keystone-0001: api/users.py token_roles list → set (32x, HIGH)
crystal-0001: syntax/parser.cr type_vars Array#includes? → Set (25x, CRITICAL)
crystal-0002: semantic/restrictions.cr discarded Array#includes? → Set (5x, CRITICAL)
dovecot-0001: mail-storage-hooks.c array_lsearch → sort+bsearch (4x, HIGH)
wireshark-0001: proto_data.c GSList → wmem_map_t (8x, HIGH)

7 unit tests: 9/9 PASS
2026-03-30 07:33:49 -04:00

107 lines
4.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import java.util.*;
/**
* CWE-407 unit test for wireshark defect.
*
* wireshark-0001: proto_data.c — per-packet proto data GSList O(N) lookup
* p_set_proto_data / p_get_proto_data / p_remove_proto_data each do
* g_slist_find_custom(pinfo->proto_data, ...) — O(N) scan over all
* per-packet protocol data entries. Called repeatedly per dissector layer.
*
* Fix: replace GSList with wmem_map_t keyed by (proto<<32 | key) → O(1).
*/
public class WiresharkTest {
// Simulate GSList-based proto_data (defect)
static class ProtoDataList {
private final List<long[]> entries = new ArrayList<>(); // [proto, key, data_id]
void set(int proto, long key, long data) {
long compKey = ((long) proto << 32) | (key & 0xFFFFFFFFL);
for (long[] e : entries) { // O(N) scan
if (e[0] == compKey) { e[1] = data; return; }
}
entries.add(new long[]{compKey, data});
}
long get(int proto, long key) {
long compKey = ((long) proto << 32) | (key & 0xFFFFFFFFL);
for (long[] e : entries) { // O(N) scan
if (e[0] == compKey) return e[1];
}
return -1;
}
}
// Simulate wmem_map_t-based proto_data (fix)
static class ProtoDataMap {
private final Map<Long, Long> map = new HashMap<>();
void set(int proto, long key, long data) {
map.put(((long) proto << 32) | (key & 0xFFFFFFFFL), data);
}
long get(int proto, long key) {
Long v = map.get(((long) proto << 32) | (key & 0xFFFFFFFFL));
return v != null ? v : -1;
}
}
static void testWireshark0001() throws Exception {
int N = 300; // dissector layers per packet (complex capture)
int PROTOS = 50;
Random rng = new Random(42);
// build test data: N (proto, key, value) tuples
int[][] queries = new int[N][2];
for (int i = 0; i < N; i++) {
queries[i][0] = rng.nextInt(PROTOS);
queries[i][1] = rng.nextInt(1000);
}
// correctness: both implementations return same values after inserts
ProtoDataList plist = new ProtoDataList();
ProtoDataMap pmap = new ProtoDataMap();
for (int i = 0; i < N; i++) {
plist.set(queries[i][0], queries[i][1], i);
pmap.set(queries[i][0], queries[i][1], i);
}
for (int i = 0; i < N; i++) {
long vlist = plist.get(queries[i][0], queries[i][1]);
long vmap = pmap.get(queries[i][0], queries[i][1]);
assert vlist == vmap : "mismatch at " + i + ": " + vlist + " vs " + vmap;
}
// performance: simulate per-packet dissection — build once, many repeated lookups
// (dissectors call p_get_proto_data repeatedly on the same pinfo per packet)
long t0 = System.nanoTime();
for (int pkt = 0; pkt < 200; pkt++) {
ProtoDataList pd = new ProtoDataList();
for (int i = 0; i < N; i++) pd.set(queries[i][0], queries[i][1], i);
// simulate many get calls on a fully-populated list (N entries → each get is O(N/2))
for (int rep = 0; rep < 50; rep++)
for (int i = 0; i < N; i++) pd.get(queries[i][0], queries[i][1]);
}
long tList = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int pkt = 0; pkt < 200; pkt++) {
ProtoDataMap pd = new ProtoDataMap();
for (int i = 0; i < N; i++) pd.set(queries[i][0], queries[i][1], i);
for (int rep = 0; rep < 50; rep++)
for (int i = 0; i < N; i++) pd.get(queries[i][0], queries[i][1]);
}
long tMap = System.nanoTime() - t0;
double ratio = (double) tList / tMap;
System.out.printf("wireshark-0001: list=%.3fs map=%.3fs ratio=%.1f×%n",
tList / 1e9, tMap / 1e9, ratio);
assert ratio > 5 : "Expected >5× speedup, got " + ratio;
System.out.println("PASS wireshark-0001");
}
public static void main(String[] args) throws Exception {
testWireshark0001();
System.out.println("ALL PASS");
}
}