Goody. I have 12 instances of atoi() used in my program that I need to replace with strtol(). For those of you who don’t know, these functions convert a string of characters representing a number to an actual integer value.
The function atoi has been deprecated because it is one of those string functions that can be easily exploited with some sort of buffer overflow attack. Basically, when all of the string functions got added to C, those programmers figured that everyone would be good about error checking, and prevent bad strings from being passed to these functions. Certainly, their way was easier. Ironically, in the process of being lazy programmers they forgot one key fact: programmers are lazy. Thus there is a lot of code out there that can be exploited.
I’ll briefly explain why atoi is easier to use:
int atoi(const char *nptr);
Give it a string, it gives you an integer. What could be easier than that? Well… probably very little, but the problem is that there’s no way to do proper error checking. Something might have gone wrong if the function returns 0, but the string could also just contain the value 0. No way to know. I suppose for most applications, you have good enough control over the input that it doesn’t really matter. The problem comes when you’re taking input from a user: a malicious person could potentially mess up your program in this way, if they’re smart about it.
Here’s the function prototype for strtol (that stands for string to long, if that wasn’t clear):
long strtol(const char * restrict nptr, char ** restrict endptr, int base);
Looks kind of scary, doesn’t it? You have to give it the input string, plus a result string that contains any unprocessed text, plus the base (decimal, octal, or hexadecimal) in which the integer value in the string is expressed. On top of all that, you get a lot more possible error returns, not to mention having to check the result string to find out how many characters were actually consumed.
Here’s what a basic use of atoi looks like:
myInt = atoi(myString);
Yeah. That easy. Now here’s a use of strtol, with only basic error checking:
if (strlen(myString)) { myLong = strtol(myString, &myResult, 10); if (myString == myResult) { printf("invalid long conversion\n"); exit(0); } printf("Long: %ld\n", myLong); } else { printf("no value to convert\n"); exit(0); }
This doesn’t even include the error checking to make sure that the value is in the range you want. The first check makes sure that the input is not just an empty string. The second check after the conversion looks to see if any characters in the input string were consumed. If the input is the same as the result, that means that there wasn’t a valid integer value in the string. Believe me there’s more…
So yeah, fun times for Nick.
Leave a Reply to grumpy_sysadminCancel reply