java-topology/whitepaper/outreach/renpy-0001.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.4 KiB
Raw Permalink Blame History

Ren'Py — CWE-407 Disclosure Brief (renpy-0001)

2026-04-13 · Patch available — awaiting upstream merge

Finding

O(N²) attribute matching in the image prediction system where optional and required are maintained as lists, causing O(N) membership tests and O(N) removals per attribute operation.

The Defect

renpy-0001 (PATCHED — MEDIUM): renpy/display/image.py:980

# Image attribute matching:
optional = list(defaults) if defaults else []
required = []

for i in name[1:]:
    if i[0] == "-":
        i = i[1:]
        if i in optional:           # O(N) list scan
            optional.remove(i)      # O(N) list removal
        if i in required:           # O(N) list scan
            required.remove(i)      # O(N) list removal
    else:
        required.append(i)

Each attribute in the image name performs up to four O(N) list operations. With A attributes, total cost is O(A²).

Complexity Proof

At A=100 attributes (complex layered image with many conditions):

  • Defective: 100 × 4 × 50 = 20,000 comparisons
  • Fixed: 100 × 4 set operations = 400 operations
  • ~50× op reduction.

Impact

Ren'Py powers thousands of visual novels and interactive fiction games. Image prediction and layered image resolution call this path frequently during scene rendering. Games with complex layered images (character sprites with many clothing/expression/pose variants) compound the quadratic overhead. The prediction system fires ahead of display, so slowdowns cause visible loading hitches during dialogue.

The Fix

Replace optional and required lists with sets:

optional = set(defaults) if defaults else set()
required = set()

for i in name[1:]:
    if i[0] == "-":
        i = i[1:]
        optional.discard(i)   # O(1)
        required.discard(i)   # O(1)
    else:
        required.add(i)       # O(1)

Patch

Fix available: defects/renpy-0001/patch/renpy-0001.patch

Single-file patch in image.py.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (renpy/renpy).
  2. Assess severity — fires during image prediction and layered image resolution.
  3. Coordinate a disclosure date — we target 90 days from first contact.
  4. We will credit the Ren'Py team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.