wave14a/c/d: 524/239 — rails-0018/grape-0001..3/django-0005..6/sqlalchemy-0003/go-stdlib-0001/vault-0001/tf-aws-0001

This commit is contained in:
russell@unturf.com 2026-03-27 18:11:25 -04:00
parent 8f0bc73afa
commit ac0e1e091e
20 changed files with 1948 additions and 21 deletions

View file

@ -3,7 +3,7 @@ package unit;
import java.util.*;
/**
* RailsTest — rails-0001..0017
* RailsTest — rails-0001..0018
*
* Proves CWE-407 in Ruby on Rails:
* rails-0001: Preloader::Batch — future_tables Array#include? in loaders.reject O(L×F) per batch
@ -23,6 +23,7 @@ import java.util.*;
* rails-0015: schema_statements — inserting.count(v) in detect loop O(V²) dupe check
* rails-0016: SQLite3Adapter — to_column_names.include? in copy_table_indexes O(I×C×N)
* rails-0017: schema_statements — index.columns.include? in rename_column_indexes O(I×C)
* rails-0018: CollectionAssociation#find_by_scan — ids Array#include? in load_target.select O(T×I)
*
* Run: javac -d . RailsTest.java && java -ea unit.RailsTest
*/
@ -558,6 +559,47 @@ public class RailsTest {
return ops;
}
// ── rails-0018: CollectionAssociation#find_by_scan ────────────────────────
/** SLOW: ids is Array — Array#include? per loaded record O(T×I) */
static long collectionFindScanSlow(int targetSize, int idsCount) {
// Simulate load_target: T in-memory records
List<String> target = new ArrayList<>();
for (int i = 0; i < targetSize; i++) target.add("rec_" + i);
// ids = args.flatten.compact.map(&:to_s).uniq — returns Array
List<String> ids = new ArrayList<>();
for (int i = 0; i < idsCount; i++) ids.add("rec_" + (i * 3)); // request every 3rd
long ops = 0;
// load_target.select { |r| ids.include?(r.id.to_s) }
for (String rec : target) {
for (String id : ids) {
ops++;
if (id.equals(rec)) break;
}
}
return ops;
}
/** FAST: ids_set is HashSet — Set#include? per record O(T+I) */
static long collectionFindScanFast(int targetSize, int idsCount) {
List<String> target = new ArrayList<>();
for (int i = 0; i < targetSize; i++) target.add("rec_" + i);
// ids_set = ids.to_set — O(I) one-time build
Set<String> idsSet = new HashSet<>();
for (int i = 0; i < idsCount; i++) idsSet.add("rec_" + (i * 3));
long ops = 0;
// load_target.select { |r| ids_set.include?(r.id.to_s) }
for (String rec : target) {
ops++; // O(1) Set#include?
idsSet.contains(rec);
}
return ops;
}
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;
@ -568,7 +610,7 @@ public class RailsTest {
}
public static void main(String[] args) {
System.out.println("=== UNIT rails-0001..0016: Ruby on Rails CWE-407 ===");
System.out.println("=== UNIT rails-0001..0018: Ruby on Rails CWE-407 ===");
System.out.println();
final int LOADERS=500, FUTURE=300, ROUNDS=20;
@ -636,6 +678,10 @@ public class RailsTest {
long s15=renameColumnIndexesSlow(RCI_IDXS,RCI_COLS), f15=renameColumnIndexesFast(RCI_IDXS,RCI_COLS);
bench("rails-0017 rename_column_indexes columns.include?", ()->renameColumnIndexesSlow(RCI_IDXS,RCI_COLS), ()->renameColumnIndexesFast(RCI_IDXS,RCI_COLS), s15, f15);
final int COLL_TARGET=2000, FIND_IDS=100;
long s16=collectionFindScanSlow(COLL_TARGET,FIND_IDS), f16=collectionFindScanFast(COLL_TARGET,FIND_IDS);
bench("rails-0018 CollectionAssociation find_by_scan ids", ()->collectionFindScanSlow(COLL_TARGET,FIND_IDS), ()->collectionFindScanFast(COLL_TARGET,FIND_IDS), s16, f16);
System.out.println();
int pass = 0;
assert s0 > f0 * 10 : "rails-0001 expected >10x"; pass++;
@ -654,9 +700,10 @@ public class RailsTest {
assert s13 > f13 * 5 : "rails-0015 expected >5x"; pass++;
assert s14 > f14 * 5 : "rails-0016 expected >5x"; pass++;
assert s15 > f15 * 5 : "rails-0017 expected >5x"; pass++;
assert s16 > f16 * 5 : "rails-0018 expected >5x"; pass++;
assert preloaderFast(10,5,2) >= 0; pass++;
System.out.printf("%d/17 PASS — rails-0001..0017: CWE-407 in preloader/callbacks/enumerable/schema/hooks/enum/filter/encryption/timezone/view/job/sqlite/rename_column%n", pass);
System.out.printf("Hotpaths: Preloader::Batch, skip_callback, Enumerable#excluding, SchemaDumper, lazy_load_hooks, FilterAttributeHandler, AutoFilteredParams, TimeZoneConversion, options_for_select, CollectionHelpers, ActiveJob::Arguments, schema_statements, SQLite3Adapter, rename_column_indexes%n");
System.out.printf("%d/18 PASS — rails-0001..0018: CWE-407 in preloader/callbacks/enumerable/schema/hooks/enum/filter/encryption/timezone/view/job/sqlite/rename_column/collection_find%n", pass);
System.out.printf("Hotpaths: Preloader::Batch, skip_callback, Enumerable#excluding, SchemaDumper, lazy_load_hooks, FilterAttributeHandler, AutoFilteredParams, TimeZoneConversion, options_for_select, CollectionHelpers, ActiveJob::Arguments, schema_statements, SQLite3Adapter, rename_column_indexes, CollectionAssociation#find_by_scan%n");
}
}