streaming-decoder-unittest.cc 23 KB
Newer Older
1 2 3 4 5 6
// 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"

7
#include "src/objects/objects-inl.h"
8 9 10 11 12 13 14 15 16 17 18 19

#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 {

20 21 22
struct MockStreamingResult {
  size_t num_sections = 0;
  size_t num_functions = 0;
23
  WasmError error;
24
  base::OwnedVector<uint8_t> received_bytes;
25

26 27
  bool ok() const { return !error.has_error(); }

28 29 30
  MockStreamingResult() = default;
};

31 32
class MockStreamingProcessor : public StreamingProcessor {
 public:
33 34 35
  explicit MockStreamingProcessor(MockStreamingResult* result)
      : result_(result) {}

36
  bool ProcessModuleHeader(base::Vector<const uint8_t> bytes,
37 38 39 40
                           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) {
41
      result_->error = WasmError(0, "expected wasm magic");
42 43 44 45
      return false;
    }
    uint32_t magic_version = decoder.consume_u32("wasm version");
    if (decoder.failed() || magic_version != kWasmVersion) {
46
      result_->error = WasmError(4, "expected wasm version");
47 48 49 50
      return false;
    }
    return true;
  }
51

52
  // Process all sections but the code section.
53 54
  bool ProcessSection(SectionCode section_code,
                      base::Vector<const uint8_t> bytes,
55
                      uint32_t offset) override {
56
    ++result_->num_sections;
57 58 59
    return true;
  }

60
  bool ProcessCodeSectionHeader(int num_functions, uint32_t offset,
61
                                std::shared_ptr<WireBytesStorage>,
62
                                int code_section_start,
63
                                int code_section_length) override {
64 65 66 67
    return true;
  }

  // Process a function body.
68
  bool ProcessFunctionBody(base::Vector<const uint8_t> bytes,
69
                           uint32_t offset) override {
70
    ++result_->num_functions;
71 72 73 74 75 76
    return true;
  }

  void OnFinishedChunk() override {}

  // Finish the processing of the stream.
77
  void OnFinishedStream(base::OwnedVector<uint8_t> bytes) override {
78
    result_->received_bytes = std::move(bytes);
79 80 81
  }

  // Report an error detected in the StreamingDecoder.
82 83 84 85
  void OnError(const WasmError& error) override {
    result_->error = error;
    CHECK(!result_->ok());
  }
86 87 88

  void OnAbort() override {}

89 90
  bool Deserialize(base::Vector<const uint8_t> module_bytes,
                   base::Vector<const uint8_t> wire_bytes) override {
91
    return false;
92
  }
93

94
 private:
95
  MockStreamingResult* const result_;
96 97
};

98 99
class WasmStreamingDecoderTest : public ::testing::Test {
 public:
100 101
  void ExpectVerifies(base::Vector<const uint8_t> data,
                      size_t expected_sections, size_t expected_functions) {
102
    for (int split = 0; split <= data.length(); ++split) {
103
      MockStreamingResult result;
104
      auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
105
          std::make_unique<MockStreamingProcessor>(&result));
106 107 108
      stream->OnBytesReceived(data.SubVector(0, split));
      stream->OnBytesReceived(data.SubVector(split, data.length()));
      stream->Finish();
109
      EXPECT_TRUE(result.ok());
110 111 112
      EXPECT_EQ(expected_sections, result.num_sections);
      EXPECT_EQ(expected_functions, result.num_functions);
      EXPECT_EQ(data, result.received_bytes.as_vector());
113 114 115
    }
  }

116
  void ExpectFailure(base::Vector<const uint8_t> data, uint32_t error_offset,
117
                     const char* message) {
118
    for (int split = 0; split <= data.length(); ++split) {
119
      MockStreamingResult result;
120
      auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
121
          std::make_unique<MockStreamingProcessor>(&result));
122 123 124
      stream->OnBytesReceived(data.SubVector(0, split));
      stream->OnBytesReceived(data.SubVector(split, data.length()));
      stream->Finish();
125
      EXPECT_FALSE(result.ok());
126
      EXPECT_EQ(error_offset, result.error.offset());
127
      EXPECT_EQ(message, result.error.message());
128 129 130 131 132
    }
  }
};

TEST_F(WasmStreamingDecoderTest, EmptyStream) {
133
  MockStreamingResult result;
134 135 136
  auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
      std::make_unique<MockStreamingProcessor>(&result));
  stream->Finish();
