VS Code (4 defects): - vscode-0001: extensionGalleryService uuid dedup O(N×M) MEDIUM 100x - vscode-0002: abstractExtensionManagementService deps O(D²) MEDIUM 49x - vscode-0003: userDataSync merge compare() O(N×M) across 8 files MEDIUM 250x - vscode-0004: configurationModels override identifiers O(N×M) LOW-MEDIUM 18x Zed (2 defects): - zed-0001: lsp_store LSP edit dedup Vec::contains O(E²) MEDIUM 49x - zed-0002: extension_builder manifest dedup Vec::contains O(N²) LOW 24x 6/6 unit tests PASS
115 lines
4.1 KiB
Java
115 lines
4.1 KiB
Java
import java.util.*;
|
|
|
|
/**
|
|
* CWE-407 unit tests for Zed editor defects.
|
|
*
|
|
* zed-0001: lsp_store LSP edit dedup Vec::contains O(E²)
|
|
* zed-0002: extension_builder manifest entry dedup Vec::contains O(N²)
|
|
*/
|
|
public class ZedTest {
|
|
|
|
// ---------------------------------------------------------------
|
|
// zed-0001: LSP edit dedup Vec::contains O(E²)
|
|
// ---------------------------------------------------------------
|
|
|
|
/** BEFORE: Vec::contains for each new edit — O(E²) */
|
|
static int lspEditDedupBefore(List<String> edits) {
|
|
int ops = 0;
|
|
List<String> lspEdits = new ArrayList<>();
|
|
for (String edit : edits) {
|
|
// !lsp_edits.contains(&edit)
|
|
boolean found = false;
|
|
for (String existing : lspEdits) {
|
|
ops++;
|
|
if (existing.equals(edit)) { found = true; break; }
|
|
}
|
|
if (!found) lspEdits.add(edit);
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
/** AFTER: HashSet seen-set for O(1) dedup — O(E) */
|
|
static int lspEditDedupAfter(List<String> edits) {
|
|
int ops = 0;
|
|
Set<String> seen = new HashSet<>();
|
|
List<String> lspEdits = new ArrayList<>();
|
|
for (String edit : edits) {
|
|
ops++; // set lookup
|
|
if (seen.add(edit)) {
|
|
lspEdits.add(edit);
|
|
}
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
// zed-0002: extension manifest dedup Vec::contains O(N²)
|
|
// ---------------------------------------------------------------
|
|
|
|
/** BEFORE: manifest.languages.contains for each dir — O(N²) */
|
|
static int manifestDedupBefore(List<String> entries) {
|
|
int ops = 0;
|
|
List<String> manifest = new ArrayList<>();
|
|
for (String entry : entries) {
|
|
boolean found = false;
|
|
for (String existing : manifest) {
|
|
ops++;
|
|
if (existing.equals(entry)) { found = true; break; }
|
|
}
|
|
if (!found) manifest.add(entry);
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
/** AFTER: HashSet seen-set — O(N) */
|
|
static int manifestDedupAfter(List<String> entries) {
|
|
int ops = 0;
|
|
Set<String> existing = new HashSet<>();
|
|
List<String> manifest = new ArrayList<>();
|
|
for (String entry : entries) {
|
|
ops++;
|
|
if (existing.add(entry)) {
|
|
manifest.add(entry);
|
|
}
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
// Main: run all tests
|
|
// ---------------------------------------------------------------
|
|
public static void main(String[] args) {
|
|
int pass = 0, fail = 0;
|
|
|
|
// --- zed-0001: LSP edit dedup ---
|
|
{
|
|
int E = 100; // edits from large refactor
|
|
List<String> edits = new ArrayList<>();
|
|
for (int i = 0; i < E; i++) edits.add("edit-" + i); // all unique = worst case
|
|
int before = lspEditDedupBefore(edits);
|
|
int after = lspEditDedupAfter(edits);
|
|
double ratio = (double) before / after;
|
|
boolean ok = ratio > 10;
|
|
System.out.printf("zed-0001 lsp-edit-dedup E=%d before=%d after=%d ratio=%.1fx %s%n",
|
|
E, before, after, ratio, ok ? "PASS" : "FAIL");
|
|
if (ok) pass++; else fail++;
|
|
}
|
|
|
|
// --- zed-0002: manifest dedup ---
|
|
{
|
|
int N = 50; // language dirs in a large extension
|
|
List<String> entries = new ArrayList<>();
|
|
for (int i = 0; i < N; i++) entries.add("languages/lang-" + i);
|
|
int before = manifestDedupBefore(entries);
|
|
int after = manifestDedupAfter(entries);
|
|
double ratio = (double) before / after;
|
|
boolean ok = ratio > 10;
|
|
System.out.printf("zed-0002 manifest-dedup N=%d before=%d after=%d ratio=%.1fx %s%n",
|
|
N, before, after, ratio, ok ? "PASS" : "FAIL");
|
|
if (ok) pass++; else fail++;
|
|
}
|
|
|
|
System.out.printf("%n%d/%d PASS%n", pass, pass + fail);
|
|
if (fail > 0) System.exit(1);
|
|
}
|
|
}
|