[Bf-blender-cvs] [db80d5c560f] master: Fix T62852: crash reading corrupt DDS file.

Brecht Van Lommel noreply at git.blender.org
Tue Apr 16 03:41:53 CEST 2019


Commit: db80d5c560f55eaaad2702a4dae61b4b9c027e26
Author: Brecht Van Lommel
Date:   Tue Apr 16 03:39:29 2019 +0200
Branches: master
https://developer.blender.org/rBdb80d5c560f55eaaad2702a4dae61b4b9c027e26

Fix T62852: crash reading corrupt DDS file.

===================================================================

M	source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
M	source/blender/imbuf/intern/dds/Stream.cpp
M	source/blender/imbuf/intern/dds/Stream.h
M	source/blender/imbuf/intern/dds/dds_api.cpp

===================================================================

diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index 16a7525bb80..76de84cdee5 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -1148,6 +1148,12 @@ void *DirectDrawSurface::readData(uint &rsize)
 	stream.seek(header_size);
 	mem_read(stream, data, size);
 
+	if (stream.failed) {
+		free(data);
+		data = NULL;
+		rsize = 0;
+	}
+
 	// Maybe check if size == rsize? assert() isn't in this scope...
 
 	return data;
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index 92b5923e8a1..d8c2862cc09 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -30,7 +30,7 @@ static const char *msg_error_read = "DDS: trying to read beyond end of stream (c
 unsigned int Stream::seek(unsigned int p)
 {
 	if (p > size) {
-		puts(msg_error_seek);
+		set_failed(msg_error_seek);
 	}
 	else {
 		pos = p;
@@ -42,7 +42,7 @@ unsigned int Stream::seek(unsigned int p)
 unsigned int mem_read(Stream & mem, unsigned long long & i)
 {
 	if (mem.pos + 8 > mem.size) {
-		puts(msg_error_seek);
+		mem.set_failed(msg_error_seek);
 		return(0);
 	}
 	memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian
@@ -53,7 +53,7 @@ unsigned int mem_read(Stream & mem, unsigned long long & i)
 unsigned int mem_read(Stream & mem, unsigned int & i)
 {
 	if (mem.pos + 4 > mem.size) {
-		puts(msg_error_read);
+		mem.set_failed(msg_error_read);
 		return(0);
 	}
 	memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian
@@ -64,7 +64,7 @@ unsigned int mem_read(Stream & mem, unsigned int & i)
 unsigned int mem_read(Stream & mem, unsigned short & i)
 {
 	if (mem.pos + 2 > mem.size) {
-		puts(msg_error_read);
+		mem.set_failed(msg_error_read);
 		return(0);
 	}
 	memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian
@@ -75,7 +75,7 @@ unsigned int mem_read(Stream & mem, unsigned short & i)
 unsigned int mem_read(Stream & mem, unsigned char & i)
 {
 	if (mem.pos + 1 > mem.size) {
-		puts(msg_error_read);
+		mem.set_failed(msg_error_read);
 		return(0);
 	}
 	i = (mem.mem + mem.pos)[0];
@@ -86,10 +86,18 @@ unsigned int mem_read(Stream & mem, unsigned char & i)
 unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt)
 {
 	if (mem.pos + cnt > mem.size) {
-		puts(msg_error_read);
+		mem.set_failed(msg_error_read);
 		return(0);
 	}
 	memcpy(i, mem.mem + mem.pos, cnt);
 	mem.pos += cnt;
 	return(cnt);
 }
+
+void Stream::set_failed(const char *msg)
+{
+	if (!failed) {
+		puts(msg_error_seek);
+		failed = true;
+	}
+}
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
index 3da0feb5aeb..b9fba2ef8b2 100644
--- a/source/blender/imbuf/intern/dds/Stream.h
+++ b/source/blender/imbuf/intern/dds/Stream.h
@@ -28,8 +28,10 @@ struct Stream {
 	unsigned char *mem; // location in memory
 	unsigned int size;  // size
 	unsigned int pos;   // current position
-	Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0) {}
+	bool failed;        // error occured when seeking
+	Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0), failed(false) {}
 	unsigned int seek(unsigned int p);
+	void set_failed(const char *msg);
 };
 
 unsigned int mem_read(Stream & mem, unsigned long long & i);
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 37577eefc56..fa88f81b55a 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -165,7 +165,9 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, size_t size, int flags, cha
 			ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size);
 
 			/* flip compressed texture */
-			FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
+			if (ibuf->dds_data.data) {
+				FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
+			}
 		}
 		else {
 			ibuf->dds_data.data = NULL;



More information about the Bf-blender-cvs mailing list