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
f1(const char * in)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
f2(const char * in)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(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(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(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(in); // to double
81 }
82
f3(void)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
do_not_diagnose(void)98 void do_not_diagnose(void) {
99 char str[32];
100
101 scanf("%s", str); // Not a numerical conversion
102 scanf("%*d"); // Assignment suppressed
103 }
104