Interpreter: Bounds check array access, add bool return from run
Out of bounds access with constant indices is a compile error.
At runtime, causes the interpreter to fail. Made several other
conditions trigger the same failure logic, and updated all
uses of the interpreter to validate success.
Change-Id: I3720b3c83903220b010ec574121fc64dbe102378
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228256
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 4350e70..6092593 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -203,6 +203,7 @@
VECTOR_UNARY_OP(kNegateF)
VECTOR_UNARY_OP(kNegateI)
+ case ByteCodeInstruction::kClampIndex: return 0;
case ByteCodeInstruction::kNotB: return 0;
case ByteCodeInstruction::kNegateFN: return 0;
@@ -454,9 +455,16 @@
case Expression::kIndex_Kind: {
const IndexExpression& i = (const IndexExpression&)expr;
int stride = SlotCount(i.fType);
+ int length = i.fBase->fType.columns();
+ SkASSERT(length <= 255);
int offset = -1;
if (i.fIndex->isConstant()) {
- offset = i.fIndex->getConstantInt() * stride;
+ int64_t index = i.fIndex->getConstantInt();
+ if (index < 0 || index >= length) {
+ fErrors.error(i.fIndex->fOffset, "Array index out of bounds.");
+ return 0;
+ }
+ offset = index * stride;
} else {
if (i.fIndex->hasSideEffects()) {
// Having a side-effect in an indexer is technically safe for an rvalue,
@@ -466,6 +474,8 @@
return 0;
}
this->writeExpression(*i.fIndex);
+ this->write(ByteCodeInstruction::kClampIndex);
+ this->write8(length);
if (stride != 1) {
this->write(ByteCodeInstruction::kPushImmediate);
this->write32(stride);