From 6a6662bfa9ad22f088f8ae71b8883faf972fb071 Mon Sep 17 00:00:00 2001
From: John Stark <jhnstrk@gmail.com>
Date: Mon, 17 Oct 2016 22:46:55 +0200
Subject: [PATCH] Fixing overflow in ocnt. see #696

---
 dcmimgle/include/dcmtk/dcmimgle/dimoopxt.h | 41 +++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/dcmimgle/include/dcmtk/dcmimgle/dimoopxt.h b/dcmimgle/include/dcmtk/dcmimgle/dimoopxt.h
index ba3e71e..ee91a48 100644
--- a/dcmimgle/include/dcmtk/dcmimgle/dimoopxt.h
+++ b/dcmimgle/include/dcmtk/dcmimgle/dimoopxt.h
@@ -277,14 +277,21 @@ class DiMonoOutputPixelTemplate
     /** initialize an optimization LUT if the optimization criteria is fulfilled
      *
      ** @param  lut   reference to storage area where the optimization LUT should be stored
-     *  @param  ocnt  number of entries for the optimization LUT
+     *  @param  ocnt  number of entries for the optimization LUT (out)
+     *  @param  absRange  absolute range to values to be encompassed by the LUT.
      */
     inline int initOptimizationLUT(T3 *&lut,
-                                   const unsigned long ocnt)
+                                   unsigned long & ocnt,
+                                   const double & absRange)
     {
         int result = 0;
-        if ((sizeof(T1) <= 2) && (Count > 3 * ocnt))                          // optimization criteria
+        if (absRange > OFnumeric_limits<unsigned long>::max())
+        {
+            return result;
+        }
+        if ((sizeof(T1) <= 2) && (OFstatic_cast(double,Count) > 3. * absRange))   // optimization criteria
         {                                                                     // use LUT for optimization
+            ocnt = OFstatic_cast(unsigned long, absRange);
             lut = new T3[ocnt];
             if (lut != NULL)
             {
@@ -376,7 +383,8 @@ class DiMonoOutputPixelTemplate
                     const T2 absmin = OFstatic_cast(T2, inter->getAbsMinimum());
                     const T2 firstentry = vlut->getFirstEntry(value);                   // choose signed/unsigned method
                     const T2 lastentry = vlut->getLastEntry(value);
-                    const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
+                    const double absRange = inter->getAbsMaxRange();
+                    unsigned long ocnt = 0;  // number of LUT entries
                     const T1 *p = pixel + start;
                     T3 *q = Data;
                     T3 *lut = NULL;
@@ -389,7 +397,7 @@ class DiMonoOutputPixelTemplate
                         const double gradient1 = OFstatic_cast(double, pcnt) / OFstatic_cast(double, vlut->getAbsMaxRange());
                         const Uint32 firstvalue = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getFirstValue()) * gradient1);
                         const Uint32 lastvalue = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getLastValue()) * gradient1);
-                        if (initOptimizationLUT(lut, ocnt))
+                        if (initOptimizationLUT(lut, ocnt, absRange))
                         {                                                                 // use LUT for optimization
                             q = lut;
                             if (dlut != NULL)                                             // perform display transformation
@@ -495,7 +503,7 @@ class DiMonoOutputPixelTemplate
                         const double gradient = outrange / OFstatic_cast(double, vlut->getAbsMaxRange());
                         const T3 firstvalue = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getFirstValue()) * gradient);
                         const T3 lastvalue = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getLastValue()) * gradient);
-                        if (initOptimizationLUT(lut, ocnt))
+                        if (initOptimizationLUT(lut, ocnt, absRange))
                         {                                                                 // use LUT for optimization
                             q = lut;
                             if (dlut != NULL)                                             // perform display transformation
@@ -622,7 +630,8 @@ class DiMonoOutputPixelTemplate
                 const double absmin = inter->getAbsMinimum();
                 const double absmax = inter->getAbsMaximum();
                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low) + 1;
-                const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
+                const double absRange = inter->getAbsMaxRange();
+                unsigned long ocnt = 0;  // number of LUT entries
                 DCMIMGLE_TRACE("intermediate pixel data - absmin: " << absmin << ", absmax: " << absmax);
                 const T1 *p = pixel + start;
                 T3 *q = Data;
