Commit 7164cf47 by Jamie Madill Committed by Shannon Woods

Clamped negative index access.

Fixed error that allowed negative index for accessing vector, matrix, and array. Now we report compile error and clamp the index to 0. Re-arranged code around it to handle negative index at the one location. BUG=crbug.com/239411 TEST=bug test case R=aedla@chromium.org, kbr@chromium.org Review URL: https://codereview.appspot.com/9193045 git-svn-id: https://angleproject.googlecode.com/svn/trunk@2207 736b8ea6-26fd-11df-bfd4-992fa37f6226 TRAC #23333 Authored-by: alokp@chromium.org Signed-off-by: Shannon Woods Signed-off-by Nicolas Capens Merged-by: Jamie Madill
parent 075edd84
......@@ -2098,93 +2098,102 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
}
recover();
}
if (baseExpression->getType().getQualifier() == EvqConst && indexExpression->getQualifier() == EvqConst)
if (indexExpression->getQualifier() == EvqConst)
{
if (baseExpression->isArray())
{
// constant folding for arrays
indexedExpression = addConstArrayNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location);
}
else if (baseExpression->isVector())
{
// constant folding for vectors
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = indexExpression->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
indexedExpression = addConstVectorNode(fields, baseExpression, location);
}
else if (baseExpression->isMatrix())
int index = indexExpression->getAsConstantUnion()->getIConst(0);
if (index < 0)
{
// constant folding for matrices
indexedExpression = addConstMatrixNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location);
std::stringstream infoStream;
infoStream << index;
std::string info = infoStream.str();
error(location, "negative index", info.c_str());
recover();
index = 0;
}
}
else
{
if (indexExpression->getQualifier() == EvqConst)
if (baseExpression->getType().getQualifier() == EvqConst)
{
const bool isMatrixOrVector = (baseExpression->isVector() || baseExpression->isMatrix());
const bool indexOOR = (isMatrixOrVector && baseExpression->getType().getNominalSize() <= indexExpression->getAsConstantUnion()->getIConst(0));
// check for index out-of-range
if (indexOOR && !baseExpression->isArray())
if (baseExpression->isArray())
{
std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
// constant folding for arrays
indexedExpression = addConstArrayNode(index, baseExpression, location);
}
else
else if (baseExpression->isVector())
{
// constant folding for vectors
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
indexedExpression = addConstVectorNode(fields, baseExpression, location);
}
else if (baseExpression->isMatrix())
{
// constant folding for matrices
indexedExpression = addConstMatrixNode(index, baseExpression, location);
}
}
else
{
if (baseExpression->isArray())
{
if (baseExpression->isArray())
if (baseExpression->getType().getArraySize() == 0)
{
if (baseExpression->getType().getArraySize() == 0)
if (baseExpression->getType().getMaxArraySize() <= index)
{
if (baseExpression->getType().getMaxArraySize() <= indexExpression->getAsConstantUnion()->getIConst(0))
{
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), indexExpression->getAsConstantUnion()->getIConst(0), true, location))
recover();
}
else
{
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), 0, false, location))
recover();
}
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), index, true, location))
recover();
}
else if ( indexExpression->getAsConstantUnion()->getIConst(0) >= baseExpression->getType().getArraySize())
else
{
std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), 0, false, location))
recover();
}
}
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
}
}
else
{
if (baseExpression->isArray() && baseExpression->getType().getArraySize() == 0)
{
error(location, "", "[", "array must be redeclared with a size before being indexed with a variable");
recover();
}
else if (baseExpression->getBasicType() == EbtInterfaceBlock)
{
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
recover();
else if (index >= baseExpression->getType().getArraySize())
{
std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << index << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
index = baseExpression->getType().getArraySize() - 1;
}
}
else if (baseExpression->getQualifier() == EvqFragmentOutput)
else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
{
error(location, "", "[", "array indexes for output variables must be constant integeral expressions");
std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << index << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
index = baseExpression->getType().getNominalSize() - 1;
}
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
}
}
else
{
if (baseExpression->isArray() && baseExpression->getType().getArraySize() == 0)
{
error(location, "", "[", "array must be redeclared with a size before being indexed with a variable");
recover();
}
else if (baseExpression->getBasicType() == EbtInterfaceBlock)
{
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
recover();
}
else if (baseExpression->getQualifier() == EvqFragmentOutput)
{
error(location, "", "[", "array indexes for output variables must be constant integeral expressions");
recover();
}
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
}
if (indexedExpression == 0)
{
ConstantUnion *unionArray = new ConstantUnion[1];
......@@ -2209,21 +2218,15 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
}
else if (baseExpression->isMatrix() && baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, baseExpression->getRows()));
}
else if (baseExpression->isMatrix())
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getRows()));
}
else if (baseExpression->isVector() && baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst));
TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getRows()));
}
else if (baseExpression->isVector())
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary));
TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
}
else
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment