Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...


If the result of the addition, is greater than the maximum value that the int type can store or less than the minimum value that the int type can store, then the variable temp has a wrong result stored. Although, unlike C\C++ the integer overflow is difficult to exploit by an attacker in Java, because of the memory properties in this platform (e.g. explicit array bound checking; if temp has a negative value as a result of an overflow and we use it as an array index we get an  java.lang.ArrayIndexOutOfBoundsException) the results of our operation are wrong and can lead to undefined or incorrect behavior
 All the of the following operators can lead to overflow (same as in C\C++):

Operator

Overflow

 

Operator

Overflow

 

Operator

Overflow

 

Operator

Overflow

+

yes

 

-=

yes

 

<<

no

 

<

no

-

yes

 

*=

yes

 

>>

no

 

>

no

*

yes

 

/=

yes

 

&

no

 

>=

no

/

yes

 

%=

no 

 

|

no

 

<=

no

%

no 

 

<<=

no

 

^

no

 

==

no

++

yes

 

>>=

no

 

~

no

 

!=

no

--

yes

 

&=

no

 

!

no

 

&&

no

=

no

 

|=

no

 

un +

no

 

||

no

+=

yes

 

^=

no

 

un -

yes

 

?:

no

...

e.g for the previous example

Compliant Solution (Use long and downcast)


 

Code Block
bgColor#ccccff
public int do_operation(int a, int b) throws ArithmeticException

{
   long temp = (long)a+(long)b;
   if(temp >Integer.MAX_VALUE || temp < Integer.MIN_VALUE) throw ArithmeticException;
   else //Value within range can perform the addition
   //Do stuff
   return (int)temp;
}


Compliant Solution (Bounds Checking)


Another example would be of explicit range checking would be:

Code Block
bgColor#ccccff
public int do_operation(int a, int b) throws ArithmeticException
{
       int temp;
       if(a>0 && b>0 && (a >Integer.MAX_VALUE - b) || a<0 && b<0 && (a < Integer.MIN_VALUE -b))
              throw ArithmeticException;
       else
             temp = a + b;//Value within range can perform the addition
      //Do stuff return
       temp;
}


Compliant Solution (Use BigInteger class)


 Another compliant approach would be to use the BigInteger class in this example and in the examples of the other operations using a wrapper for test of the overflow:

...

Code Block
bgColor#FFcccc
public int do_operation(int a,int b)
{
   int temp = a - b;
//Could result in overflow
//perform other processing
   return temp;
}



Compliant Code Example (Use long)

The appropriate way is to check explicitely the range before doing the subtraction

Code Block
bgColor#ccccff
int a,b,result;

long temp = (long)a-(long)b;
if(long < Integer.MIN_VALUE || long > Integer.MAX_VALUE)
throw ArithmeticException;
else
result = (int) temp;

Compliant Code Example (Use BigInteger class)

A BigInteger class as a test-wrapper could be used

...

Code Block
bgColor#FFcccc
int a,b,result
//do stuff
result = a*b;//May result in overflow











Compliant Code Example

Since in this platform the size of type long (64 bits) is twice the size of type int (32 bits) we should perform the multiplication in terms of long and if the product is in the integer range we downcast the result to int

...

Code Block
bgColor#FFcccc
int a,b,result
result = a/b;











Compliant Code Example


 

Code Block
bgColor#ccccff
if(a == Integer.MIN_VALUE && b == -1)
throw ArithmeticException;//May be Integer.MIN_VALUE again????
else
result = a/b;//safe operation

...

Code Block
bgColor#FFcccc
int temp = -result;







Compliant Code Example


Code Block
bgColor#ccccff
if(a == Integer.MIN_VALUE)
throw ArithmeticException;
else
result = -a;

...

For instance operations on long are operations on 64 bits. For example addition:

Compliant Code Example


 

Code Block
bgColor#ccccff
java.math.BigInteger big_long_max = new java.math.BigInteger(String.valueOf(Long.MAX_VALUE));
System.out.println("big_long="+big_long_max);
big_long_max = big_long_max.add(java.math.BigInteger.valueOf(1));//same as ++big_long_max
System.out.println("big_long="+big_long_max);
These print
big_long=9223372036854775807
big_long=9223372036854775808//exceeds the maximum range of long, no problem

java.math.BigInteger big_long_min = new java.math.BigInteger(String.valueOf(Long.MIN_VALUE));
System.out.println("big_long_min="+big_long_min);
big_long_min = big_long_min.subtract(java.math.BigInteger.valueOf(1));//same as --big_long_min
System.out.println("big_long_min="+big_long_min);//goes bellow minimum range of long, no problem

These print:
big_long_min=-9223372036854775808
big_long_min=-9223372036854775809
if(big_long < Long.MAX_VALUE && big_long > Long.MIN_VALUE)//value within range can go to the primitive type
long value = big_log.longValue();//get primitive type
else
//Perform error handling. We can not downcast since the value can not be represented as a long

...