Skip to content

Instantly share code, notes, and snippets.

@Costava
Created April 29, 2021 04:17
Show Gist options
  • Save Costava/cf8ab93a05c94217c8dbf8da8ed18f90 to your computer and use it in GitHub Desktop.
Save Costava/cf8ab93a05c94217c8dbf8da8ed18f90 to your computer and use it in GitHub Desktop.
The return value of and the value read by sscanf are misleading/wrong when an integer greater than INT_MAX is read.
//
// File: sscanf_overflow.c
// Author: Costava
//
// If sscanf is given a string of an integer greater than INT_MAX,
// sscanf will still return 1 even though the integer cannot have been
// read correctly into the given variable.
//
// errno gets set to ERANGE
// errno can be checked to see if sscanf actually succeeded.
//
// Example compilation:
// gcc sscanf_overflow.c -o sscanf_overflow -std=c99 -Wall -Wextra -Wconversion
//
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
// Call printf. If error, exit(1)
#define CHECKED_PRINTF(...) if (printf(__VA_ARGS__) < 0) { exit(1); }
int main(void) {
CHECKED_PRINTF("INT_MAX : %d\n", INT_MAX); // 2147483647
int num;
CHECKED_PRINTF("errno before sscanf: %d\n", errno); // 0
const int sscanf_return_value = sscanf("99999999999999999999999999999999999999999999999999999999999999999999999999999999", "%d", &num);
CHECKED_PRINTF("errno after sscanf : %d\n", errno); // 34
CHECKED_PRINTF("ERANGE : %d\n", ERANGE); // 34
// The read was not successful, but sscanf still returned 1.
// Unfortunate. Footgun.
CHECKED_PRINTF("sscanf_return_value: %d\n", sscanf_return_value); // 1
CHECKED_PRINTF("sscanf value read : %d\n", num); // -1
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment