Restrict the size of shader arrays.
This prevents overflow issues in the HLSL translator and some drivers. The
limit it hard-coded to 65536 to be larger than the Shader Model 5 register
limit (4096) to account for register allocation optimizations and future
hardware.
BUG=379799
Change-Id: I20f05c9dd230fbfc1c92af52533cd2b50f2ff994
Reviewed-on: https://chromium-review.googlesource.com/202939
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index eac8f2c..f900966 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -701,28 +701,44 @@
return true;
}
+ unsigned int unsignedSize = 0;
+
if (constant->getBasicType() == EbtUInt)
{
- unsigned int uintSize = constant->getUConst(0);
- if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
- {
- error(line, "array size too large", "");
- size = 1;
- return true;
- }
-
- size = static_cast<int>(uintSize);
+ unsignedSize = constant->getUConst(0);
+ size = static_cast<int>(unsignedSize);
}
else
{
size = constant->getIConst(0);
- if (size <= 0)
+ if (size < 0)
{
- error(line, "array size must be a positive integer", "");
+ error(line, "array size must be non-negative", "");
size = 1;
return true;
}
+
+ unsignedSize = static_cast<unsigned int>(size);
+ }
+
+ if (size == 0)
+ {
+ error(line, "array size must be greater than zero", "");
+ size = 1;
+ return true;
+ }
+
+ // The size of arrays is restricted here to prevent issues further down the
+ // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
+ // 4096 registers so this should be reasonable even for aggressively optimizable code.
+ const unsigned int sizeLimit = 65536;
+
+ if (unsignedSize > sizeLimit)
+ {
+ error(line, "array size too large", "");
+ size = 1;
+ return true;
}
return false;