Преглед изворни кода

HPCC-14711 Fix potential overflows in binary searches

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday пре 9 година
родитељ
комит
65f22ff8f6

+ 1 - 1
common/thorhelper/roxiehelper.cpp

@@ -881,7 +881,7 @@ public:
             unsigned int a = 0;
             while ((int)a<b)
             {
-                int i = (a+b)/2;
+                int i = (a+b)/2; // cannot overflow
                 int rc = _compare->docompare(next, rows[i]);
                 if (rc>=0)
                     a = i+1;

+ 2 - 2
ecl/hql/hqlexpr.cpp

@@ -12719,7 +12719,7 @@ static IHqlExpression * createComma(const HqlExprArray & exprs, unsigned first,
 {
     if (first +1 == last)
         return &OLINK(exprs.item(first));
-    unsigned mid = (first+last)/2;
+    unsigned mid = first+(last-first)/2;
     return createComma(createComma(exprs, first, mid), createComma(exprs, mid, last));
 }
 
@@ -12740,7 +12740,7 @@ IHqlExpression * createBalanced(node_operator op, ITypeInfo * type, const HqlExp
 {
     if (first +1 == last)
         return &OLINK(exprs.item(first));
-    unsigned mid = (first+last)/2;
+    unsigned mid = first+(last-first)/2;
     IHqlExpression * left = createBalanced(op, type, exprs, first, mid);
     IHqlExpression * right = createBalanced(op, type, exprs, mid, last);
     return createValue(op, LINK(type), left, right);

+ 2 - 2
ecl/hqlcpp/hqlcppcase.cpp

@@ -266,7 +266,7 @@ void HqlCppCaseInfo::buildChop3Map(BuildCtx & ctx, const CHqlBoundTarget & targe
         buildChop2Map(ctx, target, test, start, end);
     else
     {
-        unsigned mid = (start + end) / 2;
+        unsigned mid = start + (end - start) / 2;
         generateCompareVar(ctx, temp, test, queryCompare(mid));
         OwnedHqlExpr test1 = createValue(no_eq, LINK(temp), getZero());
         OwnedHqlExpr test2 = createValue(no_lt, LINK(temp), getZero());
@@ -348,7 +348,7 @@ void HqlCppCaseInfo::buildChop2Map(BuildCtx & ctx, const CHqlBoundTarget & targe
     }
     else
     {
-        unsigned mid = (start + end) / 2;
+        unsigned mid = start + (end - start) / 2;
         
         IHqlExpression * compare = queryCompare(mid);
         OwnedHqlExpr cond  = createCompareExpr(no_lt, test.getTranslatedExpr(), LINK(compare));

+ 1 - 1
ecl/hqlcpp/hqlstmt.cpp

@@ -1091,7 +1091,7 @@ void HqlStmts::appendStmt(HqlStmt & stmt)
         unsigned left = 0;
         while (right - left >= 2)
         {
-            unsigned mid = (left + right - 1) / 2;
+            unsigned mid = left + (right - 1 - left) / 2;
             HqlStmt & cur = item(mid);
             if (newPrio >= cur.queryPriority())
                 left = mid+1;

+ 5 - 5
roxie/ccd/ccdkey.cpp

@@ -59,7 +59,7 @@ class PtrToOffsetMapper
         int rc;
         while ((int)a<b)
         {
-            int i = (a+b+1)/2;
+            int i = a+(b+1-a)/2;
             rc = ptr - fragments[i-1].base;
             if (rc>=0)
                 a = i;
@@ -1238,7 +1238,7 @@ public:
         int b = numTracked;
         while (a<b)
         {
-            int i = (a+b)/2;
+            int i = a+(b-a)/2;
             SegMonitorArray *m = tracked[i];
             int rc = compare(&perfect, m);
             if (rc==0)
@@ -1488,7 +1488,7 @@ class InMemoryIndexCursor : public CInterface, implements IInMemoryIndexCursor
         int b = postFilter.length();
         while (a<b)
         {
-            int i = (a+b)/2;
+            int i = a+(b-a)/2;
             IKeySegmentMonitor *k = &postFilter.item(i);
             int rc = offset-k->getOffset();
             if (rc==0)
@@ -1647,7 +1647,7 @@ class InMemoryIndexCursor : public CInterface, implements IInMemoryIndexCursor
             int rc;
             while ((int)a<b)
             {
-                int i = (a+b)/2;
+                int i = a+(b-a)/2;
                 rc = docompare(keyBuffer, GETROW(i));
                 if (rc>0)
                     a = i+1;
@@ -1688,7 +1688,7 @@ class InMemoryIndexCursor : public CInterface, implements IInMemoryIndexCursor
         unsigned a = start;
         while ((int)a<b)
         {
-            int i = (a+b+1)/2;
+            int i = a+(b+1-a)/2;
             rc = docompare(keyBuffer, GETROW(i-1));
             if (rc>=0)
                 a = i;

+ 2 - 2
rtl/eclrtl/rtlkey.cpp

@@ -1860,7 +1860,7 @@ void CStringSet::addRange(const void *loval, const void *hival)
         int rc;
         while ((int)a<b)
         {
-            int i = (a+b+1)/2;
+            int i = a+(b+1-a)/2;
             rc = memcmp(loval, transitions.item(i-1).getValue(), size);
             if (rc>0)
                 a = i;
@@ -2020,7 +2020,7 @@ bool CStringSet::inRange(const void *val, unsigned &nextTransition) const
         int rc;
         while ((int)a<b)
         {
-            int i = (a+b+1)/2;
+            int i = a+(b+1-a)/2;
             rc = memcmp(val, transitions.item(i-1).getValue(), size);
             if (rc>=0)
                 a = i;

+ 2 - 2
system/jhtree/jhtree.cpp

@@ -1775,7 +1775,7 @@ bool CKeyCursor::gtEqual(const char *src, char *dst, bool seekForward)
         // first search for first GTE entry (result in b(<),a(>=))
         while ((int)a<b)
         {
-            int i = (a+b)/2;
+            int i = a+(b-a)/2;
             int rc = node->compareValueAt(src, i);
             if (rc>0)
                 a = i+1;
@@ -1848,7 +1848,7 @@ bool CKeyCursor::ltEqual(const char *src, char *dst, bool seekForward)
         // Locate first record greater than src
         while ((int)a<b)
         {
-            int i = (a+b+1)/2;
+            int i = a+(b+1-a)/2;
             int rc = node->compareValueAt(src, i-1);
             if (rc>=0)
                 a = i;

+ 1 - 1
system/jlib/jlzw.cpp

@@ -1935,7 +1935,7 @@ class CCompressedFile : public CInterface, implements ICompressedFileIO
         unsigned b = indexNum();
         index = (const offset_t *)indexbuf.toByteArray();
         while (b>a) {
-            unsigned m = (a+b)/2;
+            unsigned m = a+(b-a)/2;
             __int64 dif = (__int64)pos-index[m];
             if (dif==0) {
                 b = m+1;

+ 2 - 2
system/jlib/jsort.cpp

@@ -1207,7 +1207,7 @@ class TbbParallelMergeSorter
                 return low;
             while (high - low > 1)
             {
-                size_t mid = (low + high) / 2;
+                size_t mid = low + (high - low) / 2;
                 if (compare.docompare(rows[mid], seek) < 0)
                     low = mid;
                 else
@@ -1224,7 +1224,7 @@ class TbbParallelMergeSorter
                 return low;
             while (high - low > 1)
             {
-                size_t mid = (low + high) / 2;
+                size_t mid = low + (high - low) / 2;
                 if (compare.docompare(rows[mid], seek) <= 0)
                     low = mid;
                 else

+ 1 - 1
system/jlib/jutil.hpp

@@ -293,7 +293,7 @@ VALUE * binsearch(KEY key, VALUE * * values, unsigned num, COMPARE * cmp)
     unsigned u = num;
     while(l<u)
     {
-        unsigned i = (l+u)/2;
+        unsigned i = l+(u-l)/2;
         int c = cmp->compare(key, values[i]);
         if(c == 0)
         {

+ 1 - 1
thorlcr/msort/tsorta.cpp

@@ -353,7 +353,7 @@ try {
 #endif
     while (a<b)
     {
-        unsigned m = (a+b)/2;
+        unsigned m = a+(b-a)/2;
         cmp = keyRowCompare((unsigned)m,row);
         if (cmp>0) 
             b = m;

+ 2 - 2
thorlcr/msort/tsorts.cpp

@@ -693,7 +693,7 @@ class CThorSorter : public CSimpleInterface, implements IThorSorter, implements
         ICompare* icmp=queryCmpFn(cmpfn);
         while (l<r)
         {
-            rowidx_t m = (l+r)/2;
+            rowidx_t m = l+(r-l)/2;
             int cmp = icmp->docompare(key, rowArray.query(m));
             if (cmp < 0)
                 r = m;
@@ -880,7 +880,7 @@ public:
                     p2 = rowArray.ordinality()-1;
                 if (p1<=p2)
                 {
-                    unsigned pm=(p1+p2+1)/2;
+                    unsigned pm=p1+(p2+1-p1)/2;
                     OwnedConstThorRow kp = rowArray.get(pm);
                     if ((keyRowCompare->docompare(low.query(i), kp)<=0)&&
                         (keyRowCompare->docompare(high.query(i), kp)>=0)) // paranoia