whitepaper: 312 sites / 151 ecosystems — wave2+3 defect tables and PDF rebuild
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
This commit is contained in:
parent
b3842ab6b8
commit
9934133dcf
260 changed files with 18278 additions and 15 deletions
151
defects/tidb/unit/TiDBTest.java
Normal file
151
defects/tidb/unit/TiDBTest.java
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
package unit;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* TiDB CWE-407 unit tests — standalone, no JUnit.
|
||||
*
|
||||
* tidb-0001 getEnforcedMergeJoin / getNewJoinKeys offsets slices.Contains
|
||||
* pkg/planner/core/operator/physicalop/physical_merge_join.go:173,513,527
|
||||
*
|
||||
* tidb-0002 mergeInAndNotEQLists removeValues slices.Contains
|
||||
* pkg/planner/core/rule/rule_predicate_simplification.go:267
|
||||
*/
|
||||
public class TiDBTest {
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// tidb-0001: getNewJoinKeysByOffsets — slices.Contains vs map lookup
|
||||
//
|
||||
// Models: given N join keys and K offsets (already-placed keys), iterate
|
||||
// all N keys and skip those whose position is in offsets.
|
||||
// Slow: slices.Contains — O(K) per key, O(N*K) total.
|
||||
// Fast: map/set — O(1) per key, O(N) total.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/** Slow: scan offsets slice for every key position. Returns op count. */
|
||||
static long mergeJoinSlowOps(int numJoinKeys, int numOffsets) {
|
||||
List<Integer> offsets = new ArrayList<>();
|
||||
Random rng = new Random(7);
|
||||
Set<Integer> added = new HashSet<>();
|
||||
while (offsets.size() < numOffsets) {
|
||||
int o = rng.nextInt(numJoinKeys);
|
||||
if (added.add(o)) offsets.add(o);
|
||||
}
|
||||
|
||||
long ops = 0;
|
||||
// getNewJoinKeysByOffsets inner loop: for each pos, scan offsets
|
||||
for (int pos = 0; pos < numJoinKeys; pos++) {
|
||||
for (int i = 0; i < offsets.size(); i++) {
|
||||
ops++;
|
||||
if (offsets.get(i) == pos) break;
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** Fast: build map once, then O(1) lookup per key. Returns op count. */
|
||||
static long mergeJoinFastOps(int numJoinKeys, int numOffsets) {
|
||||
List<Integer> offsets = new ArrayList<>();
|
||||
Random rng = new Random(7);
|
||||
Set<Integer> added = new HashSet<>();
|
||||
while (offsets.size() < numOffsets) {
|
||||
int o = rng.nextInt(numJoinKeys);
|
||||
if (added.add(o)) offsets.add(o);
|
||||
}
|
||||
|
||||
long ops = 0;
|
||||
// Build map: O(K)
|
||||
Set<Integer> offsetSet = new HashSet<>(offsets);
|
||||
ops += offsets.size(); // building cost
|
||||
|
||||
// getNewJoinKeysByOffsets inner loop: O(1) per pos
|
||||
for (int pos = 0; pos < numJoinKeys; pos++) {
|
||||
ops++; // one map lookup
|
||||
offsetSet.contains(pos);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// tidb-0002: mergeInAndNotEQLists — removeValues slice vs map
|
||||
//
|
||||
// Models the filter pass: given N predicates and R indices to remove,
|
||||
// iterate all N and check membership in the remove-set.
|
||||
// Slow: slices.Contains — O(R) per predicate, O(N*R) total.
|
||||
// Fast: map — O(1) per predicate, O(N) total.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/** Slow: scan removeValues list for every predicate. Returns op count. */
|
||||
static long predicateSimplifySlowOps(int numPredicates, int numRemoved) {
|
||||
// Simulate a double-loop that marks some indices for removal
|
||||
List<Integer> removeValues = new ArrayList<>();
|
||||
// mark the first numRemoved predicates for removal (worst case: all removed come late)
|
||||
for (int i = numPredicates - numRemoved; i < numPredicates; i++) {
|
||||
removeValues.add(i);
|
||||
}
|
||||
|
||||
long ops = 0;
|
||||
// Filter pass: for each predicate, scan removeValues
|
||||
for (int i = 0; i < numPredicates; i++) {
|
||||
for (int j = 0; j < removeValues.size(); j++) {
|
||||
ops++;
|
||||
if (removeValues.get(j) == i) break;
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** Fast: use a HashSet for O(1) removal check. Returns op count. */
|
||||
static long predicateSimplifyFastOps(int numPredicates, int numRemoved) {
|
||||
Set<Integer> removeSet = new HashSet<>();
|
||||
for (int i = numPredicates - numRemoved; i < numPredicates; i++) {
|
||||
removeSet.add(i);
|
||||
}
|
||||
|
||||
long ops = 0;
|
||||
// Filter pass: O(1) per predicate
|
||||
for (int i = 0; i < numPredicates; i++) {
|
||||
ops++; // one set lookup
|
||||
removeSet.contains(i);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test runner
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
public static void main(String[] args) {
|
||||
int passed = 0;
|
||||
int failed = 0;
|
||||
|
||||
// tidb-0001: join key counts
|
||||
int[][] joinSizes = {{20, 10}, {50, 25}, {100, 50}, {200, 100}};
|
||||
for (int[] sz : joinSizes) {
|
||||
int n = sz[0], k = sz[1];
|
||||
long slow = mergeJoinSlowOps(n, k);
|
||||
long fast = mergeJoinFastOps(n, k);
|
||||
// Slow should be significantly more: O(N*K) vs O(N+K)
|
||||
// At N=20,K=10: slow~100, fast~30 → ratio ~3x minimum
|
||||
boolean pass = slow > fast * 2;
|
||||
System.out.printf("tidb-0001 N=%-4d K=%-4d slow=%6d fast=%4d ratio=%5.1fx %s%n",
|
||||
n, k, slow, fast, (double) slow / fast, pass ? "PASS" : "FAIL");
|
||||
if (pass) passed++; else failed++;
|
||||
}
|
||||
|
||||
// tidb-0002: predicate + removed counts
|
||||
int[][] predSizes = {{50, 25}, {100, 50}, {200, 100}, {500, 250}};
|
||||
for (int[] sz : predSizes) {
|
||||
int n = sz[0], r = sz[1];
|
||||
long slow = predicateSimplifySlowOps(n, r);
|
||||
long fast = predicateSimplifyFastOps(n, r);
|
||||
// Slow = O(N*R), fast = O(N). At N=50,R=25: slow~625, fast~50 → 12.5x
|
||||
boolean pass = slow > fast * 5;
|
||||
System.out.printf("tidb-0002 N=%-4d R=%-4d slow=%6d fast=%4d ratio=%5.1fx %s%n",
|
||||
n, r, slow, fast, (double) slow / fast, pass ? "PASS" : "FAIL");
|
||||
if (pass) passed++; else failed++;
|
||||
}
|
||||
|
||||
System.out.printf("%nTotal: %d/%d PASS%n", passed, passed + failed);
|
||||
if (failed > 0) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue