Fix parser assert failure for a bad OpSwitch
authorDavid Neto <dneto@google.com>
Wed, 23 Dec 2015 18:21:43 +0000 (13:21 -0500)
committerDavid Neto <dneto@google.com>
Tue, 5 Jan 2016 16:25:58 +0000 (11:25 -0500)
Emit a diagnostic if the OpSwitch selector refers to an ID that
is valid but has no type.

Discovered by afl-fuzz.

source/binary.cpp
test/BinaryParse.cpp

index 533fe7f..99cf30f 100755 (executable)
@@ -555,8 +555,9 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
         // The literal operands have the same type as the value
         // referenced by the selector Id.
         const uint32_t selector_id = peekAt(inst_offset + 1);
-        auto type_id_iter = _.id_to_type_id.find(selector_id);
-        if (type_id_iter == _.id_to_type_id.end()) {
+        const auto type_id_iter = _.id_to_type_id.find(selector_id);
+        if (type_id_iter == _.id_to_type_id.end() ||
+            type_id_iter->second == 0) {
           return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
                               << " has no type";
         }
index 1c6f237..2aacf47 100644 (file)
@@ -628,9 +628,16 @@ INSTANTIATE_TEST_CASE_P(
                       MakeInstruction(SpvOpExtInst, {2, 3, 100, 4, 5})}),
          "OpExtInst set Id 100 does not reference an OpExtInstImport result "
          "Id"},
+        // In this case, the OpSwitch selector refers to an invalid ID.
         {Concatenate({ExpectedHeaderForBound(3),
                       MakeInstruction(SpvOpSwitch, {1, 2, 42, 3})}),
          "Invalid OpSwitch: selector id 1 has no type"},
+        // In this case, the OpSwitch selector refers to an ID that has
+        // no type.
+        {Concatenate({ExpectedHeaderForBound(3),
+                      MakeInstruction(SpvOpLabel, {1}),
+                      MakeInstruction(SpvOpSwitch, {1, 2, 42, 3})}),
+         "Invalid OpSwitch: selector id 1 has no type"},
         {Concatenate({ExpectedHeaderForBound(3),
                       MakeInstruction(SpvOpTypeInt, {1, 32, 0}),
                       MakeInstruction(SpvOpSwitch, {1, 3, 42, 3})}),