store_probably_utf16_to_latin1_or_utf16 shrinks with alignment 1, so a stored latin1+utf16 string can fail to load
Maintainer antworten meist innerhalb von 2 Tagen
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 82/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- python, wasm
- Bereich
- compilers, documentation
Rechercherichtung
Beginne bei definitions.py:1673 und vergleiche store_probably_utf16_to_latin1_or_utf16 mit dem ausgerichteten Verkleinerungspfad in store_string_to_latin1_or_utf16. Prüfe CanonicalABI.md:2751 und führe die bereitgestellte Reproduktion aus; fertig bedeutet, dass das latin1+utf16-Ergebnis mit einem Allocator, der es an eine ungerade Adresse verschiebt, weiterhin ladbar bleibt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
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.
- Vorherrschende Sprache
- WebAssembly
- Sterne
- 1.4k
- Forks
- 132
- Ø Merge
- 3 T. 9 Std.
- Gemergte PRs (30 T.)
- 10
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus WebAssembly/component-model
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
WebAssembly/component-model#609 · 2 Kommentare · 1 Reaktion ·
Maintainer antworten meist innerhalb von 2 Tagen
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
WebAssembly/component-model#732 ·
Maintainer antworten meist innerhalb von 2 Tagen
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
WebAssembly/component-model#731 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 2 Tagen
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
WebAssembly/component-model#724 · 10 Kommentare ·
Maintainer antworten meist innerhalb von 2 Tagen
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 25/100
WebAssembly/component-model#695 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 2 Tagen
Alle Issues in WebAssembly/component-model
Ähnliche Issues
-
bug self-host
Schwierigkeit 2/5 Ein halber Tag Anfängerfreundlichkeit 88/100
JakeChampion/lang#10897 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
tree-sitter/tree-sitter-cpp#374 ·
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
voidzero-dev/oxc-angular-compiler#511 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 86/100
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
leanprover/lean4#15423 ·
Maintainer antworten meist innerhalb von 1 Tag