From bef80716d70a0b71b07f1ff99da5711624620b2d Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Thu, 24 Nov 2016 15:37:22 -0500 Subject: [PATCH] Validation for number of Struct members. The number of members in a struct may not exceed 16,383. Also Adding unit tests for Struct size limit check. --- source/validate_instruction.cpp | 15 +++++++++++++++ test/val/val_limits_test.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/source/validate_instruction.cpp b/source/validate_instruction.cpp index 976980e..b9f3f2e 100644 --- a/source/validate_instruction.cpp +++ b/source/validate_instruction.cpp @@ -142,6 +142,20 @@ spv_result_t LimitCheckIdBound(ValidationState_t& _, return SPV_SUCCESS; } +// Checks that the number of OpTypeStruct members is within the limit. +spv_result_t LimitCheckStruct(ValidationState_t& _, + const spv_parsed_instruction_t* inst) { + // Number of members is the number of operands of the instruction minus 1. + // One operand is the result ID. + const uint16_t limit = 0x3fff; + if (SpvOpTypeStruct == inst->opcode && inst->num_operands - 1 > limit) { + return _.diag(SPV_ERROR_INVALID_BINARY) + << "Number of OpTypeStruct members (" << inst->num_operands - 1 + << ") has exceeded the limit (" << limit << ")."; + } + return SPV_SUCCESS; +} + spv_result_t InstructionPass(ValidationState_t& _, const spv_parsed_instruction_t* inst) { const SpvOp opcode = static_cast(inst->opcode); @@ -183,6 +197,7 @@ spv_result_t InstructionPass(ValidationState_t& _, if (auto error = CapCheck(_, inst)) return error; if (auto error = LimitCheckIdBound(_, inst)) return error; + if (auto error = LimitCheckStruct(_, inst)) return error; // All instruction checks have passed. return SPV_SUCCESS; diff --git a/test/val/val_limits_test.cpp b/test/val/val_limits_test.cpp index 97bca1d..4ebb9f5 100644 --- a/test/val/val_limits_test.cpp +++ b/test/val/val_limits_test.cpp @@ -76,3 +76,30 @@ TEST_F(ValidateLimits, idEqualToBoundBad) { HasSubstr("Result '64' must be less than the ID bound '64'.")); } +TEST_F(ValidateLimits, structNumMembersGood) { + std::ostringstream spirv; + spirv << header << R"( +%1 = OpTypeInt 32 0 +%2 = OpTypeStruct)"; + for (int i = 0; i < 16383; ++i) { + spirv << " %1"; + } + CompileSuccessfully(spirv.str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateLimits, structNumMembersExceededBad) { + std::ostringstream spirv; + spirv << header << R"( +%1 = OpTypeInt 32 0 +%2 = OpTypeStruct)"; + for (int i = 0; i < 16384; ++i) { + spirv << " %1"; + } + CompileSuccessfully(spirv.str()); + ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Number of OpTypeStruct members (16384) has exceeded " + "the limit (16383).")); +} + -- 2.7.4