1 // RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -verify %s\
2 // RUN:                    -Wno-strncat-size -Wno-sizeof-pointer-memaccess     \
3 // RUN:                    -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument
4 // RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -verify %s\
5 // RUN:                    -Wno-strncat-size -Wno-sizeof-pointer-memaccess     \
6 // RUN:                    -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument\
7 // RUN:                    -triple armv7-a15-linux
8 // RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -verify %s\
9 // RUN:                    -Wno-strncat-size -Wno-sizeof-pointer-memaccess     \
10 // RUN:                    -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument\
11 // RUN:                    -triple aarch64_be-none-linux-gnu
12 // RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -verify %s\
13 // RUN:                    -Wno-strncat-size -Wno-sizeof-pointer-memaccess     \
14 // RUN:                    -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument\
15 // RUN:                    -triple i386-apple-darwin10
16 
17 typedef __SIZE_TYPE__ size_t;
18 char  *strncat(char *, const char *, size_t);
19 size_t strlen (const char *s);
20 size_t strlcpy(char *, const char *, size_t);
21 size_t strlcat(char *, const char *, size_t);
22 
testStrncat(const char * src)23 void testStrncat(const char *src) {
24   char dest[10];
25   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - 1); // expected-warning {{Potential buffer overflow. Replace with 'sizeof(dest) - strlen(dest) - 1' or use a safer 'strlcat' API}}
26   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
27   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - strlen(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
28   strncat(dest, src, sizeof(src)); // expected-warning {{Potential buffer overflow. Replace with}}
29   // Should not crash when sizeof has a type argument.
30   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(char));
31 }
32 
testStrlcpy(const char * src)33 void testStrlcpy(const char *src) {
34   char dest[10];
35   size_t destlen = sizeof(dest);
36   size_t srclen = sizeof(src);
37   size_t badlen = 20;
38   size_t ulen;
39   strlcpy(dest, src, sizeof(dest));
40   strlcpy(dest, src, destlen);
41   strlcpy(dest, src, 10);
42   strlcpy(dest, src, 20); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(dest) or lower}}
43   strlcpy(dest, src, badlen); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(dest) or lower}}
44   strlcpy(dest, src, ulen);
45   strlcpy(dest + 5, src, 5);
46   strlcpy(dest + 5, src, 10); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(<destination buffer>) or lower}}
47   strlcpy(dest, "aaaaaaaaaaaaaaa", 10); // no-warning
48 }
49 
testStrlcat(const char * src)50 void testStrlcat(const char *src) {
51   char dest[10];
52   size_t badlen = 20;
53   size_t ulen;
54   strlcpy(dest, "aaaaa", sizeof("aaaaa") - 1);
55   strlcat(dest, "bbbb", (sizeof("bbbb") - 1) - sizeof(dest) - 1);
56   strlcpy(dest, "012345678", sizeof(dest));
57   strlcat(dest, "910", sizeof(dest));
58   strlcpy(dest, "0123456789", sizeof(dest));
59   strlcpy(dest, "0123456789", sizeof(dest));
60   strlcat(dest, "0123456789", badlen / 2);
61   strlcat(dest, "0123456789", badlen); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(dest) or lower}}
62   strlcat(dest, "0123456789", badlen - strlen(dest) - 1);
63   strlcat(dest, src, ulen);
64   strlcpy(dest, src, 5);
65   strlcat(dest + 5, src, badlen); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(<destination buffer>) or lower}}
66   strlcat(dest, "aaaaaaaaaaaaaaa", 10); // no-warning
67 }
68