Monday, August 30, 2010

A Real-life Story about Bad Type Cast

We have a problem today in our soft. That is, in short, we have 285 lines of text to display but only 231 lines are displayed. The investigation is not so easy because the text to be displayed is converted from structured message and the number of lines are calculated on the fly.

Basically, there is a segment in the message that specifies the maximum allowed number of lines, the sender of the message has set it to 999, assuming it the maximum possible lines in the message.

So if you are really a geek in programming C/C++, you may already know where is going wrong. Yes, an integer 999 when assigned to a unsigned char, the latter will have value 231. In more detail: binary presentation of decimal 999 is 1111100111, when assigned to unsigned char, we have only the lower 8 bits left: 11100111, it equals decimal value 231.

The problem is quite clear, but it has been hard to find it out because it hides itself deep in one of the libraries our soft uses.

Another interesting thing is that the library code uses atoi to convert the maximum allowed size in the message to an integer value, but with a parameter like this: "999blabla", that is the value in string followed by other alphabetic characters. atoi is designed to handle this correctly, take a look at the specification of atoi:

int atoi ( const char * str );
Convert string to integer
Parses the C string str interpreting its content as an integral number, which is returned as an int value.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus orminus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

No comments: