From e5c616888b50ba1c35dd99e5500ef2c4dff5b4f9 Mon Sep 17 00:00:00 2001
From: Pavlos Antoniou <antoniou-p@hotmail.com>
Date: Wed, 7 Jun 2017 17:21:29 +0000
Subject: Fix instantiation and array accesses in class base_uint<BITS>

The implementation of base_uint::operator++(int) and base_uint::operator--(int) is now safer.
Array pn is accessed via index i after bounds checking has been performed on the index, rather than before.
The logic of the while loops has also been made more clear.

A compile time assertion has been added in the class constructors to ensure that BITS is a positive multiple of 32.
---
 src/arith_uint256.cpp |  2 ++
 src/arith_uint256.h   | 10 ++++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp
index dd34a313b7..b4952af6f4 100644
--- a/src/arith_uint256.cpp
+++ b/src/arith_uint256.cpp
@@ -15,6 +15,8 @@
 template <unsigned int BITS>
 base_uint<BITS>::base_uint(const std::string& str)
 {
+    static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32.");
+
     SetHex(str);
 }
 
diff --git a/src/arith_uint256.h b/src/arith_uint256.h
index 0f6b3d4fba..c7734035df 100644
--- a/src/arith_uint256.h
+++ b/src/arith_uint256.h
@@ -31,12 +31,16 @@ public:
 
     base_uint()
     {
+        static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32.");
+
         for (int i = 0; i < WIDTH; i++)
             pn[i] = 0;
     }
 
     base_uint(const base_uint& b)
     {
+        static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32.");
+
         for (int i = 0; i < WIDTH; i++)
             pn[i] = b.pn[i];
     }
@@ -50,6 +54,8 @@ public:
 
     base_uint(uint64_t b)
     {
+        static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32.");
+
         pn[0] = (unsigned int)b;
         pn[1] = (unsigned int)(b >> 32);
         for (int i = 2; i < WIDTH; i++)
@@ -174,7 +180,7 @@ public:
     {
         // prefix operator
         int i = 0;
-        while (++pn[i] == 0 && i < WIDTH-1)
+        while (i < WIDTH && ++pn[i] == 0)
             i++;
         return *this;
     }
@@ -191,7 +197,7 @@ public:
     {
         // prefix operator
         int i = 0;
-        while (--pn[i] == (uint32_t)-1 && i < WIDTH-1)
+        while (i < WIDTH && --pn[i] == (uint32_t)-1)
             i++;
         return *this;
     }
-- 
cgit v1.2.3