What is it?

When a compiler has to convert an object of one type to an object of another type, the compiler does type conversion.

Two type of conversions are as follows.

1. Explicit type.

2. Implicit type.

Explicit type: The programmer explicitly instructs the compiler to convert from one type to another.

Example

#include<stdio.h>
int main()
{
    int x = 10;    // integer x
    char y = 'a';  // character c
 
    // y implicitly converted to int. ASCII
    // value of 'a' is 97
    x = x + y;
    
    // x is implicitly converted to float
    float z = x + 1.0;
 
    printf("x = %d, z = %f", x, z);
    return 0;
}

The result is, 

x = 107, z = 108.000000

Implicit type: This is also known as coercion. This is an automatic type of conversion, which is done by the compiler.

Example

// C program to demonstrate explicit type casting
#include<stdio.h>
 
int main()
{
    double x = 1.2;
 
    // Explicit conversion from double to int
    int sum = (int)x + 1;
 
    printf("sum = %d", sum);
 
    return 0;
}

The result is:

sum = 2

Some examples of conversion errors

1. Non-compliant comparison.

2. Non-compliant bitwise operations.

3. Arithmetic involves two pointer types.

 

Non-compliant comparisons

The below example shows a vulnerability when performing comparison on mixed types. The code is as follows:

int si = -1;
unsigned int ui = 1;
printf("%d\n", si < ui);

 

In this example, the comparison operator operates on a signed int and an unsigned int. By the conversion rules, si is converted to an unsigned int. Because −1 cannot be represented as an unsigned int value, the −1 is converted to UINT_MAX in accordance with the C Standard.

 The noncompliant code example can be modified to produce the intuitive result by forcing the comparison to be performed using signed int values:

int si = -1;
unsigned ui = 1;
printf("%d\n", si < (int)ui);

This program prints 1 as expected. Note that (int)ui is correct in this case only because the value of ui is known to be representable as an int. If it were not known, the compliant solution would need to be written as:

int si = /* Some signed value */;
unsigned ui = /* Some unsigned value */;
printf("%d\n", (si < 0 || (unsigned)si < ui));

The above example is taken from the secure coding website of CERT.

Concept Map

The above example maps to I in the Concept Map.

Non-compliant bitwise operations

The below example shows how performing bitwise operations on integer types smaller than int may have unexpected results:

uint8_t port = 0x5a;
uint8_t result_8 = ( ~port ) >> 4;

In the above example, a bitwise complement of port is first computed and then shifted 4 bits to the right. If both of these operations are performed on an 8-bit unsigned integer, then result_8 will have the value 0x0a. However, port is first promoted to a signed int, with the following results (on a typical architecture where type int is 32 bits wide):

Expression Type Value
port uint8_t 0x5a
result_8 uint8_t 0xfa
~port int 0xffffffa5
~port >> 4 int

0xffffffa5

 

In this compliant solution, the bitwise complement of port is converted back to 8 bits. Consequently, result_8 is assigned the expected value of 0x0aU.

uint8_t port = 0x5a;
uint8_t result_8 = (uint8_t) (~port) >> 4;

The above example is taken from the secure coding website of CERT.

 Concept Map

 The above example maps to 5 and E in the Concept Map.

 

Arithmetic involves two pointer types

Take a look at the following code:

#include <stdio.h>

int main()
{
 unsigned int *p1;
 int *p2;
  unsigned int u=6;
 p1=&u;
 int i=12;
 p2=&i;

 printf ("%u\n",*p1-*p2);
 return 0;
}

You might expect the expression  evaluate to -6 since 6 - 12 = -6. But the actual result is: 4294967290

 Concept Map

 The above example maps to J in the Concept Map.

 

JSN Teki template designed by JoomlaShine.com