[Fix] (GL): raise INVALID_VALUE/INVALID_ENUM from glGetStringi for an index past the list or an unindexed name

This commit is contained in:
2026-10-12 08:32:43 -04:00
parent 049c8a421c
commit b4da0e1a87
2 changed files with 36 additions and 4 deletions
+12 -4
View File
@@ -811,8 +811,18 @@ namespace MobileGL::MG_Impl::GLImpl {
const GLubyte* GetStringi(GLenum name, GLuint index) {
MGLOG_D("glGetStringi, name: %s, index: %u", MG_Util::ConvertGLEnumToString(name).c_str(), index);
// GL 4.6 core 22.2: an index at or past the list's GL_NUM_* count is INVALID_VALUE, and a
// name glGetStringi does not index is INVALID_ENUM; both return NULL.
const auto recordError = [](ErrorCode code, const char* message) -> const GLubyte* {
MG_State::pGLContext->RecordError(code, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetStringi", message));
return nullptr;
};
if (name == GL_SPIR_V_EXTENSIONS) {
// GL_NUM_SPIR_V_EXTENSIONS is zero (see GetIntegerv), so every index is past the end.
return recordError(ErrorCode::InvalidValue, "index is not below GL_NUM_SPIR_V_EXTENSIONS.");
}
if (name != GL_EXTENSIONS) {
return (const GLubyte*)"";
return recordError(ErrorCode::InvalidEnum, "name is not an indexed string list.");
}
const auto& activeBackendObject = MG_Backend::pActiveBackendObject;
@@ -826,9 +836,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (index >= exts.size()) {
const auto& extras = ClientSideExtensions();
if (index - exts.size() < extras.size()) return (const GLubyte*)extras[index - exts.size()];
}
if (index >= exts.size()) {
return nullptr;
return recordError(ErrorCode::InvalidValue, "index is not below GL_NUM_EXTENSIONS.");
}
static Vector<String> extStrings;
@@ -1232,3 +1232,27 @@ TEST_F(RenderStateTest, FragmentShadingRatesListTheBackendMaskLargestFirst) {
EXPECT_EQ(nonTrivial, GL_FALSE);
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
}
// GL 4.6 core 22.2 (KHR-GL46.spirv_extensions.spirv_extensions_queries): an index at the list's
// GL_NUM_* count is INVALID_VALUE and a name glGetStringi does not index is INVALID_ENUM, both
// returning NULL rather than a string.
TEST_F(RenderStateTest, GetStringiRejectsOutOfRangeIndicesAndUnindexedNames) {
DrainPendingGlErrors();
EXPECT_EQ(MG_Impl::GLImpl::GetStringi(GL_SPIR_V_EXTENSIONS, 0), nullptr);
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_INVALID_VALUE);
GLint extensionCount = -1;
MG_Impl::GLImpl::GetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
ASSERT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
ASSERT_GE(extensionCount, 0);
if (extensionCount > 0) {
EXPECT_NE(MG_Impl::GLImpl::GetStringi(GL_EXTENSIONS, static_cast<GLuint>(extensionCount - 1)), nullptr);
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
}
EXPECT_EQ(MG_Impl::GLImpl::GetStringi(GL_EXTENSIONS, static_cast<GLuint>(extensionCount)), nullptr);
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_INVALID_VALUE);
EXPECT_EQ(MG_Impl::GLImpl::GetStringi(GL_VENDOR, 0), nullptr);
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_INVALID_ENUM);
}