/* 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/WasmBinaryFormat.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)