Improve error-checking during array-size conversion.
The fuzzer noticed insufficient guards in IndexExpression::Convert when
converting an array size from an IntLiteral to a SKSL_INT. We had code
in IRGenerator which did this properly, so I moved our array-size
conversion logic into SkSLType and had IndexExpression share it.
Also, a variety of tests around similar error conditions were added.
Change-Id: I51529dea25f9029f81ae236511610069d66be29f
Bug: oss-fuzz:37462
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/441236
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index c4eeb8c..73278ca 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -216,37 +216,7 @@
if (!size) {
return 0;
}
- return this->convertArraySize(type, std::move(size));
-}
-
-int IRGenerator::convertArraySize(const Type& type, std::unique_ptr<Expression> size) {
- size = this->coerce(std::move(size), *fContext.fTypes.fInt);
- if (!size) {
- return 0;
- }
- if (type.isVoid()) {
- this->errorReporter().error(size->fOffset, "type 'void' may not be used in an array");
- return 0;
- }
- if (type.isOpaque()) {
- this->errorReporter().error(
- size->fOffset, "opaque type '" + type.name() + "' may not be used in an array");
- return 0;
- }
- if (!size->is<IntLiteral>()) {
- this->errorReporter().error(size->fOffset, "array size must be an integer");
- return 0;
- }
- SKSL_INT count = size->as<IntLiteral>().value();
- if (count <= 0) {
- this->errorReporter().error(size->fOffset, "array size must be positive");
- return 0;
- }
- if (!SkTFitsIn<int>(count)) {
- this->errorReporter().error(size->fOffset, "array size is too large");
- return 0;
- }
- return static_cast<int>(count);
+ return type.convertArraySize(fContext, std::move(size));
}
void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, const Type* baseType,
@@ -320,7 +290,7 @@
int arraySizeValue = 0;
if (isArray) {
SkASSERT(arraySize);
- arraySizeValue = this->convertArraySize(*type, std::move(arraySize));
+ arraySizeValue = type->convertArraySize(fContext, std::move(arraySize));
if (!arraySizeValue) {
return {};
}