Complete validation of glGetAttribLocation()

-Added more checks to glGetAttribLocation() similar to
glBindAttribLocation().
-Added the corresponding unit tests. Using a reserved
prefix in glGetAttribLocation() should return -1.

Bug: angleproject:2419
Change-Id: I3f691f344c7003f855e53d35cd5f9578069acdae
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3252643
Commit-Queue: Amirali Abdolrashidi <abdolrashidi@google.com>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Amirali Abdolrashidi 2021-10-29 12:45:53 -07:00 коммит произвёл Angle LUCI CQ
Родитель a514df081d
Коммит 6a749cdacd
2 изменённых файлов: 60 добавлений и 4 удалений

Просмотреть файл

@ -4335,14 +4335,30 @@ bool ValidateGetAttribLocation(const Context *context,
ShaderProgramID program, ShaderProgramID program,
const GLchar *name) const GLchar *name)
{ {
// The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for if (strncmp(name, "gl_", 3) == 0)
// shader-related entry points
if (context->isWebGL() && !IsValidESSLString(name, strlen(name)))
{ {
context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters);
return false; return false;
} }
if (context->isWebGL())
{
const size_t length = strlen(name);
if (!IsValidESSLString(name, length))
{
// The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
// for shader-related entry points
context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters);
return false;
}
if (!ValidateWebGLNameLength(context, entryPoint, length) ||
strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
{
return false;
}
}
Program *programObject = GetValidProgram(context, entryPoint, program); Program *programObject = GetValidProgram(context, entryPoint, program);
if (!programObject) if (!programObject)

Просмотреть файл

@ -2249,6 +2249,35 @@ TEST_P(WebGLCompatibilityTest, BindAttribLocationLimitation)
EXPECT_GL_ERROR(GL_INVALID_VALUE); EXPECT_GL_ERROR(GL_INVALID_VALUE);
} }
// Tests getAttribLocation for reserved prefixes
TEST_P(WebGLCompatibilityTest, GetAttribLocationNameLimitation)
{
GLint attrLocation;
attrLocation = glGetAttribLocation(0, "gl_attr");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(-1, attrLocation);
attrLocation = glGetAttribLocation(0, "webgl_attr");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(-1, attrLocation);
attrLocation = glGetAttribLocation(0, "_webgl_attr");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(-1, attrLocation);
}
// Tests getAttribLocation for length limits
TEST_P(WebGLCompatibilityTest, GetAttribLocationLengthLimitation)
{
constexpr int maxLocStringLength = 256;
const std::string tooLongString(maxLocStringLength + 1, '_');
glGetAttribLocation(0, static_cast<const GLchar *>(tooLongString.c_str()));
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Test that having no attributes with a zero divisor is valid in WebGL2 // Test that having no attributes with a zero divisor is valid in WebGL2
TEST_P(WebGL2CompatibilityTest, InstancedDrawZeroDivisor) TEST_P(WebGL2CompatibilityTest, InstancedDrawZeroDivisor)
{ {
@ -5404,6 +5433,17 @@ TEST_P(WebGL2CompatibilityTest, BindAttribLocationLimitation)
EXPECT_GL_ERROR(GL_INVALID_VALUE); EXPECT_GL_ERROR(GL_INVALID_VALUE);
} }
// Tests getAttribLocation for length limit
TEST_P(WebGL2CompatibilityTest, GetAttribLocationLengthLimitation)
{
constexpr int maxLocStringLength = 1024;
const std::string tooLongString(maxLocStringLength + 1, '_');
glGetAttribLocation(0, static_cast<const GLchar *>(tooLongString.c_str()));
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Covers a bug in transform feedback loop detection. // Covers a bug in transform feedback loop detection.
TEST_P(WebGL2CompatibilityTest, TransformFeedbackCheckNullDeref) TEST_P(WebGL2CompatibilityTest, TransformFeedbackCheckNullDeref)
{ {