Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp25
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.h15
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp9
3 files changed, 40 insertions, 9 deletions
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index f5c937654b3..1d65ef743ab 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -168,11 +168,17 @@ static void FlipDXT5BlockHalf(uint8_t *block)
FlipDXT1BlockHalf(block + 8);
}
-// Flips a DXTC image, by flipping and swapping DXTC blocks as appropriate.
-int FlipDXTCImage(
- unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data)
+int FlipDXTCImage(unsigned int width,
+ unsigned int height,
+ unsigned int levels,
+ int fourcc,
+ uint8_t *data,
+ int data_size,
+ unsigned int *r_num_valid_levels)
{
- // must have valid dimensions
+ *r_num_valid_levels = 0;
+
+ /* Must have valid dimensions. */
if (width == 0 || height == 0) {
return 0;
}
@@ -205,14 +211,25 @@ int FlipDXTCImage(
return 0;
}
+ *r_num_valid_levels = levels;
+
unsigned int mip_width = width;
unsigned int mip_height = height;
+ const uint8_t *data_end = data + data_size;
+
for (unsigned int i = 0; i < levels; i++) {
unsigned int blocks_per_row = (mip_width + 3) / 4;
unsigned int blocks_per_col = (mip_height + 3) / 4;
unsigned int blocks = blocks_per_row * blocks_per_col;
+ if (data + block_bytes * blocks > data_end) {
+ /* Stop flipping when running out of data to be modified, avoiding possible buffer overrun
+ * on a malformed files. */
+ *r_num_valid_levels = i;
+ break;
+ }
+
if (mip_height == 1) {
// no flip to do, and we're done.
break;
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.h b/source/blender/imbuf/intern/dds/FlipDXT.h
index b7056742430..0c046865f33 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.h
+++ b/source/blender/imbuf/intern/dds/FlipDXT.h
@@ -19,8 +19,17 @@
#include "BLI_sys_types.h"
-/* flip compressed DXT image vertically to fit OpenGL convention */
-int FlipDXTCImage(
- unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data);
+/**
+ * Flips a DXTC image, by flipping and swapping DXTC blocks as appropriate.
+ *
+ * Use to flip vertically to fit OpenGL convention.
+ */
+int FlipDXTCImage(unsigned int width,
+ unsigned int height,
+ unsigned int levels,
+ int fourcc,
+ uint8_t *data,
+ int data_size,
+ unsigned int *r_num_valid_levels);
#endif
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 832b380bbc2..9bd365747cb 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -185,8 +185,13 @@ struct ImBuf *imb_load_dds(const unsigned char *mem,
/* flip compressed texture */
if (ibuf->dds_data.data) {
- FlipDXTCImage(
- dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
+ FlipDXTCImage(dds.width(),
+ dds.height(),
+ ibuf->dds_data.nummipmaps,
+ dds.fourCC(),
+ ibuf->dds_data.data,
+ ibuf->dds_data.size,
+ &ibuf->dds_data.nummipmaps);
}
}
else {