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
137 lines
4.8 KiB
Java
137 lines
4.8 KiB
Java
import java.util.*;
|
||
|
||
/**
|
||
* CWE-407 unit tests for Crystal compiler defects.
|
||
*
|
||
* crystal-0001: parser.cr parse_type_vars — type_vars Array#includes? O(N²)
|
||
* while parsing type params: type_vars.includes?(name) in inner loop
|
||
* Fix: parallel Set for O(1) duplicate detection
|
||
*
|
||
* crystal-0002: restrictions.cr union restrict — discarded Array#includes? O(T×O)
|
||
* nested loop: other_types × union_types, discarded.includes?(type) per iteration
|
||
* Fix: discarded = Set(Type).new
|
||
*/
|
||
public class CrystalTest {
|
||
|
||
// --- crystal-0001: type_vars includes? ---
|
||
|
||
static List<String> parseTypeVarsList(List<String> input) {
|
||
List<String> typeVars = new ArrayList<>();
|
||
for (String name : input) {
|
||
if (typeVars.contains(name)) { // O(N) — defect
|
||
throw new IllegalArgumentException("duplicated: " + name);
|
||
}
|
||
typeVars.add(name);
|
||
}
|
||
return typeVars;
|
||
}
|
||
|
||
static List<String> parseTypeVarsSet(List<String> input) {
|
||
List<String> typeVars = new ArrayList<>();
|
||
Set<String> seen = new HashSet<>(); // O(1) — fix
|
||
for (String name : input) {
|
||
if (seen.contains(name)) {
|
||
throw new IllegalArgumentException("duplicated: " + name);
|
||
}
|
||
typeVars.add(name);
|
||
seen.add(name);
|
||
}
|
||
return typeVars;
|
||
}
|
||
|
||
static void testCrystal0001() throws Exception {
|
||
int N = 3000;
|
||
List<String> typeParams = new ArrayList<>();
|
||
for (int i = 0; i < N; i++) typeParams.add("T" + i);
|
||
|
||
// correctness
|
||
List<String> r1 = parseTypeVarsList(typeParams);
|
||
List<String> r2 = parseTypeVarsSet(typeParams);
|
||
assert r1.equals(r2) : "list and set paths must agree";
|
||
|
||
// duplicate detection
|
||
List<String> withDup = new ArrayList<>(typeParams);
|
||
withDup.add("T0");
|
||
boolean threwList = false, threwSet = false;
|
||
try { parseTypeVarsList(withDup); } catch (IllegalArgumentException e) { threwList = true; }
|
||
try { parseTypeVarsSet(withDup); } catch (IllegalArgumentException e) { threwSet = true; }
|
||
assert threwList && threwSet : "both must detect duplicate";
|
||
|
||
// performance
|
||
long t0 = System.nanoTime();
|
||
for (int r = 0; r < 200; r++) parseTypeVarsList(typeParams);
|
||
long tList = System.nanoTime() - t0;
|
||
|
||
t0 = System.nanoTime();
|
||
for (int r = 0; r < 200; r++) parseTypeVarsSet(typeParams);
|
||
long tSet = System.nanoTime() - t0;
|
||
|
||
double ratio = (double) tList / tSet;
|
||
System.out.printf("crystal-0001: list=%.3fs set=%.3fs ratio=%.1f×%n",
|
||
tList / 1e9, tSet / 1e9, ratio);
|
||
assert ratio > 10 : "Expected >10× speedup, got " + ratio;
|
||
System.out.println("PASS crystal-0001");
|
||
}
|
||
|
||
// --- crystal-0002: discarded includes? in union restrict loop ---
|
||
|
||
static int restrictUnionList(int otherCount, int unionCount) {
|
||
List<Integer> discarded = new ArrayList<>();
|
||
int matched = 0;
|
||
for (int o = 0; o < otherCount; o++) {
|
||
for (int u = 0; u < unionCount; u++) {
|
||
if (discarded.contains(u)) continue; // O(D) — defect
|
||
if (u % (o + 1) == 0) {
|
||
matched++;
|
||
discarded.add(u);
|
||
}
|
||
}
|
||
}
|
||
return matched;
|
||
}
|
||
|
||
static int restrictUnionSet(int otherCount, int unionCount) {
|
||
Set<Integer> discarded = new HashSet<>();
|
||
int matched = 0;
|
||
for (int o = 0; o < otherCount; o++) {
|
||
for (int u = 0; u < unionCount; u++) {
|
||
if (discarded.contains(u)) continue; // O(1) — fix
|
||
if (u % (o + 1) == 0) {
|
||
matched++;
|
||
discarded.add(u);
|
||
}
|
||
}
|
||
}
|
||
return matched;
|
||
}
|
||
|
||
static void testCrystal0002() throws Exception {
|
||
int O = 60, U = 200;
|
||
|
||
// correctness
|
||
int r1 = restrictUnionList(O, U);
|
||
int r2 = restrictUnionSet(O, U);
|
||
assert r1 == r2 : "list and set must match: " + r1 + " vs " + r2;
|
||
|
||
// performance
|
||
long t0 = System.nanoTime();
|
||
for (int r = 0; r < 200; r++) restrictUnionList(O, U);
|
||
long tList = System.nanoTime() - t0;
|
||
|
||
t0 = System.nanoTime();
|
||
for (int r = 0; r < 200; r++) restrictUnionSet(O, U);
|
||
long tSet = System.nanoTime() - t0;
|
||
|
||
double ratio = (double) tList / tSet;
|
||
System.out.printf("crystal-0002: list=%.3fs set=%.3fs ratio=%.1f×%n",
|
||
tList / 1e9, tSet / 1e9, ratio);
|
||
assert ratio > 3 : "Expected >3× speedup, got " + ratio;
|
||
System.out.println("PASS crystal-0002");
|
||
}
|
||
|
||
public static void main(String[] args) throws Exception {
|
||
testCrystal0001();
|
||
testCrystal0002();
|
||
System.out.println("ALL PASS");
|
||
}
|
||
}
|