package unit; import java.util.*; /** * JuliaTest — CWE-407 benchmark for julia-0001 * * Models isrelocatable() O(N²) Vector membership test in includes loop * vs. O(N) HashSet-based check. * * Real code (base/loading.jl ~2102): * for inc in includes # outer O(n) * if inc āˆ‰ includes_srcfiles # inner O(n) Vector linear scan * * Fix: srcfiles_set = Set{CacheHeaderIncludes}(includes_srcfiles) → O(1) lookup. */ public class JuliaTest { static void bench(String label, Runnable slow, Runnable fast, long sOps, long fOps) { slow.run(); fast.run(); long t0 = System.nanoTime(); slow.run(); long sMs = (System.nanoTime() - t0) / 1_000_000; long t1 = System.nanoTime(); fast.run(); long fMs = (System.nanoTime() - t1) / 1_000_000; double speedup = fMs > 0 ? (double) sMs / fMs : 0; System.out.printf(" %-54s slow:%4dms (%,d ops) fast:%4dms (%,d ops) speedup:%.0fx%n", label, sMs, sOps, fMs, fOps, speedup); } static long slowIsRelocatable(int N) { List includes = new ArrayList<>(N); List srcfiles = new ArrayList<>(N / 2); for (int i = 0; i < N; i++) includes.add(i); for (int i = 0; i < N / 2; i++) srcfiles.add(i * 2); long ops = 0; for (Integer inc : includes) { for (Integer sf : srcfiles) { ops++; if (sf.equals(inc)) break; } } return ops; } static long fastIsRelocatable(int N) { List includes = new ArrayList<>(N); Set srcfileSet = new HashSet<>(N); for (int i = 0; i < N; i++) includes.add(i); for (int i = 0; i < N / 2; i++) srcfileSet.add(i * 2); long ops = 0; for (Integer inc : includes) { ops++; srcfileSet.contains(inc); } return ops; } public static void main(String[] args) { System.out.println("JuliaTest -- julia-0001: isrelocatable() includes_srcfiles Vector scan -> HashSet"); System.out.println(); System.out.println(" [isrelocatable-includes: base/loading.jl ~2102]"); int[][] cases = {{200, 10000}, {500, 5000}, {1000, 2000}}; for (int[] c : cases) { int N = c[0], R = c[1]; bench( String.format("N=%d includes, %,d isrelocatable() calls", N, R), () -> { for (int i = 0; i < R; i++) slowIsRelocatable(N); }, () -> { for (int i = 0; i < R; i++) fastIsRelocatable(N); }, (long) N * (N / 2) * R, (long) N * R ); } System.out.println(); System.out.println("Defect : base/loading.jl ~2102 -- 'inc not in includes_srcfiles' Vector O(n) scan"); System.out.println("Fix : srcfiles_set = Set{CacheHeaderIncludes}(includes_srcfiles) -- O(1) check"); System.out.println("Ticket : julia-0001-isrelocatable-includes-vector-linear-scan.md"); System.out.println(); int pass = 0; long s0 = slowIsRelocatable(1000), f0 = fastIsRelocatable(1000); assert s0 > f0 * 50 : "julia-0001 expected >50x; slow=" + s0 + " fast=" + f0; pass++; System.out.printf("%d/1 PASS -- julia-0001: CWE-407 in Julia isrelocatable() package validation%n", pass); System.out.printf("Hotpath: called for every package during precompile validation%n"); } }