Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

store_probably_utf16_to_latin1_or_utf16 shrinks with alignment 1, so a stored latin1+utf16 string can fail to load

已关闭 适合新手
#733 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 2 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
82/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python, wasm

调研方向

从 definitions.py:1673 开始,将 store_probably_utf16_to_latin1_or_utf16 与 store_string_to_latin1_or_utf16 中对齐的缩小路径进行比较。检查 CanonicalABI.md:2751 并运行提供的复现;完成的标准是,使用会将其移动到奇数地址的 allocator 时,latin1+utf16 结果仍可加载。

由索引模型根据 Issue 内容生成。

描述

store_probably_utf16_to_latin1_or_utf16 requests alignment 1 when shrinking to Latin-1 and does not check the returned pointer’s alignment. But load_string_from_range requires 2-byte alignment for all latin1+utf16 strings. An allocator honoring the requested alignment can therefore return an odd pointer: storing succeeds, but loading the result traps.

This is at a25fc0b, in definitions.py:1673 and CanonicalABI.md:2751:

latin1_size = int(len(encoded) / 2)
for i in range(latin1_size):
  cx.opts.memory[ptr + i] = cx.opts.memory[ptr + 2*i]
ptr = cx.reallocate(ptr, src_byte_length, 1, latin1_size)   # alignment 1
trap_if(ptr + latin1_size > len(cx.opts.memory))             # no alignment check
return (ptr, latin1_size)

The other shrinking path, the final reallocate in store_string_to_latin1_or_utf16, passes alignment 2 and does trap_if(ptr != align_to(ptr, 2)). That matches #54 and #61, which made latin1+utf16 always 2-aligned. Wasmtime's FACT adapter for this case (crates/environ/src/fact/trampoline.rs, commented "Corresponds to store_probably_utf16_to_latin1_or_utf16") also passes alignment 2 to the downsizing realloc and validates the result.

Reproduction

Both the source and destination use latin1+utf16, and the source string is UTF-16-tagged even though every code point fits in latin1. The realloc below honors the requested alignment but moves the buffer to an odd address on the shrink:

import sys
sys.path.insert(0, sys.argv[1])   # .../design/mvp/canonical-abi
from definitions import *

def realloc(args):
    old_ptr, old_size, align, new_size = args
    if old_size == 0:
        return [2]                  # initial allocation: 2-aligned
    assert align == 1               # the shrink asks for alignment 1...
    mem[1:1+new_size] = mem[old_ptr:old_ptr+new_size]
    return [1]                      # ...so an odd pointer meets that alignment

mem = bytearray(64)
opts = CanonicalOptions()
opts.memory = MemInst(mem, 'i32'); opts.string_encoding = 'latin1+utf16'; opts.realloc = realloc
cx = LiftLowerContext(opts, ComponentInstance(Store()))

def run(f):
    task = Task(FuncType([], []), CanonicalOptions(), cx.inst, lambda: [], lambda _: ())
    out = {}
    def body():
        try: out['v'] = f()
        except BaseException as e: out['exc'] = repr(e)
    Thread(task, body).resume()
    return out

stored = run(lambda: store_string_into_range(cx, ('hello', 'latin1+utf16', 5 | (1 << 31))))
print('store:', stored)
print('load :', run(lambda: load_string_from_range(cx, *stored['v'])))

Output:

store: {'v': (1, 5)}
load : {'exc': 'Trap()'}
Suggested fix

Match the other paths and Wasmtime:

-  ptr = cx.reallocate(ptr, src_byte_length, 1, latin1_size)
+  ptr = cx.reallocate(ptr, src_byte_length, 2, latin1_size)
+  trap_if(ptr != align_to(ptr, 2))
   trap_if(ptr + latin1_size > len(cx.opts.memory))

The same change is needed in CanonicalABI.md.

We found this while proving a canonical ABI string round trip in Lean.

主要语言
WebAssembly
星标
1.4k
派生
132
平均合并
4 天
30 天内合并 PR
12

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

WebAssembly/component-model 的其他 Issue

查看 WebAssembly/component-model 的全部 Issue

相似的 Issue

更多 Compilers Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。