Fix parser assert failure for a bad OpSwitch

Emit a diagnostic if the OpSwitch selector refers to an ID that
is valid but has no type.

Discovered by afl-fuzz.
This commit is contained in:
David Neto 2015-12-23 13:21:43 -05:00
parent 1a3734d265
commit 3664bd5670
2 changed files with 10 additions and 2 deletions

View File

@ -555,8 +555,9 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
// The literal operands have the same type as the value // The literal operands have the same type as the value
// referenced by the selector Id. // referenced by the selector Id.
const uint32_t selector_id = peekAt(inst_offset + 1); const uint32_t selector_id = peekAt(inst_offset + 1);
auto type_id_iter = _.id_to_type_id.find(selector_id); const auto type_id_iter = _.id_to_type_id.find(selector_id);
if (type_id_iter == _.id_to_type_id.end()) { if (type_id_iter == _.id_to_type_id.end() ||
type_id_iter->second == 0) {
return diagnostic() << "Invalid OpSwitch: selector id " << selector_id return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
<< " has no type"; << " has no type";
} }

View File

@ -628,9 +628,16 @@ INSTANTIATE_TEST_CASE_P(
MakeInstruction(SpvOpExtInst, {2, 3, 100, 4, 5})}), MakeInstruction(SpvOpExtInst, {2, 3, 100, 4, 5})}),
"OpExtInst set Id 100 does not reference an OpExtInstImport result " "OpExtInst set Id 100 does not reference an OpExtInstImport result "
"Id"}, "Id"},
// In this case, the OpSwitch selector refers to an invalid ID.
{Concatenate({ExpectedHeaderForBound(3), {Concatenate({ExpectedHeaderForBound(3),
MakeInstruction(SpvOpSwitch, {1, 2, 42, 3})}), MakeInstruction(SpvOpSwitch, {1, 2, 42, 3})}),
"Invalid OpSwitch: selector id 1 has no type"}, "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), {Concatenate({ExpectedHeaderForBound(3),
MakeInstruction(SpvOpTypeInt, {1, 32, 0}), MakeInstruction(SpvOpTypeInt, {1, 32, 0}),
MakeInstruction(SpvOpSwitch, {1, 3, 42, 3})}), MakeInstruction(SpvOpSwitch, {1, 3, 42, 3})}),