137
  EXPECT_FALSE(result.ok());
138 139 140 141 142
}

TEST_F(WasmStreamingDecoderTest, IncompleteModuleHeader) {
  const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)};
  {
143
    MockStreamingResult result;
144 145
    auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
        std::make_unique<MockStreamingProcessor>(&result));
146
    stream->OnBytesReceived(base::VectorOf(data, 1));
147
    stream->Finish();
148
    EXPECT_FALSE(result.ok());
149
  }
150
  for (uint32_t length = 1; length < sizeof(data); ++length) {
151
    ExpectFailure(base::VectorOf(data, length), length - 1,
152
                  "unexpected end of stream");
153 154 155 156 157
  }
}

TEST_F(WasmStreamingDecoderTest, MagicAndVersion) {
  const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)};
158
  ExpectVerifies(base::ArrayVector(data), 0, 0);
159 160 161 162 163
}

TEST_F(WasmStreamingDecoderTest, BadMagic) {
  for (uint32_t x = 1; x; x <<= 1) {
    const uint8_t data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion)};
164
    ExpectFailure(base::ArrayVector(data), 0, "expected wasm magic");
165 166 167 168 169 170
  }
}

TEST_F(WasmStreamingDecoderTest, BadVersion) {
  for (uint32_t x = 1; x; x <<= 1) {
    const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x)};
171
    ExpectFailure(base::ArrayVector(data), 4, "expected wasm version");
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
  }
}

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
  };
188
  ExpectVerifies(base::ArrayVector(data), 1, 0);
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
}

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
  };
205
  ExpectVerifies(base::ArrayVector(data), 1, 0);
206 207 208 209 210 211 212 213 214 215 216 217 218
}

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
  };
219
  ExpectVerifies(base::ArrayVector(data), 1, 0);
220 221 222 223 224 225 226 227 228 229 230 231 232
}

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
  };
233
  ExpectVerifies(base::ArrayVector(data), 1, 0);
234 235 236 237 238 239 240 241 242
}

TEST_F(WasmStreamingDecoderTest, OneEmptySection) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      0x1,                   // Section ID
      0x0                    // Section Length
  };
243
  ExpectVerifies(base::ArrayVector(data), 1, 0);
244 245 246 247 248 249 250 251 252 253 254 255 256 257
}

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
  };
258
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
259
                "unexpected end of stream");
260 261 262 263 264 265 266 267 268 269
}

TEST_F(WasmStreamingDecoderTest, OneSectionNotEnoughPayload2) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      0x1,                   // Section ID
      0x6,                   // Section Length
      0x0                    // Payload
  };
270
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
271
                "unexpected end of stream");
272 273 274 275 276 277 278
}

TEST_F(WasmStreamingDecoderTest, OneSectionInvalidLength) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      0x1,                   // Section ID
279
      0x80,                  // Section Length (invalid LEB)
280 281 282 283 284
      0x80,                  // --
      0x80,                  // --
      0x80,                  // --
      0x80,                  // --
  };
285 286
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
                "expected section length");
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
}

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
  };
311
  ExpectVerifies(base::ArrayVector(data), 2, 0);
312 313 314 315 316 317 318 319 320 321 322 323 324 325
}

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
  };
326
  ExpectVerifies(base::ArrayVector(data), 2, 0);
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
}

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
  };
346
  ExpectVerifies(base::ArrayVector(data), 2, 0);
347 348 349 350 351 352 353 354 355 356 357
}

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
  };
358
  ExpectVerifies(base::ArrayVector(data), 2, 0);
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
}

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
  };
376
  ExpectVerifies(base::ArrayVector(data), 0, 1);
377 378 379 380 381 382 383 384 385 386 387 388
}

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
  };
389
  ExpectVerifies(base::ArrayVector(data), 0, 1);
390 391 392 393 394 395 396 397 398
}

TEST_F(WasmStreamingDecoderTest, EmptyFunction) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
      0x2,                   // Section Length
      0x1,                   // Number of Functions
399
      0x0,                   // Function Length  -- ERROR
400
  };
401
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
402
                "invalid function length (0)");
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
}

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
  };
428
  ExpectVerifies(base::ArrayVector(data), 0, 2);
429 430 431 432 433 434 435
}

TEST_F(WasmStreamingDecoderTest, TwoFunctions_b) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
436
      0xB,                   // Section Length
437 438 439 440 441 442 443 444 445 446 447 448
      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
  };
