comms/voip/smtp: 30 CWE-407 defects + 9 CLEAN; 224 sites, 101 ecosystems
This commit is contained in:
parent
4d3fcc8e73
commit
b3842ab6b8
86 changed files with 6516 additions and 5 deletions
166
defects/rocketchat/unit/RocketchatTest.java
Normal file
166
defects/rocketchat/unit/RocketchatTest.java
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
package unit;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* RocketchatTest — CWE-407 benchmark
|
||||
*
|
||||
* Defects:
|
||||
* 0001: mentionIds.includes() + usersInThread.includes() per subscriber in notification fanout
|
||||
* (sendNotificationsOnMessage.ts:79, :372)
|
||||
* 0002: userIds.includes() per subscription in unread-counter update loop
|
||||
* (notifyUsersOnMessage.ts:129)
|
||||
*/
|
||||
public class RocketchatTest {
|
||||
|
||||
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 r = fOps > 0 ? (double)sOps/fOps : 0;
|
||||
System.out.printf(" %-56s slow:%4dms (%,d ops) fast:%4dms (%,d ops) speedup:%.0fx%n",
|
||||
label, sMs, sOps, fMs, fOps, r);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Defect 0001: mentionIds.includes() per subscriber (Array vs Set)
|
||||
// Models sendNotification() called inside subscriptions.forEach()
|
||||
// S = subscribers, M = mentionIds
|
||||
// -------------------------------------------------------------------------
|
||||
static long slowMentionCheck(List<String> subscribers, List<String> mentionIds) {
|
||||
long ops = 0;
|
||||
for (String sub : subscribers) {
|
||||
for (String mid : mentionIds) { // O(M) per subscriber
|
||||
ops++;
|
||||
if (mid.equals(sub)) break;
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static long fastMentionCheck(List<String> subscribers, Set<String> mentionIdSet) {
|
||||
long ops = 0;
|
||||
for (String sub : subscribers) {
|
||||
ops++;
|
||||
mentionIdSet.contains(sub); // O(1)
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Defect 0001b: usersInThread.includes() per subscriber
|
||||
// -------------------------------------------------------------------------
|
||||
static long slowThreadCheck(List<String> subscribers, List<String> usersInThread) {
|
||||
long ops = 0;
|
||||
for (String sub : subscribers) {
|
||||
for (String u : usersInThread) { // O(T) per subscriber
|
||||
ops++;
|
||||
if (u.equals(sub)) break;
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static long fastThreadCheck(List<String> subscribers, Set<String> threadSet) {
|
||||
long ops = 0;
|
||||
for (String sub : subscribers) {
|
||||
ops++;
|
||||
threadSet.contains(sub); // O(1)
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Defect 0002: userIds.includes() per subscription (notifyUsersOnMessage)
|
||||
// -------------------------------------------------------------------------
|
||||
static long slowUserIdCheck(List<String> subs, List<String> userIds) {
|
||||
long ops = 0;
|
||||
for (String sub : subs) {
|
||||
for (String uid : userIds) { // O(U) per subscription
|
||||
ops++;
|
||||
if (uid.equals(sub)) break;
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static long fastUserIdCheck(List<String> subs, Set<String> userIdSet) {
|
||||
long ops = 0;
|
||||
for (String sub : subs) {
|
||||
ops++;
|
||||
userIdSet.contains(sub); // O(1)
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("RocketchatTest — CWE-407");
|
||||
|
||||
// Parameters: large channel, realistic mention / thread counts
|
||||
final int S = 10_000; // subscribers
|
||||
final int M = 50; // mention IDs
|
||||
final int T = 200; // thread participants
|
||||
final int U = 30; // userIds in notifyUsersOnMessage
|
||||
|
||||
// Build data
|
||||
List<String> subscribers = new ArrayList<>(S);
|
||||
for (int i = 0; i < S; i++) subscribers.add("user-" + i);
|
||||
|
||||
List<String> mentionIds = new ArrayList<>(M);
|
||||
Set<String> mentionIdSet = new HashSet<>(M);
|
||||
for (int i = 0; i < M; i++) { String id = "user-" + (i * 7); mentionIds.add(id); mentionIdSet.add(id); }
|
||||
|
||||
List<String> usersInThread = new ArrayList<>(T);
|
||||
Set<String> threadSet = new HashSet<>(T);
|
||||
for (int i = 0; i < T; i++) { String id = "user-" + (i * 3); usersInThread.add(id); threadSet.add(id); }
|
||||
|
||||
List<String> userIds = new ArrayList<>(U);
|
||||
Set<String> userIdSet = new HashSet<>(U);
|
||||
for (int i = 0; i < U; i++) { String id = "user-" + (i * 11); userIds.add(id); userIdSet.add(id); }
|
||||
|
||||
// Warm up
|
||||
slowMentionCheck(subscribers, mentionIds);
|
||||
fastMentionCheck(subscribers, mentionIdSet);
|
||||
|
||||
System.out.println("\n [0001] mentionIds.includes() per subscriber (S=" + S + ", M=" + M + ")");
|
||||
final long[] slowMOps = {0}, fastMOps = {0};
|
||||
bench("0001a mentionIds Array.includes vs Set.has",
|
||||
() -> { slowMOps[0] = slowMentionCheck(subscribers, mentionIds); },
|
||||
() -> { fastMOps[0] = fastMentionCheck(subscribers, mentionIdSet); },
|
||||
S * M, S);
|
||||
|
||||
System.out.println("\n [0001b] usersInThread.includes() per subscriber (S=" + S + ", T=" + T + ")");
|
||||
final long[] slowTOps = {0}, fastTOps = {0};
|
||||
bench("0001b usersInThread Array.includes vs Set.has",
|
||||
() -> { slowTOps[0] = slowThreadCheck(subscribers, usersInThread); },
|
||||
() -> { fastTOps[0] = fastThreadCheck(subscribers, threadSet); },
|
||||
S * T, S);
|
||||
|
||||
System.out.println("\n [0002] userIds.includes() per subscription (S=" + S + ", U=" + U + ")");
|
||||
final long[] slowUOps = {0}, fastUOps = {0};
|
||||
bench("0002 userIds Array.includes vs Set.has",
|
||||
() -> { slowUOps[0] = slowUserIdCheck(subscribers, userIds); },
|
||||
() -> { fastUOps[0] = fastUserIdCheck(subscribers, userIdSet); },
|
||||
S * U, S);
|
||||
|
||||
// Assertions
|
||||
int pass = 0, total = 3;
|
||||
long expSlow0001a = (long) S * M;
|
||||
long expFast0001a = S;
|
||||
long expSlow0001b = (long) S * T;
|
||||
long expFast0001b = S;
|
||||
long expSlow0002 = (long) S * U;
|
||||
long expFast0002 = S;
|
||||
|
||||
if (slowMentionCheck(subscribers, mentionIds) >= expFast0001a * M / 2) { pass++; System.out.println(" PASS 0001a: slow ops >> fast ops"); }
|
||||
else System.out.println(" FAIL 0001a");
|
||||
|
||||
if (slowThreadCheck(subscribers, usersInThread) >= expFast0001b * T / 2) { pass++; System.out.println(" PASS 0001b: slow ops >> fast ops"); }
|
||||
else System.out.println(" FAIL 0001b");
|
||||
|
||||
if (slowUserIdCheck(subscribers, userIds) >= expFast0002 * U / 2) { pass++; System.out.println(" PASS 0002: slow ops >> fast ops"); }
|
||||
else System.out.println(" FAIL 0002");
|
||||
|
||||
System.out.printf("%n%d/%d PASS%n", pass, total);
|
||||
if (pass < total) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue