java-topology/tools/mc-patch/README.md
russell@unturf.com db29a08762 undefect. CWE-407 — 92 sites, 42 ecosystems
B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections.
Squash of 94 local commits onto remote master.
2026-03-26 19:48:18 -04:00

1.9 KiB

Minecraft DependencySorter Patch

Patched server-26.1.jar (inner jar, extracted from bundler) with fixed DependencySorter.isCyclic — adds Set<K> visited parameter to prevent exponential revisiting of diamond dependency graphs.

Files

  • server-26.1-patched.jar — inner jar with patched DependencySorter.class
  • ../defects/minecraft/DependencySorter-before.java — decompiled original
  • ../defects/minecraft/DependencySorter-after.java — fixed version

To apply to a full server.jar

import zipfile, os

with open('server-26.1-patched.jar', 'rb') as f:
    patched_inner = f.read()

with zipfile.ZipFile('server.jar', 'r') as zin, \
     zipfile.ZipFile('server-patched.jar', 'w',
                     compression=zipfile.ZIP_DEFLATED, allowZip64=True) as zout:
    for item in zin.infolist():
        if item.filename == 'META-INF/versions/26.1/server-26.1.jar':
            zout.writestr(item, patched_inner)
        else:
            zout.writestr(item, zin.read(item.filename))

Why the signing is stripped

Mojang signs server-26.1.jar with SHA-384 manifests (META-INF/MOJANGCS.SF/.RSA). Any class modification invalidates the signature. The patched jar removes:

  • META-INF/MOJANGCS.SF
  • META-INF/MOJANGCS.RSA
  • Manifest stanzas for DependencySorter.class and DependencySorter$Entry.class

All other class digests are preserved intact.

Benchmark

See tests/bench/DependencySorterBenchmark.java.

Diamond depth Tags BEFORE (ns) AFTER (ns) Speedup
8 18 98,384 22,779 4.3x
10 22 436,388 37,353 11.7x
12 26 1,633,446 51,872 31.5x
14 30 6,486,367 73,704 88.0x
16 34 OVERFLOW 98,626

Vanilla server (500 tags, shallow diamonds): no measurable boot difference. Large modpack (1000+ tags, depth 8-14): 11-88x speedup predicted.