# I'm working on a WebAssembly interpreter in zig\. WebAssembly uses LEB128 encoding throughout its specification\. · gitcafe/zig

[View on GitCafe](https://git.cafe/gitcafe/zig/commit/1f61076ffb3027e043ff78995344267b39b6226f)

Repository: [gitcafe/zig](https://git.cafe/gitcafe/zig)

Visibility: public

Requested revision: 1f61076ffb3027e043ff78995344267b39b6226f

Requested commit: 1f61076ffb3027e043ff78995344267b39b6226f

Commit: 1f61076ffb3027e043ff78995344267b39b6226f

Tree: a5d8ea3a9adbb81cd33e787abc79c421421dd60f

Author: Malcolm Still

Committer: Andrew Kelley

## Message

```
I'm working on a WebAssembly interpreter in zig. WebAssembly uses LEB128 encoding throughout its specification.

The WebAssembly spec requires signed LEB128 to be encoded up to a maximum number of bytes (max 5 bytes for i32, max 10 bytes for i64) and that "unused" bits are all 0 if the number is positive and all 1 if the number is negative. The Zig LEB128 implementation already enforces the max number of bytes and does check the unused bytes https://github.com/ziglang/zig/blob/master/lib/std/leb128.zig#L70-L79.

However, the WebAssembly test suite has a number of tests that were failing validation (expecting the wasm module to fail validation, but when running the tests, those examples were actually passing validation):

    https://github.com/malcolmstill/foxwren/blob/master/test/testsuite/binary-leb128.wast#L893-L902
    https://github.com/malcolmstill/foxwren/blob/master/test/testsuite/binary-leb128.wast#L934-L943

Notably the failures are both cases of negative numbers and the top 4 bits of the last byte are zero. And I believe this is the issue: we're only currently checking the "unused" / remaining_bits if we overflow, but in the case of 0x0_ no overflow happens and so the bits go unchecked.

In other words:

    \xff\xff\xff\xff\7f rightly successfully decodes (because it overflows and the remaining bits are 0b1111)
    \xff\xff\xff\xff\6f rightly errors with overflow (because it overflows and the remaining bits are 0b1110)
    \xff\xff\xff\xff\0f incorrectly decodes when it should error (because the top 4 bits are all 0, and so no overflow occurs and no check that the unused bits are 1 happens)

This PR adds a the remaining_bits check in an else branch of the @shlWithOverflow when we're looking at the last byte and the number being decoded is negative.

Note: this means a couple of the test cases in leb128.zig that are down as decoding shouldn't actually decode so I added the appropriate 1 bits.

```

## Parents

- [9fa723ee5043a9d2cb017e417f2e27041f671146](https://git.cafe/gitcafe/zig/commit/9fa723ee5043a9d2cb017e417f2e27041f671146?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zig/tree/1f61076ffb3027e043ff78995344267b39b6226f?format=markdown)
