@@ -706,6 +706,16 @@ Result WastParser::Synchronize(SynchronizeFunc func) {
706706 return Result::Error;
707707}
708708
709+ Result WastParser::CheckIndexRange (Location& loc,
710+ size_t size,
711+ const char * decl) {
712+ if (size >= kInvalidIndex ) {
713+ Error (loc, " too many %s declarations" , decl);
714+ return Result::Error;
715+ }
716+ return Result::Ok;
717+ }
718+
709719void WastParser::ErrorUnlessOpcodeEnabled (const Token& token) {
710720 Opcode opcode = token.opcode ();
711721 if (!opcode.IsEnabled (options_->features )) {
@@ -1506,6 +1516,7 @@ Result WastParser::ParseDataModuleField(Module* module) {
15061516 EXPECT (Lpar);
15071517 Location loc = GetLocation ();
15081518 EXPECT (Data);
1519+ CHECK_RESULT (CheckIndexRange (loc, module ->data_segments .size (), " data" ));
15091520 std::string name;
15101521 CHECK_RESULT (ParseBindVarOpt (&name));
15111522 auto field = std::make_unique<DataSegmentModuleField>(loc, name);
@@ -1543,6 +1554,7 @@ Result WastParser::ParseElemModuleField(Module* module) {
15431554 EXPECT (Lpar);
15441555 Location loc = GetLocation ();
15451556 EXPECT (Elem);
1557+ CHECK_RESULT (CheckIndexRange (loc, module ->elem_segments .size (), " elem" ));
15461558
15471559 // With MVP text format the name here was intended to refer to the table
15481560 // that the elem segment was part of, but we never did anything with this name
@@ -1620,7 +1632,7 @@ Result WastParser::ParseTagModuleField(Module* module) {
16201632 EXPECT (Lpar);
16211633 EXPECT (Tag);
16221634 Location loc = GetLocation ();
1623-
1635+ CHECK_RESULT ( CheckIndexRange (loc, module -> tags . size (), " tag " ));
16241636 std::string name;
16251637 CHECK_RESULT (ParseBindVarOpt (&name));
16261638
@@ -1629,6 +1641,7 @@ Result WastParser::ParseTagModuleField(Module* module) {
16291641
16301642 if (PeekMatchLpar (TokenType::Import)) {
16311643 CheckImportOrdering (module );
1644+ CHECK_RESULT (CheckIndexRange (loc, module ->imports .size (), " import" ));
16321645 auto import = std::make_unique<TagImport>(name);
16331646 Tag& tag = import ->tag ;
16341647 CHECK_RESULT (ParseInlineImport (import .get ()));
@@ -1655,7 +1668,9 @@ Result WastParser::ParseExportModuleField(Module* module) {
16551668 WABT_TRACE (ParseExportModuleField);
16561669 EXPECT (Lpar);
16571670 auto field = std::make_unique<ExportModuleField>(GetLocation ());
1671+ Location loc = GetLocation ();
16581672 EXPECT (Export);
1673+ CHECK_RESULT (CheckIndexRange (loc, module ->exports .size (), " export" ));
16591674 CHECK_RESULT (ParseQuotedText (&field->export_ .name ));
16601675 CHECK_RESULT (ParseExportDesc (&field->export_ ));
16611676 EXPECT (Rpar);
@@ -1668,6 +1683,7 @@ Result WastParser::ParseFuncModuleField(Module* module) {
16681683 EXPECT (Lpar);
16691684 Location loc = GetLocation ();
16701685 EXPECT (Func);
1686+ CHECK_RESULT (CheckIndexRange (loc, module ->funcs .size (), " func" ));
16711687 std::string name;
16721688 CHECK_RESULT (ParseBindVarOpt (&name));
16731689
@@ -1676,6 +1692,7 @@ Result WastParser::ParseFuncModuleField(Module* module) {
16761692
16771693 if (PeekMatchLpar (TokenType::Import)) {
16781694 CheckImportOrdering (module );
1695+ CHECK_RESULT (CheckIndexRange (loc, module ->imports .size (), " import" ));
16791696 auto import = std::make_unique<FuncImport>(name);
16801697 Func& func = import ->func ;
16811698 CHECK_RESULT (ParseInlineImport (import .get ()));
@@ -1725,6 +1742,7 @@ Result WastParser::ParseTypeModuleField(Module* module) {
17251742 CHECK_RESULT (ParseBindVarOpt (&name));
17261743 EXPECT (Lpar);
17271744 Location loc = GetLocation ();
1745+ CHECK_RESULT (CheckIndexRange (loc, module ->types .size (), " type" ));
17281746
17291747 if (Match (TokenType::Func)) {
17301748 auto func_type = std::make_unique<FuncType>(name);
@@ -1802,6 +1820,7 @@ Result WastParser::ParseGlobalModuleField(Module* module) {
18021820 EXPECT (Lpar);
18031821 Location loc = GetLocation ();
18041822 EXPECT (Global);
1823+ CHECK_RESULT (CheckIndexRange (loc, module ->globals .size (), " global" ));
18051824 std::string name;
18061825 CHECK_RESULT (ParseBindVarOpt (&name));
18071826
@@ -1810,6 +1829,7 @@ Result WastParser::ParseGlobalModuleField(Module* module) {
18101829
18111830 if (PeekMatchLpar (TokenType::Import)) {
18121831 CheckImportOrdering (module );
1832+ CHECK_RESULT (CheckIndexRange (loc, module ->imports .size (), " import" ));
18131833 auto import = std::make_unique<GlobalImport>(name);
18141834 CHECK_RESULT (ParseInlineImport (import .get ()));
18151835 CHECK_RESULT (ParseGlobalType (&import ->global ));
@@ -1835,6 +1855,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
18351855 Location loc = GetLocation ();
18361856 CheckImportOrdering (module );
18371857 EXPECT (Import);
1858+ CHECK_RESULT (CheckIndexRange (loc, module ->imports .size (), " import" ));
18381859 std::string module_name;
18391860 std::string field_name;
18401861 CHECK_RESULT (ParseQuotedText (&module_name));
@@ -1846,6 +1867,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
18461867
18471868 switch (Peek ()) {
18481869 case TokenType::Func: {
1870+ CHECK_RESULT (CheckIndexRange (loc, module ->funcs .size (), " func" ));
18491871 DropToken ();
18501872 CHECK_RESULT (ParseBindVarOpt (&name));
18511873 auto import = std::make_unique<FuncImport>(name);
@@ -1859,6 +1881,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
18591881 }
18601882
18611883 case TokenType::Table: {
1884+ CHECK_RESULT (CheckIndexRange (loc, module ->tables .size (), " table" ));
18621885 DropToken ();
18631886 CHECK_RESULT (ParseBindVarOpt (&name));
18641887 auto import = std::make_unique<TableImport>(name);
@@ -1873,6 +1896,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
18731896 }
18741897
18751898 case TokenType::Memory: {
1899+ CHECK_RESULT (CheckIndexRange (loc, module ->memories .size (), " memory" ));
18761900 DropToken ();
18771901 CHECK_RESULT (ParseBindVarOpt (&name));
18781902 auto import = std::make_unique<MemoryImport>(name);
@@ -1886,6 +1910,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
18861910 }
18871911
18881912 case TokenType::Global: {
1913+ CHECK_RESULT (CheckIndexRange (loc, module ->globals .size (), " global" ));
18891914 DropToken ();
18901915 CHECK_RESULT (ParseBindVarOpt (&name));
18911916 auto import = std::make_unique<GlobalImport>(name);
@@ -1896,6 +1921,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
18961921 }
18971922
18981923 case TokenType::Tag: {
1924+ CHECK_RESULT (CheckIndexRange (loc, module ->tags .size (), " tag" ));
18991925 DropToken ();
19001926 CHECK_RESULT (ParseBindVarOpt (&name));
19011927 auto import = std::make_unique<TagImport>(name);
@@ -1923,6 +1949,7 @@ Result WastParser::ParseMemoryModuleField(Module* module) {
19231949 EXPECT (Lpar);
19241950 Location loc = GetLocation ();
19251951 EXPECT (Memory);
1952+ CHECK_RESULT (CheckIndexRange (loc, module ->memories .size (), " memory" ));
19261953 std::string name;
19271954 CHECK_RESULT (ParseBindVarOpt (&name));
19281955
@@ -1931,6 +1958,7 @@ Result WastParser::ParseMemoryModuleField(Module* module) {
19311958
19321959 if (PeekMatchLpar (TokenType::Import)) {
19331960 CheckImportOrdering (module );
1961+ CHECK_RESULT (CheckIndexRange (loc, module ->imports .size (), " import" ));
19341962 auto import = std::make_unique<MemoryImport>(name);
19351963 import ->memory .page_size = WABT_DEFAULT_PAGE_SIZE;
19361964 CHECK_RESULT (ParseInlineImport (import .get ()));
@@ -2004,6 +2032,7 @@ Result WastParser::ParseTableModuleField(Module* module) {
20042032 EXPECT (Lpar);
20052033 Location loc = GetLocation ();
20062034 EXPECT (Table);
2035+ CHECK_RESULT (CheckIndexRange (loc, module ->tables .size (), " table" ));
20072036 std::string name;
20082037 CHECK_RESULT (ParseBindVarOpt (&name));
20092038
@@ -2012,6 +2041,7 @@ Result WastParser::ParseTableModuleField(Module* module) {
20122041
20132042 if (PeekMatchLpar (TokenType::Import)) {
20142043 CheckImportOrdering (module );
2044+ CHECK_RESULT (CheckIndexRange (loc, module ->imports .size (), " import" ));
20152045 auto import = std::make_unique<TableImport>(name);
20162046 CHECK_RESULT (ParseInlineImport (import .get ()));
20172047 CHECK_RESULT (ParseLimitsIndex (&import ->table .elem_limits ));
@@ -2032,6 +2062,7 @@ Result WastParser::ParseTableModuleField(Module* module) {
20322062
20332063 EXPECT (Lpar);
20342064 EXPECT (Elem);
2065+ CHECK_RESULT (CheckIndexRange (loc, module ->elem_segments .size (), " elem" ));
20352066
20362067 auto elem_segment_field = std::make_unique<ElemSegmentModuleField>(loc);
20372068 ElemSegment& elem_segment = elem_segment_field->elem_segment ;
0 commit comments