]> git.tdb.fi Git - libs/gl.git/commitdiff
Perform range checks in UniformBlock in debug builds
authorMikko Rasa <tdb@tdb.fi>
Wed, 10 Nov 2021 18:10:18 +0000 (20:10 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 10 Nov 2021 18:10:18 +0000 (20:10 +0200)
source/core/uniformblock.cpp
source/core/uniformblock.h

index adadf0561c8051c54d06c2ac43a3a3608e6539dd..256858580b9721a60663cbc0b80dd282c7a6e7db 100644 (file)
@@ -21,19 +21,19 @@ void UniformBlock::store(const ReflectData::UniformInfo &info, size_t array_size
 {
        array_size = min(array_size, max<size_t>(info.array_size, 1U));
 
-       char *store_ptr;
+       size_t store_offset;
        bool packed;
        if(info.block->bind_point<0)
        {
                if(info.location<0)
                        return;
 
-               store_ptr = data.data()+info.location*16;
+               store_offset = info.location*16;
                packed = true;
        }
        else
        {
-               store_ptr = data.data()+info.offset;
+               store_offset = info.offset;
                if(array_size!=1 && info.array_stride!=get_type_size(info.type))
                        packed = false;
                else if(is_matrix(info.type))
@@ -42,16 +42,19 @@ void UniformBlock::store(const ReflectData::UniformInfo &info, size_t array_size
                        packed = true;
        }
 
+       char *store_ptr = data.data()+store_offset;
        const char *value_ptr = static_cast<const char *>(value);
        if(packed)
        {
-               const char *data_end = value_ptr+array_size*get_type_size(info.type);
-               copy(value_ptr, data_end, store_ptr);
+               size_t value_size = array_size*get_type_size(info.type);
+               check_store_range(store_offset, value_size);
+               copy(value_ptr, value_ptr+value_size, store_ptr);
        }
        else if(is_matrix(info.type))
        {
                unsigned col_size = get_type_size(get_matrix_column_type(info.type));
                unsigned cols = get_type_size(info.type)/col_size;
+               check_store_range(store_offset, (array_size-1)*info.array_stride+(cols-1)*info.matrix_stride+col_size);
                for(unsigned i=0; i<array_size; ++i)
                {
                        char *elem_ptr = store_ptr;
@@ -67,6 +70,7 @@ void UniformBlock::store(const ReflectData::UniformInfo &info, size_t array_size
        else
        {
                unsigned elem_size = get_type_size(info.type);
+               check_store_range(store_offset, (array_size-1)*info.array_stride+elem_size);
                for(unsigned i=0; i<array_size; ++i)
                {
                        copy(value_ptr, value_ptr+elem_size, store_ptr);
@@ -78,5 +82,13 @@ void UniformBlock::store(const ReflectData::UniformInfo &info, size_t array_size
        dirty = true;
 }
 
+void UniformBlock::check_store_range(size_t offs, size_t size)
+{
+#ifdef DEBUG
+       if(offs>data.size() || offs+size>data.size())
+               throw out_of_range("UniformBlock::store");
+#endif
+}
+
 } // namespace GL
 } // namespace Msp
index a71dab25f71afa7108e0867cd9f4740417ac169a..810afd7758525455afdaaf8c90e16b78ea318cd8 100644 (file)
@@ -36,6 +36,7 @@ private:
 
 public:
        void store(const ReflectData::UniformInfo &, std::size_t, const void *);
+       void check_store_range(std::size_t, std::size_t);
 };
 
 } // namespace GL