449
  ExpectVerifies(base::ArrayVector(data), 0, 2);
450 451 452 453 454 455 456 457 458
}

TEST_F(WasmStreamingDecoderTest, CodeSectionLengthZero) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
      0x0,                   // Section Length
  };
459
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
460
                "code section cannot have size 0");
461 462 463 464 465 466 467
}

TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHigh) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
468
      0xD,                   // Section Length
469 470 471 472 473 474 475 476 477 478 479 480
      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
  };
481
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
482
                "not all code section bytes were used");
483 484
}

485 486 487 488 489
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHighZeroFunctions) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
490
      0xD,                   // Section Length
491 492
      0x0,                   // Number of Functions
  };
493
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
494
                "not all code section bytes were used");
495 496
}

497 498 499 500 501 502
TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLow) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
      0x9,                   // Section Length
503 504 505 506 507 508 509 510 511 512
      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
513 514
      0x0,                   // Function
  };
515
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 2,
516
                "read past code section end");
517 518 519 520 521 522 523 524
}

TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLowEndsInNumFunctions) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
      0x1,                   // Section Length
525 526
      0x82,                  // Number of Functions  <0>
      0x80,                  // --                   <1> -- ERROR
527 528 529 530 531 532 533 534 535 536 537 538
      0x00,                  // --
      0x7,                   // Function Length
      0x0,                   // Function
      0x0,                   // 2
      0x0,                   // 3
      0x0,                   // 4
      0x0,                   // 5
      0x0,                   // 6
      0x0,                   // 7
      0x1,                   // Function Length
      0x0,                   // Function
  };
539
  ExpectFailure(base::ArrayVector(data), 12, "invalid code section length");
540 541 542 543 544 545 546 547
}

TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLowEndsInFunctionLength) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
      0x5,                   // Section Length
548 549 550 551 552 553
      0x82,                  // Number of Functions  <0>
      0x80,                  // --                   <1>
      0x00,                  // --                   <2>
      0x87,                  // Function Length      <3>
      0x80,                  // --                   <4>
      0x00,                  // --                   <5> -- ERROR
554 555 556 557 558 559 560 561 562 563
      0x0,                   // Function
      0x0,                   // 2
      0x0,                   // 3
      0x0,                   // 4
      0x0,                   // 5
      0x0,                   // 6
      0x0,                   // 7
      0x1,                   // Function Length
      0x0,                   // Function
  };
564
  ExpectFailure(base::ArrayVector(data), 15, "read past code section end");
565 566 567 568 569 570 571
}

TEST_F(WasmStreamingDecoderTest, NumberOfFunctionsTooHigh) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
572
      0xB,                   // Section Length
573 574 575 576 577 578 579 580 581 582 583 584
      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
  };
585
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
586
                "unexpected end of stream");
587 588 589 590 591 592 593
}

TEST_F(WasmStreamingDecoderTest, NumberOfFunctionsTooLow) {
  const uint8_t data[] = {
      U32_LE(kWasmMagic),    // --
      U32_LE(kWasmVersion),  // --
      kCodeSectionCode,      // Section ID
594
      0x8,                   // Section Length
595 596 597 598
      0x2,                   // Number of Functions
      0x1,                   // Function Length
      0x0,                   // Function
      0x2,                   // Function Length
599 600 601 602
      0x0,                   // Function byte#0
      0x0,                   // Function byte#1   -- ERROR
      0x1,                   // Function Length
      0x0                    // Function
603
  };
604
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 3,
605
                "not all code section bytes were used");
606
}
607 608 609 610 611 612 613 614 615 616

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
617 618
      kCodeSectionCode,      // Section ID      -- ERROR
      0x3,                   // Section Length
619 620 621 622
      0x1,                   // Number of Functions
      0x1,                   // Function Length
      0x0,                   // Function
  };
623
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 5,
624
                "code section can only appear once");
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
}

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
  };
642
  ExpectVerifies(base::ArrayVector(data), 1, 1);
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
}

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
659 660
      kCodeSectionCode,      // Section ID     -- ERROR
      0x3,                   // Section Length
661 662 663 664
      0x1,                   // Number of Functions
      0x1,                   // Function Length
      0x0,                   // Function
  };
665
  ExpectFailure(base::ArrayVector(data), sizeof(data) - 5,
666
                "code section can only appear once");
667 668
}

669 670 671
}  // namespace wasm
}  // namespace internal
}  // namespace v8