Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate calls to printf #5667

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion source/val/validate_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _,
return SPV_SUCCESS;
}

bool IsVarArgFunction(const std::string function_name) {
return (function_name == "printf");
}

spv_result_t ValidateFunctionCall(ValidationState_t& _,
const Instruction* inst) {
const auto function_id = inst->GetOperandAs<uint32_t>(2);
Expand Down Expand Up @@ -251,7 +255,13 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _,

const auto function_call_arg_count = inst->words().size() - 4;
const auto function_param_count = function_type->words().size() - 3;
if (function_param_count != function_call_arg_count) {

bool isVarArgFunction = IsVarArgFunction(_.getName(function_id));

if ( // Not enough arguments
function_param_count > function_call_arg_count ||
// Too many arguments and function does not have varargs
(!isVarArgFunction && function_param_count < function_call_arg_count)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpFunctionCall Function <id>'s parameter count does not match "
"the argument count.";
Expand All @@ -260,6 +270,9 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _,
for (size_t argument_index = 3, param_index = 2;
argument_index < inst->operands().size();
argument_index++, param_index++) {
// If actual argument is in the untyped portion of the vararg function's
// declaration stop checking.
if (isVarArgFunction && (param_index - 2) >= function_param_count) break;
const auto argument_id = inst->GetOperandAs<uint32_t>(argument_index);
const auto argument = _.FindDef(argument_id);
if (!argument) {
Expand Down
6 changes: 6 additions & 0 deletions source/val/validation_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ std::string ValidationState_t::getIdName(uint32_t id) const {
return out.str();
}

const std::string ValidationState_t::getName(uint32_t id) const {
const std::string id_name = name_mapper_(id);

return id_name;
}

size_t ValidationState_t::unresolved_forward_id_count() const {
return unresolved_forward_ids_.size();
}
Expand Down
3 changes: 3 additions & 0 deletions source/val/validation_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ class ValidationState_t {
/// the OpName instruction
std::string getIdName(uint32_t id) const;

/// Returns the string assigned to id by the OpName instruction
const std::string getName(uint32_t id) const;

/// Accessor function for ID bound.
uint32_t getIdBound() const;

Expand Down