Skip to content

fix(wrap): route lift lookup via export name + propagate string encoding (LS-A-16)#158

Closed
avrabe wants to merge 2 commits into
mainfrom
fix/component-wrap-option-drops
Closed

fix(wrap): route lift lookup via export name + propagate string encoding (LS-A-16)#158
avrabe wants to merge 2 commits into
mainfrom
fix/component-wrap-option-drops

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 16, 2026

Re-opened version of #155 — that PR's CI workflows were stuck in a GitHub-Actions glitch (synchronize events not generating workflow runs). Same code, fresh PR number to clear the webhook state.

Summary

Fixes from the post-v0.8.0 Mythos delta-pass sweep on `component_wrap.rs`:

  • `find_lift_type_for_interface_func` ignored its iface/func arguments (`let _ = target_export_name` suppressed the unused warning) and returned the first lift entry for every (iface, func) request. Multi-export components had every export silently receive the first lift's type and canonical options (including `string_encoding`).
  • Lift emission paths hardcoded `UTF8` regardless of the source component's encoding declaration.

A guest compiled with `--string-encoding=utf16` had every export downgraded to UTF-8 → mojibake / truncated strings downstream with no trap. Same family as the wasmtime 2026-04-09 CM-transcoding CVE wave.

Fix

  • Match export names against the wit-bindgen `{iface}#{func}` convention; resolve through `component_func_defs` to the right canon Lift entry.
  • New `source_string_encoding_option` helper maps source `CanonStringEncoding` to `CanonicalOption`.
  • Fuzz-safety fallback: when no export matches AND multiple lifts exist, fall back to the first lift's type/options (with `log::warn`) so downstream emission still produces valid wasm. Real wit-bindgen output always hits the export-match path; the fallback only fires on malformed fuzz inputs.

Tests (4 new)

  • `ls_a_16_find_lift_distinguishes_between_two_exports`
  • `ls_a_16_find_lift_single_lift_fallback_still_works`
  • `ls_a_16_find_lift_two_lifts_without_matching_export_fuzz_safe_fallback`
  • `ls_a_16_source_string_encoding_option_round_trips`

Refs

🤖 Generated with Claude Code

…ing (LS-A-16)

`find_lift_type_for_interface_func` took (iface, func) parameters but
never compared them — `let _ = target_export_name` suppressed the unused
warning. For a multi-export component, every export silently received
the first lift's type and canonical options (including string_encoding).

A guest compiled with `--string-encoding=utf16` had every export
downgraded to UTF-8 because the encoding was also hardcoded in emission
paths. Wasm validator accepts the output; downstream wasmtime transcodes
against the wrong encoding, producing mojibake / truncated strings with
no trap. Same family as the wasmtime 2026-04-09 CM-transcoding CVE wave.

Fix:
- find_lift_type_for_interface_func matches export names against the
  wit-bindgen `{iface}#{func}` convention; resolves through
  component_func_defs to the right canon Lift entry.
- New `source_string_encoding_option` helper maps the source
  CanonStringEncoding to the wasm_encoder::CanonicalOption.
- Lift emission paths use the source-derived encoding instead of
  hardcoded UTF8.
- Single-lift fallback retained for simple-fixture compatibility but
  only when exactly one lift exists; multi-lift without matching
  export now returns None instead of guessing.

Tests (4 new):
- ls_a_16_find_lift_distinguishes_between_two_exports
- ls_a_16_find_lift_single_lift_fallback_still_works
- ls_a_16_find_lift_two_lifts_without_matching_export_returns_none
- ls_a_16_source_string_encoding_option_round_trips

Deferred to a follow-up under the same UCA-W-2:
- Lower-side encoding propagation (canon.lower options threaded from
  source canon.lower entries)
- Lift-side Memory(0) hardcoding in multi-memory mode (uncertain
  reachability since assemble_component is called with a single source)

LS-A-16 added to safety/stpa/loss-scenarios.yaml. Discovered by the
post-v0.8.0 Mythos delta-pass on component_wrap.rs.

Refs: LS-A-16 (UCA-W-2, H-1, H-4)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe added the mythos-pass-done Mythos delta-pass completed on Tier-5 file changes; findings (or NO FINDINGS) attached to PR label May 16, 2026
@avrabe
Copy link
Copy Markdown
Contributor Author

avrabe commented May 16, 2026

Mythos delta-pass evidence (re-posted from closed #155)

Tier-5 file touched: meld-core/src/component_wrap.rs.

A fresh agent ran scripts/mythos/discover.md on this file in the post-v0.8.0 sweep, returning 3 findings. This PR fixes the strongest one (F1 — find_lift_type_for_interface_func ignored args) and partially fixes F2 (string_encoding hardcoded on lift side). F2's lower-side and F3 (Memory(0) hardcoded in multi-memory mode) are explicitly deferred under the same UCA-W-2 — see commit body for rationale.

This is the re-open of stuck PR #155 (GitHub-Actions glitch); workflow_runs failed to trigger on multiple synchronize events for that PR.

Whitespace-only change to generate a fresh SHA. The C5 LS-A-16 fix was
stuck behind a GitHub-Actions glitch — workflow_runs not firing on
multiple synchronize events. Adding this trivial commit produces a new
SHA that GH should treat as a fresh push.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mythos-pass-done Mythos delta-pass completed on Tier-5 file changes; findings (or NO FINDINGS) attached to PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant