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,52 +2098,49 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co ...@@ -2098,52 +2098,49 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
} }
recover(); recover();
} }
if (baseExpression->getType().getQualifier() == EvqConst && indexExpression->getQualifier() == EvqConst)
if (indexExpression->getQualifier() == EvqConst)
{
int index = indexExpression->getAsConstantUnion()->getIConst(0);
if (index < 0)
{
std::stringstream infoStream;
infoStream << index;
std::string info = infoStream.str();
error(location, "negative index", info.c_str());
recover();
index = 0;
}
if (baseExpression->getType().getQualifier() == EvqConst)
{ {
if (baseExpression->isArray()) if (baseExpression->isArray())
{ {
// constant folding for arrays // constant folding for arrays
indexedExpression = addConstArrayNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location); indexedExpression = addConstArrayNode(index, baseExpression, location);
} }
else if (baseExpression->isVector()) else if (baseExpression->isVector())
{ {
// constant folding for vectors // constant folding for vectors
TVectorFields fields; TVectorFields fields;
fields.num = 1; fields.num = 1;
fields.offsets[0] = indexExpression->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
indexedExpression = addConstVectorNode(fields, baseExpression, location); indexedExpression = addConstVectorNode(fields, baseExpression, location);
} }
else if (baseExpression->isMatrix()) else if (baseExpression->isMatrix())
{ {
// constant folding for matrices // constant folding for matrices
indexedExpression = addConstMatrixNode(indexExpression->getAsConstantUnion()->getIConst(0), baseExpression, location); indexedExpression = addConstMatrixNode(index, baseExpression, location);
} }
} }
else else
{ {
if (indexExpression->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())
{
std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
}
else
{
if (baseExpression->isArray()) if (baseExpression->isArray())
{ {
if (baseExpression->getType().getArraySize() == 0) if (baseExpression->getType().getArraySize() == 0)
{ {
if (baseExpression->getType().getMaxArraySize() <= indexExpression->getAsConstantUnion()->getIConst(0)) if (baseExpression->getType().getMaxArraySize() <= index)
{ {
if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), indexExpression->getAsConstantUnion()->getIConst(0), true, location)) if (arraySetMaxSize(baseExpression->getAsSymbolNode(), baseExpression->getTypePointer(), index, true, location))
recover(); recover();
} }
else else
...@@ -2152,15 +2149,27 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co ...@@ -2152,15 +2149,27 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
recover(); recover();
} }
} }
else if ( indexExpression->getAsConstantUnion()->getIConst(0) >= baseExpression->getType().getArraySize()) else if (index >= baseExpression->getType().getArraySize())
{ {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << indexExpression->getAsConstantUnion()->getIConst(0) << "'"; extraInfoStream << "array index out of range '" << index << "'";
std::string extraInfo = extraInfoStream.str(); std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str()); error(location, "", "[", extraInfo.c_str());
recover(); recover();
index = baseExpression->getType().getArraySize() - 1;
}
} }
else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
{
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;
} }
indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
} }
} }
...@@ -2184,7 +2193,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co ...@@ -2184,7 +2193,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); 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