summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2016-08-06 11:39:11 -0400
committerNat Goodspeed <nat@lindenlab.com>2016-08-06 11:39:11 -0400
commit1773f44b6d9fffa7f5d0b2449184b2998e99be5a (patch)
tree48f92921a187f1929d540d2f4b788ea024878499
parent80adc9b6aa9814c74fd0c67c5de9d1765a089925 (diff)
MAINT-6584: Don't crash on inconsistent dims in a JPEG-2000 image.
Previous code would crump with LL_ERRS. But a bad image file should fail only the image load -- not crash the viewer. While at it, validate all components present, not just 0, 1, 2. While at it, make the failure message report which component and what the mismatched dimensions are, not just "Components don't have matching dimensions!"
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp33
1 files changed, 26 insertions, 7 deletions
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index ba1560ec56..025c77b85e 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -31,18 +31,31 @@
#include "llpointer.h"
#include "llmath.h"
#include "llkdumem.h"
+#include "stringize.h"
#include "kdu_block_coding.h"
#include <stdexcept>
+#include <iostream>
namespace {
+// exception used to keep KDU from terminating entire program -- see comments
+// in LLKDUMessageError::flush()
struct KDUError: public std::runtime_error
{
- KDUError(const std::string& msg): std::runtime_error(msg) {}
+ KDUError(const std::string& msg): std::runtime_error(msg) {}
};
} // anonymous namespace
+// stream kdu_dims to std::ostream
+// Turns out this must NOT be in the anonymous namespace!
+inline
+std::ostream& operator<<(std::ostream& out, const kdu_dims& dims)
+{
+ return out << "(" << dims.pos.x << "," << dims.pos.y << "),"
+ "[" << dims.size.x << "x" << dims.size.y << "]";
+}
+
class kdc_flow_control {
public:
@@ -287,13 +300,19 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
S32 components = mCodeStreamp->get_num_components();
- if (components >= 3)
- { // Check that components have consistent dimensions (for PPM file)
- kdu_dims dims1; mCodeStreamp->get_dims(1,dims1);
- kdu_dims dims2; mCodeStreamp->get_dims(2,dims2);
- if ((dims1 != dims) || (dims2 != dims))
+ // Check that components have consistent dimensions (for PPM file)
+ for (int idx = 1; idx < components; ++idx)
+ {
+ kdu_dims other_dims;
+ mCodeStreamp->get_dims(idx, other_dims);
+ if (other_dims != dims)
{
- LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL;
+ // This method is only called from methods that catch KDUError.
+ // We want to fail the image load, not crash the viewer.
+ throw KDUError(STRINGIZE("Component " << idx << " dimensions "
+ << other_dims
+ << " do not match component 0 dimensions "
+ << dims << "!"));
}
}