@@ -635,7 +644,7 @@ class DiMonoOutputPixelTemplate
                     Uint32 value;                                                     // presentation LUT is always unsigned
                     const double gradient1 = OFstatic_cast(double, plut->getCount()) / inter->getAbsMaxRange();
                     const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange());
-                    if (initOptimizationLUT(lut, ocnt))
+                    if (initOptimizationLUT(lut, ocnt, absRange))
                     {                                                                 // use LUT for optimization
                         q = lut;
                         if (dlut != NULL)                                             // perform display transformation
@@ -701,7 +710,7 @@ class DiMonoOutputPixelTemplate
                 } else {                                                              // has no presentation LUT
                     createDisplayLUT(dlut, disp, inter->getBits());
                     const double gradient = outrange / (inter->getAbsMaxRange());
-                    if (initOptimizationLUT(lut, ocnt))
+                    if (initOptimizationLUT(lut, ocnt, absRange))
                     {                                                                 // use LUT for optimization
                         q = lut;
                         if (dlut != NULL)                                             // perform display transformation
@@ -784,7 +793,8 @@ class DiMonoOutputPixelTemplate
                 const DiDisplayLUT *dlut = NULL;
                 const double absmin = inter->getAbsMinimum();
                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low);  // output range
-                const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
+                const double absRange = inter->getAbsMaxRange();
+                unsigned long ocnt = 0;  // number of LUT entries
                 const T1 *p = pixel + start;
                 T3 *q = Data;
                 unsigned long i;
@@ -797,7 +807,7 @@ class DiMonoOutputPixelTemplate
                     Uint32 value2;                                                    // presentation LUT is always unsigned
                     const double plutcnt_1 = OFstatic_cast(double, plut->getCount() - 1);
                     const double plutmax_1 = OFstatic_cast(double, plut->getAbsMaxRange() - 1);
-                    if (initOptimizationLUT(lut, ocnt))
+                    if (initOptimizationLUT(lut, ocnt, absRange))
                     {                                                                 // use LUT for optimization
                         q = lut;
                         if (dlut != NULL)                                             // perform display transformation
@@ -854,7 +864,7 @@ class DiMonoOutputPixelTemplate
                     }
                 } else {                                                              // has no presentation LUT
                     createDisplayLUT(dlut, disp, bitsof(T1));
-                    if (initOptimizationLUT(lut, ocnt))
+                    if (initOptimizationLUT(lut, ocnt, absRange))
                     {                                                                 // use LUT for optimization
                         q = lut;
                         if (dlut != NULL)                                             // perform display transformation
@@ -946,7 +956,8 @@ class DiMonoOutputPixelTemplate
                 const double leftBorder = center - 0.5 - width_1 / 2;                 // window borders, according to supplement 33
                 const double rightBorder = center - 0.5 + width_1 / 2;
                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low);  // output range
-                const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
+                const double absRange = inter->getAbsMaxRange();
+                unsigned long ocnt = 0;  // number of LUT entries
                 const T1 *p = pixel + start;
                 T3 *q = Data;
                 unsigned long i;
@@ -960,7 +971,7 @@ class DiMonoOutputPixelTemplate
                     const Uint32 pcnt = plut->getCount();
                     const double plutmax_1 = OFstatic_cast(double, plut->getAbsMaxRange()) - 1;
                     const double gradient1 = (width_1 == 0) ? 0 : OFstatic_cast(double, pcnt - 1) / width_1;
-                    if (initOptimizationLUT(lut, ocnt))
+                    if (initOptimizationLUT(lut, ocnt, absRange))
                     {                                                                 // use LUT for optimization
                         q = lut;
                         if (dlut != NULL)                                             // perform display transformation
@@ -1037,7 +1048,7 @@ class DiMonoOutputPixelTemplate
                     }
                 } else {                                                              // has no presentation LUT
                     createDisplayLUT(dlut, disp, bitsof(T1));
-                    if (initOptimizationLUT(lut, ocnt))
+                    if (initOptimizationLUT(lut, ocnt, absRange))
                     {                                                                 // use LUT for optimization
                         q = lut;
                         if (dlut != NULL)                                             // perform display transformation
-- 
2.6.4

