From 8c5889937172a4ce733dc904ddb3ca961eeed3da Mon Sep 17 00:00:00 2001 From: John Stiles Date: Thu, 19 Nov 2020 17:36:17 -0500 Subject: [PATCH] Fix fuzzer crash when casting between int and float. The fix submitted at http://review.skia.org/335868 did not support casts. The fuzzer discovered this shortcoming right away. Change-Id: I2f5166528cee41367348564d4e664476fd5704ff Bug: oss-fuzz:27650 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/336656 Commit-Queue: Brian Osman Reviewed-by: Brian Osman Auto-Submit: John Stiles --- gn/sksl_tests.gni | 1 + src/sksl/ir/SkSLConstructor.cpp | 22 ++++++++++++++++------ tests/sksl/errors/Ossfuzz27650.sksl | 1 + tests/sksl/errors/golden/Ossfuzz27650.glsl | 4 ++++ 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 tests/sksl/errors/Ossfuzz27650.sksl create mode 100644 tests/sksl/errors/golden/Ossfuzz27650.glsl diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni index 1e99cf77ab..eee26d4827 100644 --- a/gn/sksl_tests.gni +++ b/gn/sksl_tests.gni @@ -114,6 +114,7 @@ sksl_error_tests = [ "$_tests/sksl/errors/OpenArray.sksl", "$_tests/sksl/errors/Ossfuzz26700.sksl", "$_tests/sksl/errors/Ossfuzz26759.sksl", + "$_tests/sksl/errors/Ossfuzz27650.sksl", "$_tests/sksl/errors/OverflowIntLiteral.sksl", "$_tests/sksl/errors/OverflowUintLiteral.sksl", "$_tests/sksl/errors/PrivateTypes.sksl", diff --git a/src/sksl/ir/SkSLConstructor.cpp b/src/sksl/ir/SkSLConstructor.cpp index 0291e9a60f..a57fe4c06a 100644 --- a/src/sksl/ir/SkSLConstructor.cpp +++ b/src/sksl/ir/SkSLConstructor.cpp @@ -194,17 +194,27 @@ SKSL_FLOAT Constructor::getMatComponent(int col, int row) const { } int64_t Constructor::getConstantInt() const { + // We're looking for scalar integer constructors only, i.e. `int(1)`. SkASSERT(this->arguments().size() == 1); - SkASSERT(this->arguments().front()->type().typeKind() == Type::TypeKind::kScalar); - SkASSERT(this->arguments().front()->type().isInteger()); - return this->arguments().front()->getConstantInt(); + SkASSERT(this->type().columns() == 1); + SkASSERT(this->type().isInteger()); + + // The inner argument might actually be a float! `int(1.0)` is a valid cast. + const Expression& expr = *this->arguments().front(); + SkASSERT(expr.type().typeKind() == Type::TypeKind::kScalar); + return expr.type().isInteger() ? expr.getConstantInt() : (int64_t)expr.getConstantFloat(); } SKSL_FLOAT Constructor::getConstantFloat() const { + // We're looking for scalar integer constructors only, i.e. `float(1.0)`. SkASSERT(this->arguments().size() == 1); - SkASSERT(this->arguments().front()->type().typeKind() == Type::TypeKind::kScalar); - SkASSERT(this->arguments().front()->type().isFloat()); - return this->arguments().front()->getConstantFloat(); + SkASSERT(this->type().columns() == 1); + SkASSERT(this->type().isFloat()); + + // The inner argument might actually be an integer! `float(1)` is a valid cast. + const Expression& expr = *this->arguments().front(); + SkASSERT(expr.type().typeKind() == Type::TypeKind::kScalar); + return expr.type().isFloat() ? expr.getConstantFloat() : (SKSL_FLOAT)expr.getConstantInt(); } } // namespace SkSL diff --git a/tests/sksl/errors/Ossfuzz27650.sksl b/tests/sksl/errors/Ossfuzz27650.sksl new file mode 100644 index 0000000000..9dec2c7636 --- /dev/null +++ b/tests/sksl/errors/Ossfuzz27650.sksl @@ -0,0 +1 @@ +void main() { int i=9E7; 2+int4(i); } diff --git a/tests/sksl/errors/golden/Ossfuzz27650.glsl b/tests/sksl/errors/golden/Ossfuzz27650.glsl new file mode 100644 index 0000000000..37c35c1778 --- /dev/null +++ b/tests/sksl/errors/golden/Ossfuzz27650.glsl @@ -0,0 +1,4 @@ +### Compilation failed: + +error: 1: expected 'int', but found 'float' +1 error