reader/spirv: Prevent nullptrs being passed to ast::CallExpression.
nullptrs are caused by errors. Detect and return before passing nullptrs to places they shouldn't go.
Also: Rename 'params' to 'args'. These are arguments, not parameters.
Bug: oss-fuzz:38074
Fixed: tint:1355
Change-Id: I77f97b4a8e5dab21802b300ba3eedad767ac2ad5
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/75425
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 2490c1c..3cf6893 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -5207,7 +5207,7 @@
}
bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
- ast::ExpressionList params;
+ ast::ExpressionList args;
const auto opcode = inst.opcode();
// Form the texture operand.
@@ -5215,13 +5215,13 @@
if (!image) {
return false;
}
- params.push_back(GetImageExpression(inst));
+ args.push_back(GetImageExpression(inst));
// Form the sampler operand, if needed.
if (IsSampledImageAccess(opcode)) {
// Form the sampler operand.
if (auto* sampler = GetSamplerExpression(inst)) {
- params.push_back(sampler);
+ args.push_back(sampler);
} else {
return false;
}
@@ -5247,7 +5247,7 @@
if (coords.empty()) {
return false;
}
- params.insert(params.end(), coords.begin(), coords.end());
+ args.insert(args.end(), coords.begin(), coords.end());
// Skip the coordinates operand.
arg_index++;
@@ -5257,7 +5257,7 @@
// the parameter list. Issues a diagnostic and returns false on error.
auto consume_dref = [&]() -> bool {
if (arg_index < num_args) {
- params.push_back(MakeOperand(inst, arg_index).expr);
+ args.push_back(MakeOperand(inst, arg_index).expr);
arg_index++;
} else {
return Fail()
@@ -5295,7 +5295,7 @@
builtin_name = "textureGather";
if (!texture_type->Is<DepthTexture>()) {
// The explicit component is the *first* argument in WGSL.
- params.insert(params.begin(), ToI32(MakeOperand(inst, arg_index)).expr);
+ args.insert(args.begin(), ToI32(MakeOperand(inst, arg_index)).expr);
}
// Skip over the component operand, even for depth textures.
arg_index++;
@@ -5324,7 +5324,7 @@
return false;
}
- params.push_back(converted_texel);
+ args.push_back(converted_texel);
arg_index++;
} else {
return Fail() << "image write is missing a Texel operand: "
@@ -5356,7 +5356,7 @@
<< inst.PrettyPrint();
}
builtin_name += "Bias";
- params.push_back(MakeOperand(inst, arg_index).expr);
+ args.push_back(MakeOperand(inst, arg_index).expr);
image_operands_mask ^= SpvImageOperandsBiasMask;
arg_index++;
}
@@ -5383,7 +5383,7 @@
// Convert it to a signed integer type.
lod = ToI32(lod);
}
- params.push_back(lod.expr);
+ args.push_back(lod.expr);
}
image_operands_mask ^= SpvImageOperandsLodMask;
@@ -5393,7 +5393,7 @@
->IsAnyOf<DepthMultisampledTexture, MultisampledTexture>()) {
// textureLoad requires an explicit level-of-detail parameter for
// non-multisampled texture types.
- params.push_back(parser_impl_.MakeNullValue(ty_.I32()));
+ args.push_back(parser_impl_.MakeNullValue(ty_.I32()));
}
if (arg_index + 1 < num_args &&
(image_operands_mask & SpvImageOperandsGradMask)) {
@@ -5408,8 +5408,8 @@
<< inst.PrettyPrint();
}
builtin_name += "Grad";
- params.push_back(MakeOperand(inst, arg_index).expr);
- params.push_back(MakeOperand(inst, arg_index + 1).expr);
+ args.push_back(MakeOperand(inst, arg_index).expr);
+ args.push_back(MakeOperand(inst, arg_index + 1).expr);
image_operands_mask ^= SpvImageOperandsGradMask;
arg_index += 2;
}
@@ -5431,14 +5431,14 @@
<< inst.PrettyPrint();
}
- params.push_back(ToSignedIfUnsigned(MakeOperand(inst, arg_index)).expr);
+ args.push_back(ToSignedIfUnsigned(MakeOperand(inst, arg_index)).expr);
image_operands_mask ^= SpvImageOperandsConstOffsetMask;
arg_index++;
}
if (arg_index < num_args &&
(image_operands_mask & SpvImageOperandsSampleMask)) {
// TODO(dneto): only permitted with ImageFetch
- params.push_back(ToI32(MakeOperand(inst, arg_index)).expr);
+ args.push_back(ToI32(MakeOperand(inst, arg_index)).expr);
image_operands_mask ^= SpvImageOperandsSampleMask;
arg_index++;
}
@@ -5447,10 +5447,16 @@
<< "): " << inst.PrettyPrint();
}
+ // If any of the arguments are nullptr, then we've failed.
+ if (std::any_of(args.begin(), args.end(),
+ [](auto* expr) { return expr == nullptr; })) {
+ return false;
+ }
+
auto* ident = create<ast::IdentifierExpression>(
Source{}, builder_.Symbols().Register(builtin_name));
auto* call_expr =
- create<ast::CallExpression>(Source{}, ident, std::move(params));
+ create<ast::CallExpression>(Source{}, ident, std::move(args));
if (inst.type_id() != 0) {
// It returns a value.