diff options
Diffstat (limited to 'js/src/jsapi-tests/testWasmLEB128.cpp')
-rw-r--r-- | js/src/jsapi-tests/testWasmLEB128.cpp | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testWasmLEB128.cpp b/js/src/jsapi-tests/testWasmLEB128.cpp new file mode 100644 index 0000000000..58ded9ab26 --- /dev/null +++ b/js/src/jsapi-tests/testWasmLEB128.cpp @@ -0,0 +1,173 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <stdlib.h> + +#include "jsapi-tests/tests.h" + +#include "wasm/WasmValidate.h" + +static bool WriteValidBytes(js::wasm::Encoder& encoder, bool* passed) { + *passed = false; + if (!encoder.empty()) { + return true; + } + + // These remain the same under LEB128 unsigned encoding + if (!encoder.writeVarU32(0x0) || !encoder.writeVarU32(0x1) || + !encoder.writeVarU32(0x42)) { + return false; + } + + // 0x01 0x80 + if (!encoder.writeVarU32(0x80)) { + return false; + } + + // 0x03 0x80 + if (!encoder.writeVarU32(0x180)) { + return false; + } + + if (encoder.empty()) { + return true; + } + if (encoder.currentOffset() != 7) { + return true; + } + *passed = true; + return true; +} + +BEGIN_TEST(testWasmLEB128_encoding) { + using namespace js; + using namespace wasm; + + Bytes bytes; + Encoder encoder(bytes); + + bool passed; + if (!WriteValidBytes(encoder, &passed)) { + return false; + } + CHECK(passed); + + size_t i = 0; + CHECK(bytes[i++] == 0x0); + CHECK(bytes[i++] == 0x1); + CHECK(bytes[i++] == 0x42); + + CHECK(bytes[i++] == 0x80); + CHECK(bytes[i++] == 0x01); + + CHECK(bytes[i++] == 0x80); + CHECK(bytes[i++] == 0x03); + + if (i + 1 < bytes.length()) { + CHECK(bytes[i++] == 0x00); + } + return true; +} +END_TEST(testWasmLEB128_encoding) + +BEGIN_TEST(testWasmLEB128_valid_decoding) { + using namespace js; + using namespace wasm; + + Bytes bytes; + if (!bytes.append(0x0) || !bytes.append(0x1) || !bytes.append(0x42)) { + return false; + } + + if (!bytes.append(0x80) || !bytes.append(0x01)) { + return false; + } + + if (!bytes.append(0x80) || !bytes.append(0x03)) { + return false; + } + + { + // Fallible decoding + Decoder decoder(bytes); + uint32_t value; + + CHECK(decoder.readVarU32(&value) && value == 0x0); + CHECK(decoder.readVarU32(&value) && value == 0x1); + CHECK(decoder.readVarU32(&value) && value == 0x42); + CHECK(decoder.readVarU32(&value) && value == 0x80); + CHECK(decoder.readVarU32(&value) && value == 0x180); + + CHECK(decoder.done()); + } + + { + // Infallible decoding + Decoder decoder(bytes); + uint32_t value; + + value = decoder.uncheckedReadVarU32(); + CHECK(value == 0x0); + value = decoder.uncheckedReadVarU32(); + CHECK(value == 0x1); + value = decoder.uncheckedReadVarU32(); + CHECK(value == 0x42); + value = decoder.uncheckedReadVarU32(); + CHECK(value == 0x80); + value = decoder.uncheckedReadVarU32(); + CHECK(value == 0x180); + + CHECK(decoder.done()); + } + return true; +} +END_TEST(testWasmLEB128_valid_decoding) + +BEGIN_TEST(testWasmLEB128_invalid_decoding) { + using namespace js; + using namespace wasm; + + Bytes bytes; + // Fill bits as per 28 encoded bits + if (!bytes.append(0x80) || !bytes.append(0x80) || !bytes.append(0x80) || + !bytes.append(0x80)) { + return false; + } + + // Test last valid values + if (!bytes.append(0x00)) { + return false; + } + + for (uint8_t i = 0; i < 0x0F; i++) { + bytes[4] = i; + + { + Decoder decoder(bytes); + uint32_t value; + CHECK(decoder.readVarU32(&value)); + CHECK(value == uint32_t(i << 28)); + CHECK(decoder.done()); + } + + { + Decoder decoder(bytes); + uint32_t value = decoder.uncheckedReadVarU32(); + CHECK(value == uint32_t(i << 28)); + CHECK(decoder.done()); + } + } + + // Test all invalid values of the same size + for (uint8_t i = 0x10; i < 0xF0; i++) { + bytes[4] = i; + + Decoder decoder(bytes); + uint32_t value; + CHECK(!decoder.readVarU32(&value)); + } + + return true; +} +END_TEST(testWasmLEB128_invalid_decoding) |