Fix crash with boolean vectors in is_constant<T>.
Previously, we assumed that if a vector in `is_constant` was not made of floats, it must be made of integers. This ignores that boolean vectors also exist. The original code would abort when `getIVecComponent` was called on a bool vector. There is another bug here--arithmetic operators on bool types should be disallowed entirely. That will be addressed in later CLs. Change-Id: I78781d839abde9376917fd92f2fe6311a1a58b02 Bug: oss-fuzz:27808 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/338055 Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
7512507050
commit
bc75ebb1af
@ -84,6 +84,7 @@ sksl_error_tests = [
|
||||
"$_tests/sksl/errors/BitShiftFloat.sksl",
|
||||
"$_tests/sksl/errors/BitShiftFloatMatrix.sksl",
|
||||
"$_tests/sksl/errors/BitShiftFloatVector.sksl",
|
||||
"$_tests/sksl/errors/BooleanArithmetic.sksl",
|
||||
"$_tests/sksl/errors/BreakOutsideLoop.sksl",
|
||||
"$_tests/sksl/errors/CallNonFunction.sksl",
|
||||
"$_tests/sksl/errors/CanExitWithoutReturningValue.sksl",
|
||||
|
@ -663,23 +663,25 @@ static bool is_constant(const Expression& expr, T value) {
|
||||
const Constructor& constructor = expr.as<Constructor>();
|
||||
if (constructor.isCompileTimeConstant()) {
|
||||
const Type& constructorType = constructor.type();
|
||||
bool isFloat = constructorType.columns() > 1
|
||||
? constructorType.componentType().isFloat()
|
||||
: constructorType.isFloat();
|
||||
switch (constructorType.typeKind()) {
|
||||
case Type::TypeKind::kVector:
|
||||
for (int i = 0; i < constructorType.columns(); ++i) {
|
||||
if (isFloat) {
|
||||
if (constructor.componentType().isFloat()) {
|
||||
for (int i = 0; i < constructorType.columns(); ++i) {
|
||||
if (constructor.getFVecComponent(i) != value) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
return true;
|
||||
} else if (constructor.componentType().isInteger()) {
|
||||
for (int i = 0; i < constructorType.columns(); ++i) {
|
||||
if (constructor.getIVecComponent(i) != value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
// Other types (e.g. boolean) might occur, but aren't supported here.
|
||||
return false;
|
||||
|
||||
case Type::TypeKind::kScalar:
|
||||
SkASSERT(constructor.arguments().size() == 1);
|
||||
|
@ -103,7 +103,7 @@ ResultType Constructor::getVecComponent(int index) const {
|
||||
if (current + constructor.type().columns() > index) {
|
||||
// We've found a constructor that overlaps the proper argument. Descend into
|
||||
// it, honoring the type.
|
||||
return constructor.type().componentType().isFloat()
|
||||
return constructor.componentType().isFloat()
|
||||
? ResultType(constructor.getVecComponent<SKSL_FLOAT>(index - current))
|
||||
: ResultType(constructor.getVecComponent<SKSL_INT>(index - current));
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
const Type& componentType() const {
|
||||
// Returns `float` for constructors of type `float(...)` or `floatN(...)`.
|
||||
const Type& type = this->type();
|
||||
return type.columns() == 1 ? type : type.componentType();
|
||||
}
|
||||
|
||||
bool isCompileTimeConstant() const override {
|
||||
for (const std::unique_ptr<Expression>& arg: this->arguments()) {
|
||||
if (!arg->isCompileTimeConstant()) {
|
||||
@ -98,13 +104,17 @@ public:
|
||||
template <typename resultType>
|
||||
resultType getVecComponent(int index) const;
|
||||
|
||||
/**
|
||||
* For a literal vector expression, return the float value of the n'th vector component. It is
|
||||
* an error to call this method on an expression which is not a vector of FloatLiterals.
|
||||
*/
|
||||
SKSL_FLOAT getFVecComponent(int n) const override {
|
||||
return this->getVecComponent<SKSL_FLOAT>(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a literal vector expression, return the integer value of the n'th vector component. It is
|
||||
* an error to call this method on an expression which is not a literal vector.
|
||||
* an error to call this method on an expression which is not a vector of IntLiterals.
|
||||
*/
|
||||
SKSL_INT getIVecComponent(int n) const override {
|
||||
return this->getVecComponent<SKSL_INT>(n);
|
||||
|
13
tests/sksl/errors/BooleanArithmetic.sksl
Normal file
13
tests/sksl/errors/BooleanArithmetic.sksl
Normal file
@ -0,0 +1,13 @@
|
||||
bool2 add_boolean_vec() { return bool2(false, false) + bool2(true, true); }
|
||||
bool2 sub_boolean_vec() { return bool2(false, false) - bool2(true, true); }
|
||||
bool2 mul_boolean_vec() { return bool2(false, false) * bool2(true, true); }
|
||||
bool2 div_boolean_vec() { return bool2(false, false) / bool2(true, true); }
|
||||
bool2 mod_boolean_vec() { return bool2(false, false) % bool2(true, true); }
|
||||
|
||||
void main() {
|
||||
add_boolean_vec();
|
||||
sub_boolean_vec();
|
||||
mul_boolean_vec();
|
||||
div_boolean_vec();
|
||||
mod_boolean_vec();
|
||||
}
|
3
tests/sksl/errors/golden/BooleanArithmetic.glsl
Normal file
3
tests/sksl/errors/golden/BooleanArithmetic.glsl
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
void main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user