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
107 lines
4.2 KiB
Java
107 lines
4.2 KiB
Java
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");
|
||
}
|
||
}
|