From 4365124bd39bd6edbda6eaef64ec72a1a10565f8 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 30 Oct 2021 23:32:18 +0300 Subject: [PATCH] Add some checks for invalid arguments --- source/backends/opengl/deviceinfo_backend.cpp | 3 +++ source/core/buffer.cpp | 2 ++ source/core/deviceinfo.h | 1 + source/core/sampler.cpp | 5 +++++ source/core/texture1d.cpp | 4 ++-- source/core/texture1d.h | 2 +- source/core/texture2d.cpp | 4 ++-- source/core/texture2d.h | 2 +- source/core/texture3d.cpp | 4 ++-- source/core/texture3d.h | 2 +- source/core/texturecube.cpp | 4 ++-- source/core/texturecube.h | 2 +- 12 files changed, 23 insertions(+), 12 deletions(-) diff --git a/source/backends/opengl/deviceinfo_backend.cpp b/source/backends/opengl/deviceinfo_backend.cpp index 30eeb032..df085dc7 100644 --- a/source/backends/opengl/deviceinfo_backend.cpp +++ b/source/backends/opengl/deviceinfo_backend.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include "deviceinfo.h" @@ -34,6 +35,8 @@ Limits::Limits() glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, reinterpret_cast(&max_uniform_bindings)); glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, reinterpret_cast(&uniform_buffer_alignment)); } + if(EXT_texture_filter_anisotropic) + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &max_anisotropy); } diff --git a/source/core/buffer.cpp b/source/core/buffer.cpp index 557e576d..240fcd72 100644 --- a/source/core/buffer.cpp +++ b/source/core/buffer.cpp @@ -33,6 +33,8 @@ void Buffer::sub_data(size_t off, size_t sz, const void *d) { if(size==0) throw invalid_operation("Buffer::sub_data"); + if(off>size || off+sz>size) + throw out_of_range("Buffer::sub_data"); BufferBackend::sub_data(off, sz, d); } diff --git a/source/core/deviceinfo.h b/source/core/deviceinfo.h index 6ac75ca1..a9584119 100644 --- a/source/core/deviceinfo.h +++ b/source/core/deviceinfo.h @@ -18,6 +18,7 @@ struct Limits unsigned max_samples = 4; unsigned max_uniform_bindings = 24; unsigned uniform_buffer_alignment = 256; + float max_anisotropy = 1.0f; Limits(); }; diff --git a/source/core/sampler.cpp b/source/core/sampler.cpp index 6658ef9a..7560029c 100644 --- a/source/core/sampler.cpp +++ b/source/core/sampler.cpp @@ -1,4 +1,5 @@ #include +#include "deviceinfo.h" #include "error.h" #include "sampler.h" @@ -21,6 +22,8 @@ void Sampler::set_min_filter(TextureFilter f) void Sampler::set_mag_filter(TextureFilter f) { + if(is_mipmapped(f)) + throw invalid_argument("Sampler::set_mag_filter"); mag_filter = f; dirty_params |= MAG_FILTER; } @@ -35,6 +38,8 @@ void Sampler::set_max_anisotropy(float a) { if(a<1.0f) throw invalid_argument("Sampler::set_max_anisotropy"); + if(a>DeviceInfo::get_global().limits.max_anisotropy) + throw out_of_range("Sampler::set_max_anisotropy"); bool supported = check_anisotropic(a>1.0f); max_anisotropy = a; if(supported) diff --git a/source/core/texture1d.cpp b/source/core/texture1d.cpp index 1015a0af..ae4347e3 100644 --- a/source/core/texture1d.cpp +++ b/source/core/texture1d.cpp @@ -31,11 +31,11 @@ void Texture1D::image(unsigned level, const void *data) return sub_image(level, 0, get_level_size(level), data); } -void Texture1D::sub_image(unsigned level, int x, unsigned wd, const void *data) +void Texture1D::sub_image(unsigned level, unsigned x, unsigned wd, const void *data) { if(width==0) throw invalid_operation("Texture1D::sub_image"); - if(level>=levels) + if(level>=levels || x>width || x+wd>width) throw out_of_range("Texture1D::sub_image"); Texture1DBackend::sub_image(level, x, wd, data); diff --git a/source/core/texture1d.h b/source/core/texture1d.h index 7ef55f80..f99d3ef0 100644 --- a/source/core/texture1d.h +++ b/source/core/texture1d.h @@ -46,7 +46,7 @@ public: /** Replaces a range of texels in the texture. Allocated storage must exist. The image data is interpreted according to the storage format and the range must be fully inside the selected mipmap level. */ - void sub_image(unsigned level, int x, unsigned wd, const void *); + void sub_image(unsigned level, unsigned x, unsigned wd, const void *); virtual void image(const Graphics::Image &, unsigned = 0); diff --git a/source/core/texture2d.cpp b/source/core/texture2d.cpp index 3c3579c1..41f4ab11 100644 --- a/source/core/texture2d.cpp +++ b/source/core/texture2d.cpp @@ -38,11 +38,11 @@ void Texture2D::image(unsigned level, const void *data) return sub_image(level, 0, 0, size.x, size.y, data); } -void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data) +void Texture2D::sub_image(unsigned level, unsigned x, unsigned y, unsigned wd, unsigned ht, const void *data) { if(width==0 || height==0) throw invalid_operation("Texture2D::sub_image"); - if(level>=levels) + if(level>=levels || x>width || x+wd>width || y>height || y+ht>height) throw out_of_range("Texture2D::sub_image"); Texture2DBackend::sub_image(level, x, y, wd, ht, data); diff --git a/source/core/texture2d.h b/source/core/texture2d.h index 427e1795..1c750bd1 100644 --- a/source/core/texture2d.h +++ b/source/core/texture2d.h @@ -50,7 +50,7 @@ public: /** Replaces a rectangular region of the texture. Allocated storage must exist. The image data is interpreted according to the storage format and the region must be fully inside the selected mipmap level. */ - void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *); + void sub_image(unsigned level, unsigned x, unsigned y, unsigned wd, unsigned ht, const void *); virtual void image(const Graphics::Image &, unsigned = 0); diff --git a/source/core/texture3d.cpp b/source/core/texture3d.cpp index e48b7662..0125dd09 100644 --- a/source/core/texture3d.cpp +++ b/source/core/texture3d.cpp @@ -39,11 +39,11 @@ void Texture3D::image(unsigned level, const void *data) return sub_image(level, 0, 0, 0, size.x, size.y, size.z, data); } -void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, const void *data) +void Texture3D::sub_image(unsigned level, unsigned x, unsigned y, unsigned z, unsigned wd, unsigned ht, unsigned dp, const void *data) { if(width==0 || height==0 || depth==0) throw invalid_operation("Texture3D::sub_image"); - if(level>=levels) + if(level>=levels || x>width || x+wd>width || y>height || y+ht>height || z>depth || z+dp>depth) throw out_of_range("Texture3D::sub_image"); Texture3DBackend::sub_image(level, x, y, z, wd, ht, dp, data); diff --git a/source/core/texture3d.h b/source/core/texture3d.h index 9d5104c9..1fbcf4ee 100644 --- a/source/core/texture3d.h +++ b/source/core/texture3d.h @@ -52,7 +52,7 @@ public: /** Replaces a cuboid-shaped region of the texture. Allocated storage must exist. The image data is interpreted according to the storage format and the region must be fully inside the texture. */ - void sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, const void *); + void sub_image(unsigned level, unsigned x, unsigned y, unsigned z, unsigned wd, unsigned ht, unsigned dp, const void *); /** Sets the texture's contents from an image. The image is treated as a stack of square layers and its height must be divisible by its width. If diff --git a/source/core/texturecube.cpp b/source/core/texturecube.cpp index 9aec4b1d..ff2b2875 100644 --- a/source/core/texturecube.cpp +++ b/source/core/texturecube.cpp @@ -55,11 +55,11 @@ void TextureCube::image(TextureCubeFace face, unsigned level, const void *data) return sub_image(face, level, 0, 0, lsz, lsz, data); } -void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data) +void TextureCube::sub_image(TextureCubeFace face, unsigned level, unsigned x, unsigned y, unsigned wd, unsigned ht, const void *data) { if(size==0) throw invalid_operation("TextureCube::sub_image"); - if(level>=levels) + if(level>=levels || x>size || x+wd>size || y>size || y+ht>size) throw out_of_range("TextureCube::sub_image"); TextureCubeBackend::sub_image(face, level, x, y, wd, ht, data); diff --git a/source/core/texturecube.h b/source/core/texturecube.h index aa43c9da..0f753c75 100644 --- a/source/core/texturecube.h +++ b/source/core/texturecube.h @@ -68,7 +68,7 @@ public: /** Replaces a rectangular region of a face. Allocated storage must exist. The image data is interpreted according to the storage format and the region must be fully inside the face. */ - void sub_image(TextureCubeFace, unsigned level, int x, int y, unsigned w, unsigned h, const void *); + void sub_image(TextureCubeFace, unsigned level, unsigned x, unsigned y, unsigned w, unsigned h, const void *); void image(TextureCubeFace, const Graphics::Image &); -- 2.43.0