diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 645161c2f..a2d52b6b8 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -18,6 +18,7 @@ BX_ERROR_RESULT(BGFX_ERROR_TEXTURE_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 1) ); BX_ERROR_RESULT(BGFX_ERROR_FRAME_BUFFER_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 2) ); +BX_ERROR_RESULT(BGFX_ERROR_IDENTIFIER_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 3) ); namespace bgfx { @@ -973,7 +974,7 @@ namespace bgfx return s_predefinedName[_enum]; } - PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name) + PredefinedUniform::Enum nameToPredefinedUniformEnum(const bx::StringView& _name) { for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii) { @@ -4644,6 +4645,55 @@ namespace bgfx return err.isOk(); } + void isIdentifierValid(const bx::StringView& _name, bx::Error* _err) + { + BX_ERROR_SCOPE(_err, "Uniform identifier validation"); + + BGFX_ERROR_CHECK(false + || !_name.isEmpty() + , _err + , BGFX_ERROR_IDENTIFIER_VALIDATION + , "Identifier can't be empty." + , "" + ); + + BGFX_ERROR_CHECK(false + || PredefinedUniform::Count == nameToPredefinedUniformEnum(_name) + , _err + , BGFX_ERROR_IDENTIFIER_VALIDATION + , "Identifier can't use predefined uniform name." + , "" + ); + + const char ch = *_name.getPtr(); + BGFX_ERROR_CHECK(false + || bx::isAlpha(ch) + || '_' == ch + , _err + , BGFX_ERROR_IDENTIFIER_VALIDATION + , "The first character of an identifier should be either an alphabet character or an underscore." + , "" + ); + + bool result = true; + + for (const char* ptr = _name.getPtr() + 1, *term = _name.getTerm() + ; ptr != term && result + ; ++ptr + ) + { + result &= bx::isAlphaNum(*ptr) || '_' == *ptr; + } + + BGFX_ERROR_CHECK(false + || result + , _err + , BGFX_ERROR_IDENTIFIER_VALIDATION + , "Identifier contains invalid characters. Identifier must be the alphabet character, number, or underscore." + , "" + ); + } + void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format) { bimg::imageGetSize( (bimg::TextureInfo*)&_info, _width, _height, _depth, _cubeMap, _hasMips, _numLayers, bimg::TextureFormat::Enum(_format) ); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 6205222df..e75d07a3a 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -304,6 +304,7 @@ namespace bgfx extern PlatformData g_platformData; extern bool g_platformDataChangedSinceReset; extern void isFrameBufferValid(uint8_t _num, const Attachment* _attachment, bx::Error* _err); + extern void isIdentifierValid(const bx::StringView& _name, bx::Error* _err); #if BGFX_CONFIG_MAX_DRAW_CALLS < (64<<10) typedef uint16_t RenderItemCount; @@ -792,7 +793,7 @@ namespace bgfx const char* getUniformTypeName(UniformType::Enum _enum); UniformType::Enum nameToUniformTypeEnum(const char* _name); const char* getPredefinedUniformName(PredefinedUniform::Enum _enum); - PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name); + PredefinedUniform::Enum nameToPredefinedUniformEnum(const bx::StringView& _name); class CommandBuffer { @@ -4692,10 +4693,15 @@ namespace bgfx { BGFX_MUTEX_SCOPE(m_resourceApiLock); - if (PredefinedUniform::Count != nameToPredefinedUniformEnum(_name) ) { - BX_TRACE("%s is predefined uniform name.", _name); - return BGFX_INVALID_HANDLE; + bx::Error err; + isIdentifierValid(_name, &err); + BGFX_ERROR_ASSERT(&err); + + if (!err.isOk() ) + { + return BGFX_INVALID_HANDLE; + } } _num = bx::max(1, _num);