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 ...@@ -2098,93 +2098,102 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
} }
recover(); recover();
} }
if (baseExpression->getType().getQualifier() == EvqConst && indexExpression->getQualifier() == EvqConst)
if (indexExpression->getQualifier() == EvqConst)
{ {
if (baseExpression->isArray()) int index = indexExpression->getAsConstantUnion()->getIConst(0);
{ if (index < 0)
// 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())
{ {
// constant folding for matrices std::stringstream infoStream;
indexedExpression = addConstMatrixNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location); infoStream << index;
std::string info = infoStream.str();
error(location, "negative index", info.c_str());
recover();
index = 0;
} }
} if (baseExpression->getType().getQualifier() == EvqConst)
else
{
if (indexExpression->getQualifier() == EvqConst)
{ {
const bool isMatrixOrVector = (baseExpression->isVector() || baseExpression->isMatrix()); if (baseExpression->isArray())
const bool indexOOR = (isMatrixOrVector && baseExpression->getType().getNominalSize() <= indexExpression->getAsConstantUnion()->getIConst(0));
// check for index out-of-range
if (indexOOR && !baseExpression->isArray())
{ {
std::stringstream extraInfoStream; // constant folding for arrays
extraInfoStream << "field selection out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'"; indexedExpression = addConstArrayNode(index, baseExpression, location);
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
} }
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(), index, true, location))
{ recover();
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), indexExpression->getAsConstantUnion()->getIConst(0), true, location))
recover();
}
else
{
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), 0, false, location))
recover();
}
} }
else if ( indexExpression->getAsConstantUnion()->getIConst(0) >= baseExpression->getType().getArraySize()) else
{ {
std::stringstream extraInfoStream; if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), 0, false, location))
extraInfoStream << "array index out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'"; recover();
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
} }
} }
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); else if (index >= baseExpression->getType().getArraySize())
} {
} std::stringstream extraInfoStream;
else extraInfoStream << "array index out of range '" << index << "'";
{ std::string extraInfo = extraInfoStream.str();
if (baseExpression->isArray() && baseExpression->getType().getArraySize() == 0) error(location, "", "[", extraInfo.c_str());
{ recover();
error(location, "", "[", "array must be redeclared with a size before being indexed with a variable"); index = baseExpression->getType().getArraySize() - 1;
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) 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(); 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) if (indexedExpression == 0)
{ {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
...@@ -2209,21 +2218,15 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co ...@@ -2209,21 +2218,15 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
indexedExpression->getTypePointer()->setQualifier(EvqConst); 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()) else if (baseExpression->isMatrix())
{ {
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getRows())); TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
} indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getRows()));
else if (baseExpression->isVector() && baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst));
} }
else if (baseExpression->isVector()) 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 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