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