diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-07-29 20:03:22 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-07-29 20:03:22 +0900 |
| commit | a6889262c6f58124e4bed8e4f51024abc9a9e264 (patch) | |
| tree | ef386a5b8b8bf0630378a7f8d9bf63f6ebed0036 | |
| parent | c50662e1e81289c44b4da4107944221328bb5f1c (diff) | |
| download | php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.tar.gz php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.tar.zst php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.zip | |
fix: Make AlignTest pass
| -rw-r--r-- | BUGS | 1 | ||||
| -rw-r--r-- | phpunit.xml | 1 | ||||
| -rw-r--r-- | src/WebAssembly/BinaryFormat/Decoder.php | 45 |
3 files changed, 46 insertions, 1 deletions
@@ -2,7 +2,6 @@ ## Validation -* AlignTest * ImportsTest * LinkingTest * SkipStackGuardPageTest diff --git a/phpunit.xml b/phpunit.xml index 2e62c6f..defe6df 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -18,6 +18,7 @@ </testsuite> <testsuite name="default"> <file>tests/src/SpecTestsuites/Core/AddressTest.php</file> + <file>tests/src/SpecTestsuites/Core/AlignTest.php</file> <file>tests/src/SpecTestsuites/Core/BinaryLeb128Test.php</file> <file>tests/src/SpecTestsuites/Core/BinaryTest.php</file> <file>tests/src/SpecTestsuites/Core/BlockTest.php</file> diff --git a/src/WebAssembly/BinaryFormat/Decoder.php b/src/WebAssembly/BinaryFormat/Decoder.php index ff23a5d..65541e5 100644 --- a/src/WebAssembly/BinaryFormat/Decoder.php +++ b/src/WebAssembly/BinaryFormat/Decoder.php @@ -678,6 +678,13 @@ final class Decoder private function decodeInstr(): Instr { + $instr = $this->doDecodeInstr(); + $this->validateMemArg($instr); + return $instr; + } + + private function doDecodeInstr(): Instr + { switch ($op = $this->decodeByte()) { case 0x00: return Instr::Unreachable(); case 0x01: return Instr::Nop(); @@ -1141,4 +1148,42 @@ final class Decoder assert(0 <= $result, '$result is guaranteed to be non-negative because it is the sum of non-negative integers'); return $result; } + + private function validateMemArg(Instr $instr): void + { + $isValid = match ($instr::class) { + // 1-byte operations: align must be <= 0 (2^0 = 1) + Instrs\Memory\I32Load8S::class, + Instrs\Memory\I32Load8U::class, + Instrs\Memory\I64Load8S::class, + Instrs\Memory\I64Load8U::class, + Instrs\Memory\I32Store8::class, + Instrs\Memory\I64Store8::class => $instr->align <= 0, + // 2-byte operations: align must be <= 1 (2^1 = 2) + Instrs\Memory\I32Load16S::class, + Instrs\Memory\I32Load16U::class, + Instrs\Memory\I64Load16S::class, + Instrs\Memory\I64Load16U::class, + Instrs\Memory\I32Store16::class, + Instrs\Memory\I64Store16::class => $instr->align <= 1, + // 4-byte operations: align must be <= 2 (2^2 = 4) + Instrs\Memory\I32Load::class, + Instrs\Memory\F32Load::class, + Instrs\Memory\I32Store::class, + Instrs\Memory\F32Store::class, + Instrs\Memory\I64Load32S::class, + Instrs\Memory\I64Load32U::class, + Instrs\Memory\I64Store32::class => $instr->align <= 2, + // 8-byte operations: align must be <= 3 (2^3 = 8) + Instrs\Memory\I64Load::class, + Instrs\Memory\F64Load::class, + Instrs\Memory\I64Store::class, + Instrs\Memory\F64Store::class => $instr->align <= 3, + // Not a memory operation. + default => true, + }; + if (!$isValid) { + throw new InvalidBinaryFormatException("malformed memop flags"); + } + } } |
