Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I verify that an integer value passed in from argv won't overflow?

Tags:

c

I have a program that requires the user to enter an integer as a command line argument, in the form of ./program 100.

Obviously this will read the value in as a string, so I need to parse it to an integer. I have to ensure that the input value won't overflow an integer variable. I have read about strtol(), but it works with long variables and I have to stick with a regular int.

Is there anything similar that can be used for an int?

like image 428
Jake Avatar asked Apr 01 '19 20:04

Jake


2 Answers

You can use strtol for this. You'll first need to check if this function fails to convert the value. If it convert successfully, then check if the value is in the range of INT_MIN to INT_MAX:

errno = 0;
long x = strtol(argv[1], NULL, 10);
if (errno) {
    perror("conversion failed");
} else if (x < INT_MIN) {
    printf("value too small\n");
} else if (x > INT_MAX) {
    printf("value too big\n");
} else {
    printf("value = %ld\n", x);
}

Note that this will work whether long is the same size as int or larger.

If sizeof(long) > sizeof(int), the INT_MIN and INT_MAX checks will catch the cases where the value fits in a long but not an int. If sizeof(long) == sizeof(int), an out of range value will result in errno being set to non-zero to catch the error, and the INT_MIN and INT_MAX cases will never be true.

like image 153
dbush Avatar answered Nov 16 '22 03:11

dbush


How should I verify that an integer value passed in from argv won't overflow?

Use strtol() and check the end pointer. Then check errno and maybe a range test

if (argc > 1) {
  char *endptr;
  errno = 0;
  long num = strtol(argv[1], &endptr, 10);

  if (argv[1] == endptr) {
    puts("No conversion");
  } else if (errno == ERANGE) {
    puts("Value outside long range");
  #if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
  } else if (num < INT_MAX || num > INT_MAX) {
    errno = ERANGE;
    puts("Value outside int range");
  #endif
  } else {
    // If code wants to look for trailing junk
    if (*endptr) {
      puts("Non-numeric text");
    } else {
      printf("Success %d\n", (int) num);
    } 
  } 

Based on Why is there no strtoi in stdlib.h?

like image 26
chux - Reinstate Monica Avatar answered Nov 16 '22 03:11

chux - Reinstate Monica