7bace1d41a
The streaming decoder computed the code section start from the passed "offset". That offset is computed from the module offset *after* the number of functions has been read. Hence 1 is subtracted, with the comment: // The offset passed to {ProcessCodeSectionHeader} is an error offset and // not the start offset of a buffer. Therefore we need the -1 here. That subtraction of 1 worked when the number of functions was encoded in a 1-byte LEB, otherwise it was off. This CL fixes the immediate issue of passing the right code offset. The usage of the previously existing offset also seems wrong, and I will try to clean that up in a follow-up CL. R=ahaas@chromium.org CC=szuend@chromium.org Bug: chromium:1150303 Change-Id: I64bb2ececeb4749b7ba2096cd148ccb4079eca4f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2562383 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#71503}
670 lines
23 KiB
C++
670 lines
23 KiB
C++
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
#include "src/objects/objects-inl.h"
|
|
|
|
#include "src/wasm/module-decoder.h"
|
|
#include "src/wasm/streaming-decoder.h"
|
|
|
|
#include "src/objects/descriptor-array.h"
|
|
#include "src/objects/dictionary.h"
|
|
#include "test/common/wasm/wasm-macro-gen.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace wasm {
|
|
|
|
struct MockStreamingResult {
|
|
size_t num_sections = 0;
|
|
size_t num_functions = 0;
|
|
WasmError error;
|
|
OwnedVector<uint8_t> received_bytes;
|
|
|
|
bool ok() const { return !error.has_error(); }
|
|
|
|
MockStreamingResult() = default;
|
|
};
|
|
|
|
class MockStreamingProcessor : public StreamingProcessor {
|
|
public:
|
|
explicit MockStreamingProcessor(MockStreamingResult* result)
|
|
: result_(result) {}
|
|
|
|
bool ProcessModuleHeader(Vector<const uint8_t> bytes,
|
|
uint32_t offset) override {
|
|
Decoder decoder(bytes.begin(), bytes.end());
|
|
uint32_t magic_word = decoder.consume_u32("wasm magic");
|
|
if (decoder.failed() || magic_word != kWasmMagic) {
|
|
result_->error = WasmError(0, "expected wasm magic");
|
|
return false;
|
|
}
|
|
uint32_t magic_version = decoder.consume_u32("wasm version");
|
|
if (decoder.failed() || magic_version != kWasmVersion) {
|
|
result_->error = WasmError(4, "expected wasm version");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Process all sections but the code section.
|
|
bool ProcessSection(SectionCode section_code, Vector<const uint8_t> bytes,
|
|
uint32_t offset) override {
|
|
++result_->num_sections;
|
|
return true;
|
|
}
|
|
|
|
bool ProcessCodeSectionHeader(int num_functions, uint32_t offset,
|
|
std::shared_ptr<WireBytesStorage>,
|
|
int code_section_start,
|
|
int code_section_length) override {
|
|
return true;
|
|
}
|
|
|
|
// Process a function body.
|
|
bool ProcessFunctionBody(Vector<const uint8_t> bytes,
|
|
uint32_t offset) override {
|
|
++result_->num_functions;
|
|
return true;
|
|
}
|
|
|
|
void OnFinishedChunk() override {}
|
|
|
|
// Finish the processing of the stream.
|
|
void OnFinishedStream(OwnedVector<uint8_t> bytes) override {
|
|
result_->received_bytes = std::move(bytes);
|
|
}
|
|
|
|
// Report an error detected in the StreamingDecoder.
|
|
void OnError(const WasmError& error) override {
|
|
result_->error = error;
|
|
CHECK(!result_->ok());
|
|
}
|
|
|
|
void OnAbort() override {}
|
|
|
|
bool Deserialize(Vector<const uint8_t> module_bytes,
|
|
Vector<const uint8_t> wire_bytes) override {
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
MockStreamingResult* const result_;
|
|
};
|
|
|
|
class WasmStreamingDecoderTest : public ::testing::Test {
|
|
public:
|
|
void ExpectVerifies(Vector<const uint8_t> data, size_t expected_sections,
|
|
size_t expected_functions) {
|
|
for (int split = 0; split <= data.length(); ++split) {
|
|
MockStreamingResult result;
|
|
auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
|
|
std::make_unique<MockStreamingProcessor>(&result));
|
|
stream->OnBytesReceived(data.SubVector(0, split));
|
|
stream->OnBytesReceived(data.SubVector(split, data.length()));
|
|
stream->Finish();
|
|
EXPECT_TRUE(result.ok());
|
|
EXPECT_EQ(expected_sections, result.num_sections);
|
|
EXPECT_EQ(expected_functions, result.num_functions);
|
|
EXPECT_EQ(data, result.received_bytes.as_vector());
|
|
}
|
|
}
|
|
|
|
void ExpectFailure(Vector<const uint8_t> data, uint32_t error_offset,
|
|
const char* message) {
|
|
for (int split = 0; split <= data.length(); ++split) {
|
|
MockStreamingResult result;
|
|
auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
|
|
std::make_unique<MockStreamingProcessor>(&result));
|
|
stream->OnBytesReceived(data.SubVector(0, split));
|
|
stream->OnBytesReceived(data.SubVector(split, data.length()));
|
|
stream->Finish();
|
|
EXPECT_FALSE(result.ok());
|
|
EXPECT_EQ(error_offset, result.error.offset());
|
|
EXPECT_EQ(message, result.error.message());
|
|
}
|
|
}
|
|
};
|
|
|
|
TEST_F(WasmStreamingDecoderTest, EmptyStream) {
|
|
MockStreamingResult result;
|
|
auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
|
|
std::make_unique<MockStreamingProcessor>(&result));
|
|
stream->Finish();
|
|
EXPECT_FALSE(result.ok());
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, IncompleteModuleHeader) {
|
|
const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)};
|
|
{
|
|
MockStreamingResult result;
|
|
auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
|
|
std::make_unique<MockStreamingProcessor>(&result));
|
|
stream->OnBytesReceived(VectorOf(data, 1));
|
|
stream->Finish();
|
|
EXPECT_FALSE(result.ok());
|
|
}
|
|
for (uint32_t length = 1; length < sizeof(data); ++length) {
|
|
ExpectFailure(VectorOf(data, length), length - 1,
|
|
"unexpected end of stream");
|
|
}
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, MagicAndVersion) {
|
|
const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)};
|
|
ExpectVerifies(ArrayVector(data), 0, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, BadMagic) {
|
|
for (uint32_t x = 1; x; x <<= 1) {
|
|
const uint8_t data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion)};
|
|
ExpectFailure(ArrayVector(data), 0, "expected wasm magic");
|
|
}
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, BadVersion) {
|
|
for (uint32_t x = 1; x; x <<= 1) {
|
|
const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x)};
|
|
ExpectFailure(ArrayVector(data), 4, "expected wasm version");
|
|
}
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneSection) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x6, // Section Length
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0 // 6
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 1, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneSection_b) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x86, // Section Length = 6 (LEB)
|
|
0x0, // --
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0 // 6
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 1, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneShortSection) {
|
|
// Short section means that section length + payload is less than 5 bytes,
|
|
// which is the maximum size of the length field.
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x2, // Section Length
|
|
0x0, // Payload
|
|
0x0 // 2
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 1, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneShortSection_b) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x82, // Section Length = 2 (LEB)
|
|
0x80, // --
|
|
0x0, // --
|
|
0x0, // Payload
|
|
0x0 // 2
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 1, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneEmptySection) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x0 // Section Length
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 1, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneSectionNotEnoughPayload1) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x6, // Section Length
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0 // 5
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"unexpected end of stream");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneSectionNotEnoughPayload2) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x6, // Section Length
|
|
0x0 // Payload
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"unexpected end of stream");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneSectionInvalidLength) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x80, // Section Length (invalid LEB)
|
|
0x80, // --
|
|
0x80, // --
|
|
0x80, // --
|
|
0x80, // --
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1, "expected section length");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoLongSections) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x6, // Section Length
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x2, // Section ID
|
|
0x7, // Section Length
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0 // 7
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 2, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoShortSections) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x1, // Section Length
|
|
0x0, // Payload
|
|
0x2, // Section ID
|
|
0x2, // Section Length
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 2, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoSectionsShortLong) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x1, // Section Length
|
|
0x0, // Payload
|
|
0x2, // Section ID
|
|
0x7, // Section Length
|
|
0x0, // Payload
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0 // 7
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 2, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoEmptySections) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
0x1, // Section ID
|
|
0x0, // Section Length
|
|
0x2, // Section ID
|
|
0x0 // Section Length
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 2, 0);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneFunction) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x8, // Section Length
|
|
0x1, // Number of Functions
|
|
0x6, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 0, 1);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, OneShortFunction) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x3, // Section Length
|
|
0x1, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 0, 1);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, EmptyFunction) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x2, // Section Length
|
|
0x1, // Number of Functions
|
|
0x0, // Function Length -- ERROR
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"invalid function length (0)");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoFunctions) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x10, // Section Length
|
|
0x2, // Number of Functions
|
|
0x6, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x7, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0, // 7
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 0, 2);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoFunctions_b) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0xB, // Section Length
|
|
0x2, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
0x7, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0, // 7
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 0, 2);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthZero) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x0, // Section Length
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"code section cannot have size 0");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHigh) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0xD, // Section Length
|
|
0x2, // Number of Functions
|
|
0x7, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0, // 7
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"not all code section bytes were used");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHighZeroFunctions) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0xD, // Section Length
|
|
0x0, // Number of Functions
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"not all code section bytes were used");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLow) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x9, // Section Length
|
|
0x2, // Number of Functions <0>
|
|
0x7, // Function Length <1>
|
|
0x0, // Function <2>
|
|
0x0, // 2 <3>
|
|
0x0, // 3 <3>
|
|
0x0, // 4 <4>
|
|
0x0, // 5 <5>
|
|
0x0, // 6 <6>
|
|
0x0, // 7 <7>
|
|
0x1, // Function Length <8> -- ERROR
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 2,
|
|
"read past code section end");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLowEndsInNumFunctions) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x1, // Section Length
|
|
0x82, // Number of Functions <0>
|
|
0x80, // -- <1> -- ERROR
|
|
0x00, // --
|
|
0x7, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0, // 7
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), 12, "invalid code section length");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLowEndsInFunctionLength) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x5, // Section Length
|
|
0x82, // Number of Functions <0>
|
|
0x80, // -- <1>
|
|
0x00, // -- <2>
|
|
0x87, // Function Length <3>
|
|
0x80, // -- <4>
|
|
0x00, // -- <5> -- ERROR
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0, // 7
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), 15, "read past code section end");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, NumberOfFunctionsTooHigh) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0xB, // Section Length
|
|
0x4, // Number of Functions
|
|
0x7, // Function Length
|
|
0x0, // Function
|
|
0x0, // 2
|
|
0x0, // 3
|
|
0x0, // 4
|
|
0x0, // 5
|
|
0x0, // 6
|
|
0x0, // 7
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 1,
|
|
"unexpected end of stream");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, NumberOfFunctionsTooLow) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x8, // Section Length
|
|
0x2, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
0x2, // Function Length
|
|
0x0, // Function byte#0
|
|
0x0, // Function byte#1 -- ERROR
|
|
0x1, // Function Length
|
|
0x0 // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 3,
|
|
"not all code section bytes were used");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, TwoCodeSections) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x3, // Section Length
|
|
0x1, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
kCodeSectionCode, // Section ID -- ERROR
|
|
0x3, // Section Length
|
|
0x1, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 5,
|
|
"code section can only appear once");
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, UnknownSection) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x3, // Section Length
|
|
0x1, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
kUnknownSectionCode, // Section ID
|
|
0x3, // Section Length
|
|
0x1, // Name Length
|
|
0x1, // Name
|
|
0x0, // Content
|
|
};
|
|
ExpectVerifies(ArrayVector(data), 1, 1);
|
|
}
|
|
|
|
TEST_F(WasmStreamingDecoderTest, UnknownSectionSandwich) {
|
|
const uint8_t data[] = {
|
|
U32_LE(kWasmMagic), // --
|
|
U32_LE(kWasmVersion), // --
|
|
kCodeSectionCode, // Section ID
|
|
0x3, // Section Length
|
|
0x1, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
kUnknownSectionCode, // Section ID
|
|
0x3, // Section Length
|
|
0x1, // Name Length
|
|
0x1, // Name
|
|
0x0, // Content
|
|
kCodeSectionCode, // Section ID -- ERROR
|
|
0x3, // Section Length
|
|
0x1, // Number of Functions
|
|
0x1, // Function Length
|
|
0x0, // Function
|
|
};
|
|
ExpectFailure(ArrayVector(data), sizeof(data) - 5,
|
|
"code section can only appear once");
|
|
}
|
|
|
|
} // namespace wasm
|
|
} // namespace internal
|
|
} // namespace v8
|