Skip to content

reconstruct_component corrupts components that nest core modules inside a ComponentSection #325

Description

@avrabe

Found while building fixtures for #239 Phase B (PR #324). Pre-existing, not introduced by that PR, and it fails loudly — no silent miscompile.

What happens

reconstruct_component replaces each nested core module by locating its section header and writing a fresh [id=1][LEB128 size][module bytes] in its place. That is correct for a top-level ModuleSection, but Parser::parse_all also yields ModuleSection payloads for modules inside a nested ComponentSection. For those, the inner module's new (smaller) size is written while the enclosing component section's own LEB128 size field is copied through verbatim from the original bytes. The outer size is then wrong and everything after it misparses.

optimize_component catches this in its own post-pass validation and returns an error, so the output is never shipped:

Optimized component validation failed: core instance 0 has no export named `add` (at offset 0x8d)

Repro

Any component that defines a nested component containing a core module — e.g. the NESTED_COMPONENT fixture in loom-core/src/component_optimizer.rs (phase_b_reachability_gc_tests). Optimizing it fails as above, because Phase A shrinks both modules and the inner one is nested.

Why it matters

Nested components are how the Component Model expresses composition, so this is not an exotic shape. Today it means loom optimize simply refuses such components (CLI falls back with "Component optimization not available"), which is safe but is a capability gap rather than a deliberate decision.

Suggested fix

Track ComponentSection byte ranges the way module_ranges is already tracked for custom sections, and for a ModuleSection that falls inside one, leave the bytes verbatim (do not optimize or replace that module) — conservative, matches the existing "skip rather than risk" idiom. A full fix would re-emit the enclosing component section with a corrected size.

Note

#239 Phase B (PR #324) bails on nested components, so it cannot make this worse.

Refs #239

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions