java-topology/defects/minecraft/patch/minecraft-0002-piston-resolver-hashset.md

1.4 KiB

UNDF: UNDF-2026-000000376

Classification

Field Value
CWE CWE-407 Inefficient Algorithmic Complexity
Severity MEDIUM
Component net/minecraft/world/level/block/piston/PistonStructureResolver.java
Function resolve() BFS loop
Hot path Called every piston activation event

Defect

PistonStructureResolver.toPush is an ArrayList<BlockPos>. During piston BFS, toPush.contains(pos) is called for every candidate block — O(N) scan per call, inside the BFS loop: O(N²) total.

// BEFORE — O(N²): ArrayList.contains() inside BFS loop
private final List<BlockPos> toPush = Lists.newArrayList();
// ...
if (!this.toPush.contains(pos)) {
    this.toPush.add(pos);
}

At the 12-block push limit toPush is bounded, but the pattern propagates to modded environments with higher push limits.

Fix

Add a parallel HashSet<BlockPos> for O(1) duplicate detection.

// AFTER — O(N): HashSet.add() returns false on duplicate → O(1)
private final List<BlockPos> toPush = Lists.newArrayList();
private final Set<BlockPos> toPushSet = new HashSet<>();

// Replace: if (!this.toPush.contains(pos)) { this.toPush.add(pos); }
// With:    if (this.toPushSet.add(pos)) { this.toPush.add(pos); }

The List is retained for ordered iteration (piston push order matters). The Set is used only for membership testing.