| 1 | // RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c11 |
| 2 | |
| 3 | typedef __SIZE_TYPE__ size_t; |
| 4 | typedef signed ptrdiff_t; |
| 5 | typedef long long intmax_t; |
| 6 | typedef unsigned long long uintmax_t; |
| 7 | typedef void * FILE; |
| 8 | |
| 9 | extern FILE *stdin; |
| 10 | |
| 11 | extern int fscanf(FILE * restrict stream, const char * restrict format, ...); |
| 12 | extern int scanf(const char * restrict format, ...); |
| 13 | extern int sscanf(const char * restrict s, const char * restrict format, ...); |
| 14 | |
| 15 | extern double atof(const char *nptr); |
| 16 | extern int atoi(const char *nptr); |
| 17 | extern long int atol(const char *nptr); |
| 18 | extern long long int atoll(const char *nptr); |
| 19 | |
| 20 | void f1(const char *in) { |
| 21 | int i; |
| 22 | long long ll; |
| 23 | unsigned int ui; |
| 24 | unsigned long long ull; |
| 25 | intmax_t im; |
| 26 | uintmax_t uim; |
| 27 | float f; |
| 28 | double d; |
| 29 | long double ld; |
| 30 | |
| 31 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] |
| 32 | sscanf(in, "%d" , &i); |
| 33 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c] |
| 34 | fscanf(stdin, "%lld" , &ll); |
| 35 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead [cert-err34-c] |
| 36 | sscanf(in, "%u" , &ui); |
| 37 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead [cert-err34-c] |
| 38 | fscanf(stdin, "%llu" , &ull); |
| 39 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead [cert-err34-c] |
| 40 | scanf("%jd" , &im); |
| 41 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead [cert-err34-c] |
| 42 | fscanf(stdin, "%ju" , &uim); |
| 43 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead [cert-err34-c] |
| 44 | sscanf(in, "%f" , &f); // to float |
| 45 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c] |
| 46 | fscanf(stdin, "%lg" , &d); |
| 47 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead [cert-err34-c] |
| 48 | sscanf(in, "%Le" , &ld); |
| 49 | |
| 50 | // These are conversions with other modifiers |
| 51 | short s; |
| 52 | char c; |
| 53 | size_t st; |
| 54 | ptrdiff_t pt; |
| 55 | |
| 56 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 57 | scanf("%hhd" , &c); |
| 58 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 59 | scanf("%hd" , &s); |
| 60 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 61 | scanf("%zu" , &st); |
| 62 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 63 | scanf("%td" , &pt); |
| 64 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 65 | scanf("%o" , ui); |
| 66 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 67 | scanf("%X" , ui); |
| 68 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 69 | scanf("%x" , ui); |
| 70 | } |
| 71 | |
| 72 | void f2(const char *in) { |
| 73 | // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] |
| 74 | int i = atoi(nptr: in); // to int |
| 75 | // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] |
| 76 | long l = atol(nptr: in); // to long |
| 77 | // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c] |
| 78 | long long ll = atoll(nptr: in); // to long long |
| 79 | // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c] |
| 80 | double d = atof(nptr: in); // to double |
| 81 | } |
| 82 | |
| 83 | void f3(void) { |
| 84 | int i; |
| 85 | unsigned int u; |
| 86 | float f; |
| 87 | char str[32]; |
| 88 | |
| 89 | // Test that we don't report multiple infractions for a single call. |
| 90 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 91 | scanf("%d%u%f" , &i, &u, &f); |
| 92 | |
| 93 | // Test that we still catch infractions that are not the first specifier. |
| 94 | // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert |
| 95 | scanf("%s%d" , str, &i); |
| 96 | } |
| 97 | |
| 98 | void do_not_diagnose(void) { |
| 99 | char str[32]; |
| 100 | |
| 101 | scanf("%s" , str); // Not a numerical conversion |
| 102 | scanf(restrict: "%*d" ); // Assignment suppressed |
| 103 | } |
| 104 | |