1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "test/unittests/test-utils.h"
6
7 #include "src/objects/objects-inl.h"
8
9 #include "src/wasm/module-decoder.h"
10 #include "src/wasm/streaming-decoder.h"
11
12 #include "src/objects/descriptor-array.h"
13 #include "src/objects/dictionary.h"
14 #include "test/common/wasm/wasm-macro-gen.h"
15
16 namespace v8 {
17 namespace internal {
18 namespace wasm {
19
20 struct MockStreamingResult {
21 size_t num_sections = 0;
22 size_t num_functions = 0;
23 WasmError error;
24 base::OwnedVector<uint8_t> received_bytes;
25
okv8::internal::wasm::MockStreamingResult26 bool ok() const { return !error.has_error(); }
27
28 MockStreamingResult() = default;
29 };
30
31 class MockStreamingProcessor : public StreamingProcessor {
32 public:
MockStreamingProcessor(MockStreamingResult * result)33 explicit MockStreamingProcessor(MockStreamingResult* result)
34 : result_(result) {}
35
ProcessModuleHeader(base::Vector<const uint8_t> bytes,uint32_t offset)36 bool ProcessModuleHeader(base::Vector<const uint8_t> bytes,
37 uint32_t offset) override {
38 Decoder decoder(bytes.begin(), bytes.end());
39 uint32_t magic_word = decoder.consume_u32("wasm magic");
40 if (decoder.failed() || magic_word != kWasmMagic) {
41 result_->error = WasmError(0, "expected wasm magic");
42 return false;
43 }
44 uint32_t magic_version = decoder.consume_u32("wasm version");
45 if (decoder.failed() || magic_version != kWasmVersion) {
46 result_->error = WasmError(4, "expected wasm version");
47 return false;
48 }
49 return true;
50 }
51
52 // Process all sections but the code section.
ProcessSection(SectionCode section_code,base::Vector<const uint8_t> bytes,uint32_t offset)53 bool ProcessSection(SectionCode section_code,
54 base::Vector<const uint8_t> bytes,
55 uint32_t offset) override {
56 ++result_->num_sections;
57 return true;
58 }
59
ProcessCodeSectionHeader(int num_functions,uint32_t offset,std::shared_ptr<WireBytesStorage>,int code_section_start,int code_section_length)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 return true;
65 }
66
67 // Process a function body.
ProcessFunctionBody(base::Vector<const uint8_t> bytes,uint32_t offset)68 bool ProcessFunctionBody(base::Vector<const uint8_t> bytes,
69 uint32_t offset) override {
70 ++result_->num_functions;
71 return true;
72 }
73
OnFinishedChunk()74 void OnFinishedChunk() override {}
75
76 // Finish the processing of the stream.
OnFinishedStream(base::OwnedVector<uint8_t> bytes)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.
OnError(const WasmError & error)82 void OnError(const WasmError& error) override {
83 result_->error = error;
84 CHECK(!result_->ok());
85 }
86
OnAbort()87 void OnAbort() override {}
88
Deserialize(base::Vector<const uint8_t> module_bytes,base::Vector<const uint8_t> wire_bytes)89 bool Deserialize(base::Vector<const uint8_t> module_bytes,
90 base::Vector<const uint8_t> wire_bytes) override {
91 return false;
92 }
93
94 private:
95 MockStreamingResult* const result_;
96 };
97
98 class WasmStreamingDecoderTest : public ::testing::Test {
99 public:
ExpectVerifies(base::Vector<const uint8_t> data,size_t expected_sections,size_t expected_functions)100 void ExpectVerifies(base::Vector<const uint8_t> data,
101 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 stream->OnBytesReceived(data.SubVector(0, split));
107 stream->OnBytesReceived(data.SubVector(split, data.length()));
108 stream->Finish();
109 EXPECT_TRUE(result.ok());
110 EXPECT_EQ(expected_sections, result.num_sections);
111 EXPECT_EQ(expected_functions, result.num_functions);
112 EXPECT_EQ(data, result.received_bytes.as_vector());
113 }
114 }
115
ExpectFailure(base::Vector<const uint8_t> data,uint32_t error_offset,const char * message)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 stream->OnBytesReceived(data.SubVector(0, split));
123 stream->OnBytesReceived(data.SubVector(split, data.length()));
124 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
TEST_F(WasmStreamingDecoderTest,EmptyStream)132 TEST_F(WasmStreamingDecoderTest, EmptyStream) {
133 MockStreamingResult result;
134 auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
135 std::make_unique<MockStreamingProcessor>(&result));
136 stream->Finish();
137 EXPECT_FALSE(result.ok());
138 }
139
TEST_F(WasmStreamingDecoderTest,IncompleteModuleHeader)140 TEST_F(WasmStreamingDecoderTest, IncompleteModuleHeader) {
141 const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)};
142 {
143 MockStreamingResult result;
144 auto stream = StreamingDecoder::CreateAsyncStreamingDecoder(
145 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
TEST_F(WasmStreamingDecoderTest,MagicAndVersion)156 TEST_F(WasmStreamingDecoderTest, MagicAndVersion) {
157 const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)};
158 ExpectVerifies(base::ArrayVector(data), 0, 0);
159 }
160
TEST_F(WasmStreamingDecoderTest,BadMagic)161 TEST_F(WasmStreamingDecoderTest, BadMagic) {
162 for (uint32_t x = 1; x; x <<= 1) {
163 const uint8_t data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion)};
164 ExpectFailure(base::ArrayVector(data), 0, "expected wasm magic");
165 }
166 }
167
TEST_F(WasmStreamingDecoderTest,BadVersion)168 TEST_F(WasmStreamingDecoderTest, BadVersion) {
169 for (uint32_t x = 1; x; x <<= 1) {
170 const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x)};
171 ExpectFailure(base::ArrayVector(data), 4, "expected wasm version");
172 }
173 }
174
TEST_F(WasmStreamingDecoderTest,OneSection)175 TEST_F(WasmStreamingDecoderTest, OneSection) {
176 const uint8_t data[] = {
177 U32_LE(kWasmMagic), // --
178 U32_LE(kWasmVersion), // --
179 0x1, // Section ID
180 0x6, // Section Length
181 0x0, // Payload
182 0x0, // 2
183 0x0, // 3
184 0x0, // 4
185 0x0, // 5
186 0x0 // 6
187 };
188 ExpectVerifies(base::ArrayVector(data), 1, 0);
189 }
190
TEST_F(WasmStreamingDecoderTest,OneSection_b)191 TEST_F(WasmStreamingDecoderTest, OneSection_b) {
192 const uint8_t data[] = {
193 U32_LE(kWasmMagic), // --
194 U32_LE(kWasmVersion), // --
195 0x1, // Section ID
196 0x86, // Section Length = 6 (LEB)
197 0x0, // --
198 0x0, // Payload
199 0x0, // 2
200 0x0, // 3
201 0x0, // 4
202 0x0, // 5
203 0x0 // 6
204 };
205 ExpectVerifies(base::ArrayVector(data), 1, 0);
206 }
207
TEST_F(WasmStreamingDecoderTest,OneShortSection)208 TEST_F(WasmStreamingDecoderTest, OneShortSection) {
209 // Short section means that section length + payload is less than 5 bytes,
210 // which is the maximum size of the length field.
211 const uint8_t data[] = {
212 U32_LE(kWasmMagic), // --
213 U32_LE(kWasmVersion), // --
214 0x1, // Section ID
215 0x2, // Section Length
216 0x0, // Payload
217 0x0 // 2
218 };
219 ExpectVerifies(base::ArrayVector(data), 1, 0);
220 }
221
TEST_F(WasmStreamingDecoderTest,OneShortSection_b)222 TEST_F(WasmStreamingDecoderTest, OneShortSection_b) {
223 const uint8_t data[] = {
224 U32_LE(kWasmMagic), // --
225 U32_LE(kWasmVersion), // --
226 0x1, // Section ID
227 0x82, // Section Length = 2 (LEB)
228 0x80, // --
229 0x0, // --
230 0x0, // Payload
231 0x0 // 2
232 };
233 ExpectVerifies(base::ArrayVector(data), 1, 0);
234 }
235
TEST_F(WasmStreamingDecoderTest,OneEmptySection)236 TEST_F(WasmStreamingDecoderTest, OneEmptySection) {
237 const uint8_t data[] = {
238 U32_LE(kWasmMagic), // --
239 U32_LE(kWasmVersion), // --
240 0x1, // Section ID
241 0x0 // Section Length
242 };
243 ExpectVerifies(base::ArrayVector(data), 1, 0);
244 }
245
TEST_F(WasmStreamingDecoderTest,OneSectionNotEnoughPayload1)246 TEST_F(WasmStreamingDecoderTest, OneSectionNotEnoughPayload1) {
247 const uint8_t data[] = {
248 U32_LE(kWasmMagic), // --
249 U32_LE(kWasmVersion), // --
250 0x1, // Section ID
251 0x6, // Section Length
252 0x0, // Payload
253 0x0, // 2
254 0x0, // 3
255 0x0, // 4
256 0x0 // 5
257 };
258 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
259 "unexpected end of stream");
260 }
261
TEST_F(WasmStreamingDecoderTest,OneSectionNotEnoughPayload2)262 TEST_F(WasmStreamingDecoderTest, OneSectionNotEnoughPayload2) {
263 const uint8_t data[] = {
264 U32_LE(kWasmMagic), // --
265 U32_LE(kWasmVersion), // --
266 0x1, // Section ID
267 0x6, // Section Length
268 0x0 // Payload
269 };
270 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
271 "unexpected end of stream");
272 }
273
TEST_F(WasmStreamingDecoderTest,OneSectionInvalidLength)274 TEST_F(WasmStreamingDecoderTest, OneSectionInvalidLength) {
275 const uint8_t data[] = {
276 U32_LE(kWasmMagic), // --
277 U32_LE(kWasmVersion), // --
278 0x1, // Section ID
279 0x80, // Section Length (invalid LEB)
280 0x80, // --
281 0x80, // --
282 0x80, // --
283 0x80, // --
284 };
285 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
286 "expected section length");
287 }
288
TEST_F(WasmStreamingDecoderTest,TwoLongSections)289 TEST_F(WasmStreamingDecoderTest, TwoLongSections) {
290 const uint8_t data[] = {
291 U32_LE(kWasmMagic), // --
292 U32_LE(kWasmVersion), // --
293 0x1, // Section ID
294 0x6, // Section Length
295 0x0, // Payload
296 0x0, // 2
297 0x0, // 3
298 0x0, // 4
299 0x0, // 5
300 0x0, // 6
301 0x2, // Section ID
302 0x7, // Section Length
303 0x0, // Payload
304 0x0, // 2
305 0x0, // 3
306 0x0, // 4
307 0x0, // 5
308 0x0, // 6
309 0x0 // 7
310 };
311 ExpectVerifies(base::ArrayVector(data), 2, 0);
312 }
313
TEST_F(WasmStreamingDecoderTest,TwoShortSections)314 TEST_F(WasmStreamingDecoderTest, TwoShortSections) {
315 const uint8_t data[] = {
316 U32_LE(kWasmMagic), // --
317 U32_LE(kWasmVersion), // --
318 0x1, // Section ID
319 0x1, // Section Length
320 0x0, // Payload
321 0x2, // Section ID
322 0x2, // Section Length
323 0x0, // Payload
324 0x0, // 2
325 };
326 ExpectVerifies(base::ArrayVector(data), 2, 0);
327 }
328
TEST_F(WasmStreamingDecoderTest,TwoSectionsShortLong)329 TEST_F(WasmStreamingDecoderTest, TwoSectionsShortLong) {
330 const uint8_t data[] = {
331 U32_LE(kWasmMagic), // --
332 U32_LE(kWasmVersion), // --
333 0x1, // Section ID
334 0x1, // Section Length
335 0x0, // Payload
336 0x2, // Section ID
337 0x7, // Section Length
338 0x0, // Payload
339 0x0, // 2
340 0x0, // 3
341 0x0, // 4
342 0x0, // 5
343 0x0, // 6
344 0x0 // 7
345 };
346 ExpectVerifies(base::ArrayVector(data), 2, 0);
347 }
348
TEST_F(WasmStreamingDecoderTest,TwoEmptySections)349 TEST_F(WasmStreamingDecoderTest, TwoEmptySections) {
350 const uint8_t data[] = {
351 U32_LE(kWasmMagic), // --
352 U32_LE(kWasmVersion), // --
353 0x1, // Section ID
354 0x0, // Section Length
355 0x2, // Section ID
356 0x0 // Section Length
357 };
358 ExpectVerifies(base::ArrayVector(data), 2, 0);
359 }
360
TEST_F(WasmStreamingDecoderTest,OneFunction)361 TEST_F(WasmStreamingDecoderTest, OneFunction) {
362 const uint8_t data[] = {
363 U32_LE(kWasmMagic), // --
364 U32_LE(kWasmVersion), // --
365 kCodeSectionCode, // Section ID
366 0x8, // Section Length
367 0x1, // Number of Functions
368 0x6, // Function Length
369 0x0, // Function
370 0x0, // 2
371 0x0, // 3
372 0x0, // 4
373 0x0, // 5
374 0x0, // 6
375 };
376 ExpectVerifies(base::ArrayVector(data), 0, 1);
377 }
378
TEST_F(WasmStreamingDecoderTest,OneShortFunction)379 TEST_F(WasmStreamingDecoderTest, OneShortFunction) {
380 const uint8_t data[] = {
381 U32_LE(kWasmMagic), // --
382 U32_LE(kWasmVersion), // --
383 kCodeSectionCode, // Section ID
384 0x3, // Section Length
385 0x1, // Number of Functions
386 0x1, // Function Length
387 0x0, // Function
388 };
389 ExpectVerifies(base::ArrayVector(data), 0, 1);
390 }
391
TEST_F(WasmStreamingDecoderTest,EmptyFunction)392 TEST_F(WasmStreamingDecoderTest, EmptyFunction) {
393 const uint8_t data[] = {
394 U32_LE(kWasmMagic), // --
395 U32_LE(kWasmVersion), // --
396 kCodeSectionCode, // Section ID
397 0x2, // Section Length
398 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
TEST_F(WasmStreamingDecoderTest,TwoFunctions)405 TEST_F(WasmStreamingDecoderTest, TwoFunctions) {
406 const uint8_t data[] = {
407 U32_LE(kWasmMagic), // --
408 U32_LE(kWasmVersion), // --
409 kCodeSectionCode, // Section ID
410 0x10, // Section Length
411 0x2, // Number of Functions
412 0x6, // Function Length
413 0x0, // Function
414 0x0, // 2
415 0x0, // 3
416 0x0, // 4
417 0x0, // 5
418 0x0, // 6
419 0x7, // Function Length
420 0x0, // Function
421 0x0, // 2
422 0x0, // 3
423 0x0, // 4
424 0x0, // 5
425 0x0, // 6
426 0x0, // 7
427 };
428 ExpectVerifies(base::ArrayVector(data), 0, 2);
429 }
430
TEST_F(WasmStreamingDecoderTest,TwoFunctions_b)431 TEST_F(WasmStreamingDecoderTest, TwoFunctions_b) {
432 const uint8_t data[] = {
433 U32_LE(kWasmMagic), // --
434 U32_LE(kWasmVersion), // --
435 kCodeSectionCode, // Section ID
436 0xB, // Section Length
437 0x2, // Number of Functions
438 0x1, // Function Length
439 0x0, // Function
440 0x7, // Function Length
441 0x0, // Function
442 0x0, // 2
443 0x0, // 3
444 0x0, // 4
445 0x0, // 5
446 0x0, // 6
447 0x0, // 7
448 };
449 ExpectVerifies(base::ArrayVector(data), 0, 2);
450 }
451
TEST_F(WasmStreamingDecoderTest,CodeSectionLengthZero)452 TEST_F(WasmStreamingDecoderTest, CodeSectionLengthZero) {
453 const uint8_t data[] = {
454 U32_LE(kWasmMagic), // --
455 U32_LE(kWasmVersion), // --
456 kCodeSectionCode, // Section ID
457 0x0, // Section Length
458 };
459 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
460 "code section cannot have size 0");
461 }
462
TEST_F(WasmStreamingDecoderTest,CodeSectionLengthTooHigh)463 TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHigh) {
464 const uint8_t data[] = {
465 U32_LE(kWasmMagic), // --
466 U32_LE(kWasmVersion), // --
467 kCodeSectionCode, // Section ID
468 0xD, // Section Length
469 0x2, // Number of Functions
470 0x7, // Function Length
471 0x0, // Function
472 0x0, // 2
473 0x0, // 3
474 0x0, // 4
475 0x0, // 5
476 0x0, // 6
477 0x0, // 7
478 0x1, // Function Length
479 0x0, // Function
480 };
481 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
482 "not all code section bytes were used");
483 }
484
TEST_F(WasmStreamingDecoderTest,CodeSectionLengthTooHighZeroFunctions)485 TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooHighZeroFunctions) {
486 const uint8_t data[] = {
487 U32_LE(kWasmMagic), // --
488 U32_LE(kWasmVersion), // --
489 kCodeSectionCode, // Section ID
490 0xD, // Section Length
491 0x0, // Number of Functions
492 };
493 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
494 "not all code section bytes were used");
495 }
496
TEST_F(WasmStreamingDecoderTest,CodeSectionLengthTooLow)497 TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLow) {
498 const uint8_t data[] = {
499 U32_LE(kWasmMagic), // --
500 U32_LE(kWasmVersion), // --
501 kCodeSectionCode, // Section ID
502 0x9, // Section Length
503 0x2, // Number of Functions <0>
504 0x7, // Function Length <1>
505 0x0, // Function <2>
506 0x0, // 2 <3>
507 0x0, // 3 <3>
508 0x0, // 4 <4>
509 0x0, // 5 <5>
510 0x0, // 6 <6>
511 0x0, // 7 <7>
512 0x1, // Function Length <8> -- ERROR
513 0x0, // Function
514 };
515 ExpectFailure(base::ArrayVector(data), sizeof(data) - 2,
516 "read past code section end");
517 }
518
TEST_F(WasmStreamingDecoderTest,CodeSectionLengthTooLowEndsInNumFunctions)519 TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLowEndsInNumFunctions) {
520 const uint8_t data[] = {
521 U32_LE(kWasmMagic), // --
522 U32_LE(kWasmVersion), // --
523 kCodeSectionCode, // Section ID
524 0x1, // Section Length
525 0x82, // Number of Functions <0>
526 0x80, // -- <1> -- ERROR
527 0x00, // --
528 0x7, // Function Length
529 0x0, // Function
530 0x0, // 2
531 0x0, // 3
532 0x0, // 4
533 0x0, // 5
534 0x0, // 6
535 0x0, // 7
536 0x1, // Function Length
537 0x0, // Function
538 };
539 ExpectFailure(base::ArrayVector(data), 12, "invalid code section length");
540 }
541
TEST_F(WasmStreamingDecoderTest,CodeSectionLengthTooLowEndsInFunctionLength)542 TEST_F(WasmStreamingDecoderTest, CodeSectionLengthTooLowEndsInFunctionLength) {
543 const uint8_t data[] = {
544 U32_LE(kWasmMagic), // --
545 U32_LE(kWasmVersion), // --
546 kCodeSectionCode, // Section ID
547 0x5, // Section Length
548 0x82, // Number of Functions <0>
549 0x80, // -- <1>
550 0x00, // -- <2>
551 0x87, // Function Length <3>
552 0x80, // -- <4>
553 0x00, // -- <5> -- ERROR
554 0x0, // Function
555 0x0, // 2
556 0x0, // 3
557 0x0, // 4
558 0x0, // 5
559 0x0, // 6
560 0x0, // 7
561 0x1, // Function Length
562 0x0, // Function
563 };
564 ExpectFailure(base::ArrayVector(data), 15, "read past code section end");
565 }
566
TEST_F(WasmStreamingDecoderTest,NumberOfFunctionsTooHigh)567 TEST_F(WasmStreamingDecoderTest, NumberOfFunctionsTooHigh) {
568 const uint8_t data[] = {
569 U32_LE(kWasmMagic), // --
570 U32_LE(kWasmVersion), // --
571 kCodeSectionCode, // Section ID
572 0xB, // Section Length
573 0x4, // Number of Functions
574 0x7, // Function Length
575 0x0, // Function
576 0x0, // 2
577 0x0, // 3
578 0x0, // 4
579 0x0, // 5
580 0x0, // 6
581 0x0, // 7
582 0x1, // Function Length
583 0x0, // Function
584 };
585 ExpectFailure(base::ArrayVector(data), sizeof(data) - 1,
586 "unexpected end of stream");
587 }
588
TEST_F(WasmStreamingDecoderTest,NumberOfFunctionsTooLow)589 TEST_F(WasmStreamingDecoderTest, NumberOfFunctionsTooLow) {
590 const uint8_t data[] = {
591 U32_LE(kWasmMagic), // --
592 U32_LE(kWasmVersion), // --
593 kCodeSectionCode, // Section ID
594 0x8, // Section Length
595 0x2, // Number of Functions
596 0x1, // Function Length
597 0x0, // Function
598 0x2, // Function Length
599 0x0, // Function byte#0
600 0x0, // Function byte#1 -- ERROR
601 0x1, // Function Length
602 0x0 // Function
603 };
604 ExpectFailure(base::ArrayVector(data), sizeof(data) - 3,
605 "not all code section bytes were used");
606 }
607
TEST_F(WasmStreamingDecoderTest,TwoCodeSections)608 TEST_F(WasmStreamingDecoderTest, TwoCodeSections) {
609 const uint8_t data[] = {
610 U32_LE(kWasmMagic), // --
611 U32_LE(kWasmVersion), // --
612 kCodeSectionCode, // Section ID
613 0x3, // Section Length
614 0x1, // Number of Functions
615 0x1, // Function Length
616 0x0, // Function
617 kCodeSectionCode, // Section ID -- ERROR
618 0x3, // Section Length
619 0x1, // Number of Functions
620 0x1, // Function Length
621 0x0, // Function
622 };
623 ExpectFailure(base::ArrayVector(data), sizeof(data) - 5,
624 "code section can only appear once");
625 }
626
TEST_F(WasmStreamingDecoderTest,UnknownSection)627 TEST_F(WasmStreamingDecoderTest, UnknownSection) {
628 const uint8_t data[] = {
629 U32_LE(kWasmMagic), // --
630 U32_LE(kWasmVersion), // --
631 kCodeSectionCode, // Section ID
632 0x3, // Section Length
633 0x1, // Number of Functions
634 0x1, // Function Length
635 0x0, // Function
636 kUnknownSectionCode, // Section ID
637 0x3, // Section Length
638 0x1, // Name Length
639 0x1, // Name
640 0x0, // Content
641 };
642 ExpectVerifies(base::ArrayVector(data), 1, 1);
643 }
644
TEST_F(WasmStreamingDecoderTest,UnknownSectionSandwich)645 TEST_F(WasmStreamingDecoderTest, UnknownSectionSandwich) {
646 const uint8_t data[] = {
647 U32_LE(kWasmMagic), // --
648 U32_LE(kWasmVersion), // --
649 kCodeSectionCode, // Section ID
650 0x3, // Section Length
651 0x1, // Number of Functions
652 0x1, // Function Length
653 0x0, // Function
654 kUnknownSectionCode, // Section ID
655 0x3, // Section Length
656 0x1, // Name Length
657 0x1, // Name
658 0x0, // Content
659 kCodeSectionCode, // Section ID -- ERROR
660 0x3, // Section Length
661 0x1, // Number of Functions
662 0x1, // Function Length
663 0x0, // Function
664 };
665 ExpectFailure(base::ArrayVector(data), sizeof(data) - 5,
666 "code section can only appear once");
667 }
668
669 } // namespace wasm
670 } // namespace internal
671 } // namespace v8
672