Add 88 new defect entries to HIGH and MEDIUM tables:
HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002
MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
ovs-0001, onos-0003, odl-0002, jetty-0001
PDF: 976K
120 lines
4.1 KiB
Java
120 lines
4.1 KiB
Java
package unit;
|
|
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* RaylibGlyphIndexTest — CWE-407 raylib-0001
|
|
*
|
|
* Models GetGlyphIndex(Font font, int codepoint):
|
|
* slow() = O(n) linear scan of glyphs array (current defect)
|
|
* fast() = O(log n) binary search on sorted glyphs array (patch)
|
|
*
|
|
* Assert: slowOps > fastOps * Nx at N=2048 glyphs.
|
|
*/
|
|
public class RaylibGlyphIndexTest {
|
|
|
|
// Simulates font.glyphs[i].value — codepoint stored per glyph slot
|
|
static int[] buildGlyphs(int n) {
|
|
int[] glyphs = new int[n];
|
|
// Mimic a Unicode font: codepoints spread across BMP
|
|
// Start at 0x20 (space), stride by 1 — typical Latin+extended range
|
|
for (int i = 0; i < n; i++) {
|
|
glyphs[i] = 0x20 + i;
|
|
}
|
|
return glyphs;
|
|
}
|
|
|
|
static long linearOps;
|
|
static long binaryOps;
|
|
|
|
/**
|
|
* slow: O(n) linear scan — exact translation of raylib GetGlyphIndex
|
|
* SUPPORT_UNORDERED_CHARSET branch.
|
|
*/
|
|
static int getGlyphIndexSlow(int[] glyphs, int codepoint) {
|
|
int index = 0;
|
|
int fallbackIndex = 0;
|
|
for (int i = 0; i < glyphs.length; i++) {
|
|
linearOps++;
|
|
if (glyphs[i] == 63) fallbackIndex = i; // '?' fallback
|
|
if (glyphs[i] == codepoint) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
if (index == 0 && glyphs[0] != codepoint) index = fallbackIndex;
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* fast: O(log n) binary search — patch approach, requires sorted glyphs.
|
|
*/
|
|
static int getGlyphIndexFast(int[] glyphs, int codepoint) {
|
|
int lo = 0, hi = glyphs.length - 1;
|
|
while (lo <= hi) {
|
|
binaryOps++;
|
|
int mid = lo + (hi - lo) / 2;
|
|
if (glyphs[mid] == codepoint) return mid;
|
|
else if (glyphs[mid] < codepoint) lo = mid + 1;
|
|
else hi = mid - 1;
|
|
}
|
|
// Fallback to '?' (codepoint 63) — also binary search
|
|
return getGlyphIndexFast(glyphs, 63);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
final int N = 2048; // font.glyphCount
|
|
final int NX = 10; // minimum required speedup factor
|
|
final int TRIALS = 1000; // number of lookups to accumulate ops
|
|
|
|
int[] glyphs = buildGlyphs(N);
|
|
// Sorted by construction — binary search is valid
|
|
|
|
// Worst-case codepoint: the last glyph (maximizes linear scan ops)
|
|
int worstCaseCodepoint = glyphs[N - 1];
|
|
|
|
linearOps = 0;
|
|
binaryOps = 0;
|
|
|
|
for (int t = 0; t < TRIALS; t++) {
|
|
getGlyphIndexSlow(glyphs, worstCaseCodepoint);
|
|
}
|
|
long slowOps = linearOps;
|
|
|
|
for (int t = 0; t < TRIALS; t++) {
|
|
getGlyphIndexFast(glyphs, worstCaseCodepoint);
|
|
}
|
|
long fastOps = binaryOps;
|
|
|
|
// Correctness check
|
|
int slowIdx = getGlyphIndexSlow(glyphs, worstCaseCodepoint);
|
|
int fastIdx = getGlyphIndexFast(glyphs, worstCaseCodepoint);
|
|
|
|
boolean correctnessOk = (slowIdx == fastIdx);
|
|
boolean speedupOk = slowOps > fastOps * NX;
|
|
|
|
System.out.printf("N=%d glyphs, worst-case codepoint=0x%X%n", N, worstCaseCodepoint);
|
|
System.out.printf("slow (linear) ops over %d trials: %d%n", TRIALS, slowOps);
|
|
System.out.printf("fast (binary) ops over %d trials: %d%n", TRIALS, fastOps);
|
|
System.out.printf("speedup ratio: %.1fx (required >%dx)%n",
|
|
(double) slowOps / fastOps, NX);
|
|
System.out.printf("index match: slow=%d fast=%d%n", slowIdx, fastIdx);
|
|
|
|
int passed = 0, total = 2;
|
|
if (correctnessOk) {
|
|
System.out.println("1/2 PASS correctness: slow and fast return same index");
|
|
passed++;
|
|
} else {
|
|
System.out.printf("1/2 FAIL correctness: slow=%d fast=%d%n", slowIdx, fastIdx);
|
|
}
|
|
if (speedupOk) {
|
|
System.out.printf("2/2 PASS speedup: %d > %d * %d%n", slowOps, fastOps, NX);
|
|
passed++;
|
|
} else {
|
|
System.out.printf("2/2 FAIL speedup: %d not > %d * %d%n", slowOps, fastOps, NX);
|
|
}
|
|
|
|
System.out.printf("%d/%d PASS%n", passed, total);
|
|
if (passed < total) System.exit(1);
|
|
}
|
|
}
|