diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-04-16 04:39:29 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-04-16 04:41:17 +0300 |
commit | db80d5c560f55eaaad2702a4dae61b4b9c027e26 (patch) | |
tree | 8b6cb721cea99c29e615429adf8d7f37996af552 /source/blender | |
parent | 6a50a3d140d7050dcfa391eb55d5a03720b06f3a (diff) |
Fix T62852: crash reading corrupt DDS file.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/imbuf/intern/dds/DirectDrawSurface.cpp | 6 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/Stream.cpp | 20 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/Stream.h | 4 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dds/dds_api.cpp | 4 |
4 files changed, 26 insertions, 8 deletions
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; |