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