wave17: openssh-0001/2, strongswan-0001, gradle-0002, groovy-0001/2, make-0001, clojure-CLEAN + whitepaper 549/240
This commit is contained in:
parent
0f275c44af
commit
4221966e66
22 changed files with 1776 additions and 4 deletions
117
defects/groovy/unit/GroovyVerifierDefaultParamsTest.java
Normal file
117
defects/groovy/unit/GroovyVerifierDefaultParamsTest.java
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* groovy-0002 — Verifier: Arrays.asList(params).contains(p) O(V×P) per generated variant
|
||||
*
|
||||
* Demonstrates CWE-407: Verifier.addDefaultParameterMethods and
|
||||
* addDefaultParameterConstructors call Arrays.asList(params).contains(p) inside
|
||||
* visitVariableExpression, allocating a new List and scanning linearly on every
|
||||
* variable expression visit.
|
||||
*
|
||||
* Models the inner visitor call pattern:
|
||||
* slow(): Arrays.asList(params).contains(p) — allocates list + O(P) per call
|
||||
* fast(): pre-built HashSet.contains(p) — O(1) per call
|
||||
*
|
||||
* Ratio must be >= 5x at N=500.
|
||||
*/
|
||||
public class GroovyVerifierDefaultParamsTest {
|
||||
|
||||
/**
|
||||
* Defective path: simulate the visitor visiting V variable expressions,
|
||||
* each time calling Arrays.asList(params).contains(p).
|
||||
*
|
||||
* params: array of P "kept" parameters for this generated variant
|
||||
* allParams: array of P+D parameters for the original method
|
||||
* varExprs: V parameter references seen in the body
|
||||
*
|
||||
* Returns total element comparisons.
|
||||
*/
|
||||
static long slow(String[] params, String[] allParams, List<String> varExprs) {
|
||||
long ops = 0;
|
||||
for (String p : varExprs) {
|
||||
// Arrays.asList(params).contains(p) — O(P) scan, new List allocation
|
||||
boolean inParams = false;
|
||||
for (String x : params) {
|
||||
ops++;
|
||||
if (x.equals(p)) { inParams = true; break; }
|
||||
}
|
||||
if (!inParams) {
|
||||
// Arrays.asList(allParams).contains(p) — second O(P) scan
|
||||
for (String x : allParams) {
|
||||
ops++;
|
||||
if (x.equals(p)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed path: pre-build HashSet once before the visitor, then O(1) per call.
|
||||
*
|
||||
* Returns total element comparisons (each hash probe = 1 op).
|
||||
*/
|
||||
static long fast(Set<String> paramsSet, Set<String> allParamsSet, List<String> varExprs) {
|
||||
long ops = 0;
|
||||
for (String p : varExprs) {
|
||||
ops++; // one hash probe
|
||||
boolean inParams = paramsSet.contains(p);
|
||||
if (!inParams) {
|
||||
ops++; // second hash probe
|
||||
allParamsSet.contains(p);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] sizes = {100, 200, 500, 1000};
|
||||
int pass = 0, total = 0;
|
||||
boolean allPassed = true;
|
||||
|
||||
for (int N : sizes) {
|
||||
// P = N parameters in the kept array (generated variant)
|
||||
// V = N variable expressions in the body
|
||||
String[] params = new String[N];
|
||||
String[] allParams = new String[N + 10]; // original has 10 extra defaulted params
|
||||
for (int i = 0; i < N; i++) {
|
||||
params[i] = "param" + i;
|
||||
allParams[i] = "param" + i;
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
allParams[N + i] = "default" + i;
|
||||
}
|
||||
|
||||
// Variable expressions: mix of params that ARE in kept set and ones that aren't
|
||||
// Force worst case: all var-exprs reference defaulted params (not in params[])
|
||||
List<String> varExprs = new ArrayList<>();
|
||||
for (int i = 0; i < N; i++) {
|
||||
varExprs.add("default" + (i % 10));
|
||||
}
|
||||
|
||||
Set<String> paramsSet = new HashSet<>(Arrays.asList(params));
|
||||
Set<String> allParamsSet = new HashSet<>(Arrays.asList(allParams));
|
||||
|
||||
long slowOps = slow(params, allParams, varExprs);
|
||||
long fastOps = fast(paramsSet, allParamsSet, varExprs);
|
||||
|
||||
double ratio = (double) slowOps / fastOps;
|
||||
boolean pass1 = ratio >= 5.0;
|
||||
total++;
|
||||
if (pass1) pass++;
|
||||
else allPassed = false;
|
||||
|
||||
System.out.printf("N=%4d slow=%8d fast=%6d ratio=%7.1fx %s%n",
|
||||
N, slowOps, fastOps, ratio, pass1 ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
System.out.printf("%d/%d PASS%n", pass, total);
|
||||
if (!allPassed) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue