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