diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index be14b57e..03338475 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -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("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 extStrings; diff --git a/MobileGL/MG_Test/State/RenderStateTest.cpp b/MobileGL/MG_Test/State/RenderStateTest.cpp index ff042f3c..66e718ef 100644 --- a/MobileGL/MG_Test/State/RenderStateTest.cpp +++ b/MobileGL/MG_Test/State/RenderStateTest.cpp @@ -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(extensionCount - 1)), nullptr); + EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); + } + EXPECT_EQ(MG_Impl::GLImpl::GetStringi(GL_EXTENSIONS, static_cast(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); +}